貝葉斯算法的代碼實現
貝葉斯分類算法是統計學的一種分類方法,它是一類利用概率統計知識進行分類的算法。在許多場合,樸素貝葉斯(Na?ve Bayes,NB)分類算法可以與決策樹和神經網絡分類算法相媲美,該算法能運用到大型數據庫中,而且方法簡單、分類準確率高、速度快。
今天教大家如何用代碼實現貝葉斯算法
所需jar包
創建目錄存放訓練語料
創建類BayesClassifier
樸素貝葉斯分類器, 利用樣本數據集計算先驗概率和各個文本向量屬性在分類中的條件概率,從而計算出各個概率值,最后對各個概率值進行排序,選出最大的概率值,即為所屬的分類。
public class BayesClassifier { private TrainingDataManager tdm;//訓練集管理器 private String trainnigDataPath;//訓練集路徑 private static double zoomFactor = 10.0f;
默認的構造器,初始化訓練集
package com.lzl; import com.lzl.ChineseSpliter; import com.lzl.ClassConditionalProbability; import com.lzl.PriorProbability; import com.lzl.TrainingDataManager; import com.lzl.StopWordsHandler; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Vector; public BayesClassifier() { tdm =new TrainingDataManager(); }
計算給定的文本屬性向量X在給定的分類Cj中的類條件概率
ClassConditionalProbability連乘值
@param X 給定的文本屬性向量
@param Cj 給定的類別
@return 分類條件概率連乘值,即
float calcProd(String[] X, String Cj) { float ret = 1.0F; // 類條件概率連乘 for (int i = 0; i 去掉停用詞 @param text 給定的文本 @return 去停用詞后結果 public String[] DropStopWords(String[] oldWords) { Vector 對給定的文本進行分類 @param text 給定的文本 @return 分類結果 @SuppressWarnings("unchecked") public String classify(String text) { String[] terms = null; terms= ChineseSpliter.split(text, " ").split(" ");//中文分詞處理(分詞后結果可能還包含有停用詞) terms = DropStopWords(terms);//去掉停用詞,以免影響分詞 String[] Classes = tdm.getTraningClassifications();//分類 float probility = 0.0F; List 創建類ChineseSpliter.java 中文分詞器,因為對文本進行分類時,需要計算文本中每個詞在各類別中出現的概率,所以需要對文本進行分詞,用到了分詞器 package com.lzl; import java.io.IOException; import jeasy.analysis.MMAnalyzer; public class ChineseSpliter { /** * 對給定的文本進行中文分詞 * @param text 給定的文本 * @param splitToken 用于分割的標記,如"|" * @return 分詞完畢的文本 */ public static String split(String text,String splitToken) { String result = null; MMAnalyzer analyzer = new MMAnalyzer(); //中文分詞工具 try { result = analyzer.segment(text, splitToken); } catch (IOException e) { e.printStackTrace(); } return result; } } 創建類ClassConditionalProbability.java 類條件概率計算,這是另一個影響因子,和先驗概率一起來決定最終結果 類條件概率 P(xj|cj)=( N(X=xi, C=cj )+1 ) / ( N(C=cj)+M+V ) 其中,N(X=xi, C=cj)表示類別cj中包含屬性x i的訓練文本數量;N(C=cj)表示類別cj中的訓練文本數量;M值用于避免 N(X=xi, C=cj)過小所引發的問題;V表示類別的總數。 條件概率 定義 設A, B是兩個事件,且P(A)>0 稱 P(B∣A)=P(AB)/P(A) 為在條件A下發生的條件事件B發生的條件概率。 package com.lzl; public class ClassConditionalProbability { private static TrainingDataManager tdm = new TrainingDataManager();//訓練語料的分類 private static final float M = 0F; /** * 計算類條件概率 * @param x 給定的文本屬性 * @param c 給定的分類 * @return 給定條件下的類條件概率 */ public static float calculatePxc(String x, String c) { float ret = 0F; float Nxc = tdm.getCountContainKeyOfClassification(c, x);//返回給定分類c中包含關鍵字/詞x的訓練文本的數目 float Nc = tdm.getTrainingFileCountOfClassification(c);//返回訓練文本集中在給定分類c下的訓練文本數目 float V = tdm.getTraningClassifications().length;//所有訓練文本的類別數目 ret = (Nxc + 1) / (Nc + M + V); return ret; } } 創建ClassifyResult.java 分類結果,用來保存各個分類及其計算出的概率值 package com.lzl; public class ClassifyResult { public double probility;//分類的概率 public String classification;//分類 public ClassifyResult() { this.probility = 0; this.classification = null; } } 創建PriorProbability.java 先驗概率計算 P(cj)=N(C=cj)/N 其中,N(C=cj)表示類別cj中的訓練文本數量; N表示訓練文本集總數量。 package com.lzl; public class PriorProbability { private static TrainingDataManager tdm =new TrainingDataManager(); /** * 先驗概率 * @param c 給定的分類 * @return 給定條件下的先驗概率 */ public static float calculatePc(String c) { float ret = 0F; float Nc = tdm.getTrainingFileCountOfClassification(c);//返回訓練文本集中在給定分類下的訓練文本數目 float N = tdm.getTrainingFileCount();//返回訓練文本集中所有的文本數目 ret = Nc / N; return ret; } } 創建StopWordsHandler.java 停用詞處理器,去掉文檔中無意思的詞語也是必須的一項工作,這里簡單的定義了一些常見的停用詞, 并根據這些常用停用詞在分詞時進行判斷。 相當于預處理,去噪 package com.lzl; public class StopWordsHandler { private static String stopWordsList[] ={"的", "我們","要","自己","之","將","“","”",",","(",")","后","應","到","某","后","個","是","位","新","一","兩","在","中","或","有","更","好",""};//常用停用詞 public static boolean IsStopWord(String word) { for(int i=0;i 創建TrainingDataManager.java 訓練集管理器,首先需要從訓練樣本集中得到假設的先驗概率和給定假設下觀察到不同數據的概率。 package com.lzl; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; public class TrainingDataManager { private String[] traningFileClassifications;//訓練語料分類集合 private File traningTextDir;//訓練語料存放目錄 private static String defaultPath = "F:\\studyfiles\\數據挖掘\\3\\Bayes\\BayesData\\Sample"; public TrainingDataManager() { traningTextDir = new File(defaultPath); if (!traningTextDir.isDirectory()) { throw new IllegalArgumentException("訓練語料庫搜索失??! [" +defaultPath + "]"); } this.traningFileClassifications = traningTextDir.list(); } 返回訓練文本類別,這個類別就是目錄名 @return 訓練文本類別 public String[] getTraningClassifications() { return this.traningFileClassifications; } 根據訓練文本類別返回這個類別下的所有訓練文本路徑(full path) @param classification 給定的分類 @return 給定分類下所有文件的路徑(full path) public String[] getFilesPath(String classification) { File classDir = new File(traningTextDir.getPath() +File.separator +classification); String[] ret = classDir.list(); for (int i = 0; i < ret.length; i++) { ret[i] = traningTextDir.getPath() +File.separator +classification +File.separator +ret[i]; } return ret; } 返回給定路徑的文本文件內容 @param filePath 給定的文本文件路徑 @return 文本內容 @throws java.io.FileNotFoundException @throws java.io.IOException public static String getText(String filePath) throws FileNotFoundException,IOException { InputStreamReader isReader =new InputStreamReader(new FileInputStream(filePath),"GBK"); BufferedReader reader = new BufferedReader(isReader); String aline; StringBuilder sb = new StringBuilder(); while ((aline = reader.readLine()) != null) { sb.append(aline + " "); } isReader.close(); reader.close(); return sb.toString(); } 返回訓練文本集中所有的文本數目 @return 訓練文本集中所有的文本數目 public int getTrainingFileCount() { int ret = 0; for (int i = 0; i < traningFileClassifications.length; i++) { ret +=getTrainingFileCountOfClassification(traningFileClassifications[i]); } return ret; } 返回訓練文本集中在給定分類下的訓練文本數目 @param classification 給定的分類 @return 訓練文本集中在給定分類下的訓練文本數目 public int getTrainingFileCountOfClassification(String classification) { File classDir = new File(traningTextDir.getPath() +File.separator +classification); return classDir.list().length; } 返回給定分類中包含關鍵字/詞的訓練文本的數目 @param classification 給定的分類 @param key 給定的關鍵字/詞 @return 給定分類中包含關鍵字/詞的訓練文本的數目 public int getCountContainKeyOfClassification(String classification,String key) { int ret = 0; try { String[] filePath = getFilesPath(classification); for (int j = 0; j < filePath.length; j++) { String text = getText(filePath[j]); if (text.contains(key)) { ret++; } } } catch (FileNotFoundException ex) { Logger.getLogger(TrainingDataManager.class.getName()).log(Level.SEVERE, null,ex); } catch (IOException ex) { Logger.getLogger(TrainingDataManager.class.getName()).log(Level.SEVERE, null,ex); } return ret; } } 運行結果 機器學習
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。