/*先把標題給寫了、這樣就能經常提醒自己*/
題記:今天下午去上廁所的一會兒時間,就把第四章給掃完了,說是掃完了主要是因為沒有深入去看,對于某些證明都直接跳過了,看了一下里面的例子,大概懂個意思就行了
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元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
