贝叶斯算法代码实现

网友投稿 759 2022-05-29

贝叶斯分类算法是统计学的一种分类方法,它是一类利用概率统计知识进行分类的算法。在许多场合,朴素贝叶斯(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 v1 = new Vector(); for(int i=0;i

对给定的文本进行分类

@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 crs = new ArrayList();//分类结果 for (int i = 0; i

创建类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小时内删除侵权内容。

上一篇:用AI+云原生,为行业开发者打造全栈全场景下的应用开发新体验
下一篇:ThinkSNS+的 SPA(H5)安装教程
相关文章