网上有很多对朴素贝叶斯算法的说明的文章,在对算法实现前,参考了一下几篇文章:

NLP系列(2)_用朴素贝叶斯进行文本分类(上)

NLP系列(3)_用朴素贝叶斯进行文本分类(下)

带你搞懂朴素贝叶斯分类算法

其中“带你搞懂朴素贝叶斯算法”在我看来比较容易理解,上面两篇比较详细,更深入。

算法java实现

第一步对训练集进行预处理,分词并计算词频,得到存储训练集的特征集合

/**
* 所有训练集分词特征集合
* 第一个String代表分类标签,也就是存储该类别训练集的文件名
* 第二个String代表某条训练集的路径,这里存储的是该条语料的绝对路径
* Map<String, Integer>存储的是该条训练集的特征词和词频
*
*/
private static Map<String, Map<String, Map<String, Integer>>> allTrainFileSegsMap = new HashMap<String, Map<String, Map<String, Integer>>>();
/**
* 放大因子
* 在计算中,因各个词的先验概率都比较小,我们乘以固定的值放大,便于计算
*/
private static BigDecimal zoomFactor = new BigDecimal(10); /**
* 对传入的训练集进行分词,获取训练集分词后的词和词频集合
* @param trainFilePath 训练集路径
*/
public static void getFeatureClassForTrainText(String trainFilePath){
//通过将训练集路径字符串转变成抽象路径,创建一个File对象
File trainFileDirs = new File(trainFilePath);
//获取该路径下的所有分类路径
File[] trainFileDirList = trainFileDirs.listFiles();
if (trainFileDirList == null){
System.out.println("训练数据集不存在");
}
for (File trainFileDir : trainFileDirList){
//读取该分类下的所有训练文件
List<String> fileList = null;
try {
fileList = FileOptionUtil.readDirs(trainFileDir.getAbsolutePath());
if (fileList.size() != 0){
//遍历训练集目录数据,进行分词和类别标签处理
for(String filePath : fileList){
System.out.println("开始对此训练集进行分词处理:" + filePath);
//分词处理,获取每条训练集文本的词和词频
//若知道文件编码的话,不要用下述的判断编码格式了,效率太低
// Map<String, Integer> contentSegs = IKWordSegmentation.segString(FileOptionUtil.readFile(filePath, FileOptionUtil.getCodeString(filePath)));
Map<String, Integer> contentSegs = IKWordSegmentation.segString(FileOptionUtil.readFile(filePath, "gbk"));
if (allTrainFileSegsMap.containsKey(trainFileDir.getName())){
Map<String, Map<String, Integer>> allSegsMap = allTrainFileSegsMap.get(trainFileDir.getName());
allSegsMap.put(filePath, contentSegs);
allTrainFileSegsMap.put(trainFileDir.getName(), allSegsMap);
} else {
Map<String, Map<String, Integer>> allSegsMap = new HashMap<String, Map<String, Integer>>();
allSegsMap.put(filePath, contentSegs);
allTrainFileSegsMap.put(trainFileDir.getName(), allSegsMap);
}
}
} else {
System.out.println("该分类下没有待训练语料");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

第二步计算类别的先验概率

/**
* 计算类别C的先验概率
* 先验概率P(c)= 类c下单词总数/整个训练样本的单词总数
* @param category
* @return 类C的先验概率
*/
public static BigDecimal prioriProbability(String category){
BigDecimal categoryWordsCount = new BigDecimal(categoryWordCount(category));
BigDecimal allTrainFileWordCount = new BigDecimal(getAllTrainCategoryWordsCount());
return categoryWordsCount.divide(allTrainFileWordCount, 10, BigDecimal.ROUND_CEILING);
}

第三步计算特征词的条件概率

/**
* 多项式朴素贝叶斯类条件概率
* 类条件概率P(IK|c)=(类c下单词IK在各个文档中出现过的次数之和+1)/(类c下单词总数+|V|)
* V是训练样本的单词表(即抽取单词,单词出现多次,只算一个),
* |V|则表示训练样本包含多少种单词。 P(IK|c)可以看作是单词tk在证明d属于类c上提供了多大的证据,
* 而P(c)则可以认为是类别c在整体上占多大比例(有多大可能性)
* @param category
* @param word
* @return
*/
public static BigDecimal categoryConditionalProbability(String category, String word){
BigDecimal wordCount = new BigDecimal(wordInCategoryCount(word, category) + 1);
BigDecimal categoryTrainFileWordCount = new BigDecimal(categoryWordCount(category) + getAllTrainCategoryWordCount());
return wordCount.divide(categoryTrainFileWordCount, 10, BigDecimal.ROUND_CEILING);
}

第四步计算给定文本的分类结果

/**
* 多项式朴素贝叶斯分类结果
* P(C_i|w_1,w_2...w_n) = P(w_1,w_2...w_n|C_i) * P(C_i) / P(w_1,w_2...w_n)
* = P(w_1|C_i) * P(w_2|C_i)...P(w_n|C_i) * P(C_i) / (P(w_1) * P(w_2) ...P(w_n))
* @param words
* @return
*/
public static Map<String, BigDecimal> classifyResult(Set<String> words){
Map<String, BigDecimal> resultMap = new HashMap<String, BigDecimal>();
//获取训练语料集所有的分类集合
Set<String> categorySet = allTrainFileSegsMap.keySet();
//循环计算每个类别的概率
for (String categorySetLabel : categorySet){
BigDecimal probability = new BigDecimal(1.0);
for (String word : words){
probability = probability.multiply(categoryConditionalProbability(categorySetLabel, word)).multiply(zoomFactor);
}
resultMap.put(categorySetLabel, probability.multiply(prioriProbability(categorySetLabel)));
}
return resultMap;
}

辅助函数

/**
* 对分类结果进行比较,得出概率最大的类
* @param classifyResult
* @return
*/
public static String getClassifyResultName(Map<String, BigDecimal> classifyResult){
String classifyName = "";
if (classifyResult.isEmpty()){
return classifyName;
}
BigDecimal result = new BigDecimal(0);
Set<String> classifyResultSet = classifyResult.keySet();
for (String classifyResultSetString : classifyResultSet){
if (classifyResult.get(classifyResultSetString).compareTo(result) >= 1){
result = classifyResult.get(classifyResultSetString);
classifyName = classifyResultSetString;
}
}
return classifyName;
} /**
* 统计给定类别下的单词总数(带词频计算)
* @param categoryLabel 指定类别参数
* @return
*/
public static Long categoryWordCount(String categoryLabel){
Long sum = 0L;
Map<String, Map<String, Integer>> categoryWordMap = allTrainFileSegsMap.get(categoryLabel);
if (categoryWordMap == null){
return sum;
}
Set<String> categoryWordMapKeySet = categoryWordMap.keySet();
for (String categoryLabelString : categoryWordMapKeySet){
Map<String, Integer> categoryWordMapDataMap = categoryWordMap.get(categoryLabelString);
List<Map.Entry<String, Integer>> dataWordMapList = new ArrayList<Map.Entry<String, Integer>>(categoryWordMapDataMap.entrySet());
for (int i=0; i<dataWordMapList.size(); i++){
sum += dataWordMapList.get(i).getValue();
}
}
return sum;
} /**
* 获取训练样本所有词的总数(词总数计算是带上词频的,也就是可以重复算数)
* @return
*/
public static Long getAllTrainCategoryWordsCount(){
Long sum = 0L;
//获取所有分类
Set<String> categoryLabels = allTrainFileSegsMap.keySet();
//循环相加每个类下的词总数
for (String categoryLabel : categoryLabels){
sum += categoryWordCount(categoryLabel);
}
return sum;
} /**
* 获取训练样本下各个类别不重复词的总词数,区别于getAllTrainCategoryWordsCount()方法,此处计算不计算词频
* 备注:此处并不是严格意义上的进行全量词表生成后的计算,也就是加入类别1有"中国=6"、类别2有"中国=2",总词数算中国两次,
* 也就是说,我们在计算的时候并没有生成全局词表(将所有词都作为出现一次)
* @return
*/
public static Long getAllTrainCategoryWordCount(){
Long sum = 0L;
//获取所有分类
Set<String> categoryLabels = allTrainFileSegsMap.keySet();
for (String cateGoryLabelsLabel : categoryLabels){
Map<String, Map<String, Integer>> categoryWordMap = allTrainFileSegsMap.get(cateGoryLabelsLabel);
List<Map.Entry<String, Map<String, Integer>>> categoryWordMapList = new ArrayList<Map.Entry<String, Map<String, Integer>>>(categoryWordMap.entrySet());
for (int i=0; i<categoryWordMapList.size(); i++){
sum += categoryWordMapList.get(i).getValue().size();
}
}
return sum;
} /**
* 计算测试数据的每个单词在每个类下出现的总数
* @param word
* @param categoryLabel
* @return
*/
public static Long wordInCategoryCount(String word, String categoryLabel){
Long sum = 0L;
Map<String, Map<String, Integer>> categoryWordMap = allTrainFileSegsMap.get(categoryLabel);
Set<String> categoryWordMapKeySet = categoryWordMap.keySet();
for (String categoryWordMapKeySetFile : categoryWordMapKeySet){
Map<String, Integer> categoryWordMapDataMap = categoryWordMap.get(categoryWordMapKeySetFile);
Integer value = categoryWordMapDataMap.get(word);
if (value!=null && value>0){
sum += value;
}
}
return sum;
} /**
* 获取所有分类类别
* @return
*/
public Set<String> getAllCategory(){
return allTrainFileSegsMap.keySet();
}

main函数测试

//main方法
public static void main(String[] args){
BayesNB.getFeatureClassForTrainText("/Users/zhouyh/work/yanfa/xunlianji/train/");
String s = "全国假日旅游部际协调会议的各成员单位和中央各有关部门围绕一个目标,积极配合,主动工作,抓得深入,抓得扎实。主要有以下几个特点:一是安全工作有部署有检查有跟踪。国务院安委会办公室节前深入部署全面检查,节中及时总结,下发关于黄金周后期安全工作的紧急通知;铁路、民航、交通等部门针对黄金周前后期旅客集中返程交通压力较大情况,及时调遣应急运力;质检总局进一步强化节日期间质量安全监管工作;旅游部门每日及时发布旅游信息通报,有效引导游客。二是各方面主动协调密切配合。各省区市加强了在安全事故问题上的协调与沟通,化解了一些跨省区矛盾和问题;铁道、民航部门准时准确报送信息;中宣部和中央文明办以黄金周旅游为载体," +
"部署精神文明建设和践行社会主义荣辱观的宣传活动;中国气象局及时将黄金周每日气象分析送交各有关部门;公安部专门部署警力,为协调游客流动大的城市及景区做了大量工作;旅游部门密切配合有关部门做好各类事故处理和投诉调解工作。三是政府各部门的社会服务意识大为增强。外交部及其驻外领事馆及时提供境外安全信息为旅游者服务;中央电视台、地方电视台和各大媒体及各地方媒体提供的旅游信息十分丰富;气象信息服务充分具体;中消协提出多项旅游警示。各部门的密切配合和主动服务配合,确保了本次黄金周的顺利平稳运行。";
Set<String> words = IKWordSegmentation.segString(s).keySet(); Map<String, BigDecimal> resultMap = BayesNB.classifyResult(words);
String category = BayesNB.getClassifyResultName(resultMap);
System.out.println(category);
}

经过上述步骤即可实现简单的多项式模型算法,有部分代码参考了网上的算法代码。

朴素贝叶斯算法java实现(多项式模型)的更多相关文章

  1. 利用朴素贝叶斯算法进行分类-Java代码实现

    http://www.crocro.cn/post/286.html 利用朴素贝叶斯算法进行分类-Java代码实现  鳄鱼  3个月前 (12-14)  分类:机器学习  阅读(44)  评论(0) ...

  2. 朴素贝叶斯算法原理及Spark MLlib实例(Scala/Java/Python)

    朴素贝叶斯 算法介绍: 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法. 朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,在没有其它可用信息下,我 ...

  3. 朴素贝叶斯算法的python实现

    朴素贝叶斯 算法优缺点 优点:在数据较少的情况下依然有效,可以处理多类别问题 缺点:对输入数据的准备方式敏感 适用数据类型:标称型数据 算法思想: 朴素贝叶斯比如我们想判断一个邮件是不是垃圾邮件,那么 ...

  4. 【十大算法实现之naive bayes】朴素贝叶斯算法之文本分类算法的理解与实现

    关于bayes的基础知识,请参考: 基于朴素贝叶斯分类器的文本聚类算法 (上) http://www.cnblogs.com/phinecos/archive/2008/10/21/1315948.h ...

  5. Python机器学习笔记:朴素贝叶斯算法

    朴素贝叶斯是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法.对于大多数的分类算法,在所有的机器学习分类算法中,朴素贝叶斯和其他绝大多数的分类算法都不同.比如决策树,KNN,逻辑回归,支持向 ...

  6. 朴素贝叶斯算法的python实现方法

    朴素贝叶斯算法的python实现方法 本文实例讲述了朴素贝叶斯算法的python实现方法.分享给大家供大家参考.具体实现方法如下: 朴素贝叶斯算法优缺点 优点:在数据较少的情况下依然有效,可以处理多类 ...

  7. 朴素贝叶斯算法下的情感分析——C#编程实现

    这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Pr ...

  8. 【数据挖掘】朴素贝叶斯算法计算ROC曲线的面积

    题记:          近来关于数据挖掘学习过程中,学习到朴素贝叶斯运算ROC曲线.也是本节实验课题,roc曲线的计算原理以及如果统计TP.FP.TN.FN.TPR.FPR.ROC面积等等.往往运用 ...

  9. C#编程实现朴素贝叶斯算法下的情感分析

    C#编程实现 这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Lang ...

随机推荐

  1. Java常用API(Arrays类)

    Java常用API(Arrays类) 什么是Arrays类? java.util.Arrays 此类包含用来操作数组的各种方法,比如排序和搜索等.其所有方法均为静态方法,调用起来 非常简单. 这里我们 ...

  2. 没想到 Google 排名第一的编程语言,为什么会这么火?

    没想到吧,Python 又拿第一了! 在 Google 公布的编程语言流行指数中,Python 依旧是全球范围内最受欢迎的技术语言!   01 为什么 Python 会这么火? 核心还是因为企业需要用 ...

  3. Ethical Hacking - NETWORK PENETRATION TESTING(15)

    ARP Poisoning - arpspoof Arpspoof is a tool part of a suit called dsniff, which contains a number of ...

  4. Oracle RMAN 异机恢复一例

    背景介绍:本例需求是将NBU备份的oracle数据库恢复到另一主机上. NBU环境配置.异机上的Oracle软件安装配置忽略,下面只介绍OracleDB恢复的过程. ----------------- ...

  5. 设计模式:interpreter模式

    理解:可以广义的理解为创造一种语言,实现该语言的解释器,然后用创造的语言编写程序 对比:如xml就是一种语言,解析xml的代码就是解释器 例子: //目标:定义4中几种命令,使用C++解析 //如下: ...

  6. 【工具】- HttpClient篇

    简介 对于httpclient,相信很多人或多或少接触过,对于httpclient的使用姿势,相信很多人会有疑问?下面这边会通过代码说明 package xxx; import org.apache. ...

  7. 自已动手作图搞清楚AVL树

    @ 目录 一.背景 二.平衡二分搜索树---AVL树 2.1 AVL树的基本概念 结点 高度 平衡因子 2.2 AVL树的验证 三.旋转操作 3.1 L L--需要通过右旋操作 3.2 R R--需要 ...

  8. 云上自动化 vs 云上编排

    1 摘要 本文介绍了为什么在一个好的公有云或私有云中必须要有一个编排系统来支持云上自动化,以及实现这个编排系统的困难和各家的努力.同时提供了一套实现编排系统的原型,它包括了理论分析及主体插件框架,还给 ...

  9. 5.pandas新增数据列

    有的时候,表格自带的数据根本没有办法满足我们,我们经常会新加一列数据或者对原有的数据进行修改 还是接着上篇文章的数据进行操作 直接赋值 我想算一下每一天的温差 df.loc[:, 'wencha'] ...

  10. 解决智慧城市发展困扰:Web 3D 智慧环卫 GIS 系统

    前言 智慧环卫,依托物联网技术与移动互联网技术,对环卫管理所涉及到的人.车.物.事进行全过程实时管理,合理设计规划环卫管理模式,提升环卫作业质量,降低环卫运营成本,用数字评估和推动垃圾分类管理实效.智 ...