/*先把標題給寫了、這樣就能經常提醒自己*/
題記:今天下午去上廁所的一會兒時間,就把第四章給掃完了,說是掃完了主要是因為沒有深入去看,對于某些證明都直接跳過了,看了一下里面的例子,大概懂個意思就行了
1.? 樸素貝葉斯法
設輸入空間
為
維向量的集合,輸出空間為類標記集合
,輸入特征向量
,輸出類標記為
,
是
和
的聯合概率分布,數據集
由
獨立同分布產生。
樸素貝葉斯法就是通過訓練集來學習聯合概率分布
.具體怎么學習呢? 主要就是從先驗概率分布和條件概率分布入手,倆個概率相乘即可得聯合概率。
為什么稱之為樸素呢,主要是其將條件概率的估計簡化了,對條件概率分布作了條件獨立性假設,這也是樸素貝葉斯法的基石,具體的假設如下
? ? ? ? ? ? ? ? ?
此公式在假設條件之下可以等價于
現在, 對于給定的輸入向量
,通過學習到的模型計算后驗概率分布P(Y=Ck|X=x),后驗分布中最大的類作為的輸出結果,根據貝葉斯定理可知后驗概率為
?
?
上面的公式可能有點歧義,分母的Ck應該寫成Cj才對,因為P(X=x)=E P(Y=Cj)*P(X=x|Y=Cj)
而
對于所有
都是相同的,即此可以將輸出結果簡化為
至此大概講解了樸素貝葉斯的基本方法步驟了,關于參數估計還有具體實例下次再寫了。夏天真熱啊!
2.? 參數估計
? 2.1 極大似然估計
上一小節講了對于給定的輸入向量
,其輸出結果可表示為
對此可應用極大似然估計法來估計相應的概率,如先驗概率
的極大似然估計是
設第個
特征
可能取值的集合為
,條件概率
的極大似然估計是
公式看起來可能有點不實在,還是直接上例子來說明吧!
?
例子:試由下表的訓練數據學習一個樸素貝葉斯分類器并確定
的類標記,表中
為特征,
為類標記。
據此可算出
是
后驗分布中值
最大的,也就是最終的類標記為-1
? ? 2.2 貝葉斯 估計
極大似然估計的一個可能是會出現所要估計的概率值為 0的情況,這時會影響到后驗概率的計算結果,解決這一問題的方法是采用貝葉斯估計,具體的只需要在極大似然估計的基礎上加多一個參數即可。懶得繼續寫公式了,不想寫了,剛剛碼完代碼!!
?
有興趣的可以看一下具體的代碼實現
package
org.juefan.bayes;
import
java.util.ArrayList;
import
java.util.HashMap;
import
java.util.Map;
import
org.juefan.basic.FileIO;
/**
* 這是一個簡易的貝葉斯分類器
* 只適用于離散數據,連續型數據的暫時請先繞道了^.^
*
@author
JueFan
*/
public
class
NaiveBayes{
//
平滑指數, 默認為拉普拉斯平滑,極大似然估計則為0
private
static
double
Lambda = 1
;
//
存儲先驗概率數據
private
Map<Object, Double> PriorProbability =
new
HashMap<>
();
//
存儲條件概率數據
private
Map<Object, ArrayList<Map<Object, Double>>> ConditionProbability =
new
HashMap<>
();
/**
* 計算類別的先驗概率
*
@param
datas
*/
public
void
setPriorPro(ArrayList<Data>
datas){
int
counts =
datas.size();
for
(Data data: datas){
if
(PriorProbability.containsKey(data.y)){
PriorProbability.put(data.y, PriorProbability.get(data.y)
+ 1
);
}
else
{
PriorProbability.put(data.y, (
double
) 1
);
}
}
for
(Object o: PriorProbability.keySet())
PriorProbability.put(o, (PriorProbability.get(o)
+ Lambda)/(counts + Lambda *
PriorProbability.size()));
}
/**
* 計算條件概率
*
@param
datas
*/
public
void
setCondiPro(ArrayList<Data>
datas){
Map
<Object, ArrayList<Data>> tmMap =
new
HashMap<>
();
//
按類別先將數據分類存放
for
(Data data: datas){
if
(tmMap.containsKey(data.y)){
tmMap.get(data.y).add(data);
}
else
{
ArrayList
<Data> tmDatas =
new
ArrayList<>
();
tmDatas.add(data);
tmMap.put(data.y, tmDatas);
}
}
//
條件概率主體
for
(Object o: tmMap.keySet()){
ArrayList
<Map<Object, Double>> tmCon =
new
ArrayList<>
();
int
LabelCount =
tmMap.get(o).size();
//
計算每個特征的相對頻數
for
(Data data: tmMap.get(o)){
for
(
int
i = 0; i < data.x.size(); i++
){
if
(tmCon.size() < i + 1
){
Map
<Object, Double> tmMap2 =
new
HashMap<>
();
tmMap2.put(data.x.get(i), (
double
) 1
);
tmCon.add(tmMap2);
}
else
{
if
(tmCon.get(i).containsKey(data.x.get(i))){
tmCon.get(i).put(data.x.get(i), tmCon.get(i).get(data.x.get(i))
+ 1
);
}
else
{
tmCon.get(i).put(data.x.get(i), (
double
) 1
);
}
}
}
}
//
計算條件概率
for
(
int
i = 0; i < tmCon.size(); i++
){
for
(Object o1: tmCon.get(i).keySet()){
tmCon.get(i).put(o1, (tmCon.get(i).get(o1)
+ Lambda)/(LabelCount + Lambda *
tmCon.get(i).size()));
}
}
ConditionProbability.put(o, tmCon);
}
}
/**
* 判斷實例的類別
*
@param
data
*
@return
判斷結果
*/
public
Object getLabel(Data data){
Object label
=
new
Object();
double
pro =
0D;
for
(Object o: PriorProbability.keySet()){
double
tmPro = 1
;
tmPro
*=
PriorProbability.get(o);
for
(
int
i = 0; i < data.x.size(); i++
){
tmPro
*=
ConditionProbability.get(o).get(i).get(data.x.get(i));
}
if
(tmPro >
pro){
pro
=
tmPro;
label
=
o;
}
System.out.println(o.toString()
+ " :的后驗概率為: " +
tmPro);
}
return
label;
}
public
static
void
main(String[] args) {
ArrayList
<Data> datas =
new
ArrayList<>
();
FileIO fileIO
=
new
FileIO();
fileIO.setFileName(
".//file//bayes.txt"
);
fileIO.FileRead();
for
(String data: fileIO.fileList){
datas.add(
new
Data(data));
}
NaiveBayes bayes
=
new
NaiveBayes();
bayes.setPriorPro(datas);
bayes.setCondiPro(datas);
Data data
=
new
Data("1\t2\tS"
);
System.out.println(data.toString()
+ "\t的判斷類別為: " +
bayes.getLabel(data));
}
}
?
?對代碼有興趣的可以上本人的GitHub查看: https://github.com/JueFan/StatisticsLearningMethod/
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

