基于朴素贝叶斯的兴趣分类
寒假期间使用了朴素贝叶斯算法对用户画像中的用户兴趣进行了分类,然而最终预测的准确率以及召回率却不尽如人意,这里就谈谈朴素贝叶斯算法的使用以及我对此次失败的一个小小反思吧~
关于分类
分类是将一个未知样本分到几个预先已知类的过程。在众多的分类模型中,应用最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBC)。
分类模型 | 优点 | 缺点 |
---|---|---|
决策树 | 根据决策树可以很容易地构造出规则,而规则通常易于解释和理解;决策树可很好地扩展到大型数据库中,同时它的大小独立于数据库的大小;决策树模型的另外一大优点就是可以对有许多属性的数据集构造决策树。 | 处理缺失数据时的困难,过度拟合问题的出现,以及忽略数据集中属性之间的相关性等。 |
朴素贝叶斯 | 有稳定的分类效率。对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。对缺失数据不太敏感,算法也比较简单,常用于文本分类。 | 需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。 |
关于朴素贝叶斯
朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。朴素贝叶斯分类器模型会给问题实例分配用特征值表示的类标签,类标签取自有限集合。朴素贝叶斯分类器基于一个简单的假定:给定目标值时属性之间相互条件独立。举个例子,如果一种水果其具有红,圆,直径大概3英寸等特征,该水果可以被判定为是苹果。尽管这些特征相互依赖或者有些特征由其他特征决定,然而朴素贝叶斯分类器认为这些属性在判定该水果是否为苹果的概率分布上独立的。
关于朴素贝叶斯的原理网上资料很多,具体内容可以参考此博客:http://www.cnblogs.com/leoo2sk/archive/2010/09/17/naive-bayesian-classifier.html
项目思路
1.确定分类
我们是按照微博的兴趣分类将兴趣分为24个类别,并赋予特征词大约每个类别500个,将每个类别放置在一个txt文件中
2.获取标签特征
//获取标签特征词(!!发现隐藏文件,由于使用过gedit打开过),形成一个vocabularyList<String > vocabulary = new ArrayList<String>();File dir = new File("/home/hadoop/项目内容/类别库");File[] files = dir.listFiles(); //获取不同类别的标签文件System.out.println(files.length);StringBuilder sb = new StringBuilder();for(File file : files){BufferedReader br = new BufferedReader(new FileReader(file));String line = null;while((line = br.readLine()) != null){sb.append(line); //按"`"分割不同类别的标签}sb.append(line + "`");}String[] tags = sb.toString().trim().split("`");List<String> newTags = new ArrayList<String>();for(String tag: tags){if(tag.length() > 4){newTags.add(tag); //去除空行标签}}Object[] newtags = newTags.toArray();List<Tuple2<Integer,String>> list = new ArrayList<Tuple2<Integer,String>>(); //记录每类中的标签for(int i = 0; i<newtags.length;i++){Tuple2<Integer,String> classWithTags = new Tuple2<Integer, String>(i,(String)newtags[i]);System.out.println(classWithTags);list.add(classWithTags);String[] tokens = ((String)newtags[i]).split("/");for(String tag: tokens){vocabulary.add(tag);}}
3.获取训练样本
此处的训练样本则为各个分类的特征词~
//获取训练样本JavaPairRDD<Integer,String> trainRDD = sc.parallelizePairs(list); //将每类的标签词转化为RDDJavaPairRDD<Integer,String> trainSetRDD = trainRDD.mapValues(new ToTrainSet(vocabulary)); //将标签词转化为向量模型List<Tuple2<Integer,String>> trainSet = trainSetRDD.collect();writeTrainSet(trainSet); //写成libsvm文件格式,以方便训练System.out.println("trainset is ok");
4.训练模型
//读取训练集并训练模型String path = "./trainset";JavaRDD<LabeledPoint> trainData = MLUtils.loadLibSVMFile(sc.sc(),path).toJavaRDD();model = NaiveBayes.train(trainData.rdd(),1.0);System.out.println("model is ok");
5.预测测试集
测试集是挑选每个用户关注的大V及其简介, 利用HanLP进行切词
//读取txt文件并利用hanlp切词形成一个list,作为测试样本String filepath = "/home/hadoop/result/19岁金鱼想当歌手.txt";File inputfile = new File(filepath);rewriteFile(filepath);String content = readTxtFile(inputfile); //获取txt的内容System.out.print(content);Segment segment = HanLP.newSegment();List<Term> termList = segment.seg(content); //用Hanlp进行切词形成Listfor(Term term : termList){testStr += term.word + " "; //使用term.word去掉属性部分}
//预测测试集double[] testArray = sentenceToArrays(vocabulary,testStr);writeTestSet(testArray);String testPath = "./testset";JavaRDD<LabeledPoint> testData = MLUtils.loadLibSVMFile(sc.sc(), testPath).toJavaRDD();
6.选取概率值前三的兴趣存档
即每个用户确定3个兴趣
预测效果
对每个用户的兴趣进行分类后,为了验证算法的准确率以及召回率,我是随机选择了500个用户进行人工标注其兴趣,兴趣的个数不限,后利用公式
代码实现如下:
Map<String,String> human = new HashMap<String,String>();Map<String,String> predict = new HashMap<String,String>();String humanpath = "/home/hadoop/Seeing项目内容/result/人工标注/人工标注用户";String predictpath = "/home/hadoop/Seeing项目内容/result/人工标注/新机器";//将人工标注的放于human中BufferedReader human_br = new BufferedReader(new FileReader(new File(humanpath)));String human_interest = "";while((human_interest = human_br.readLine()) != null){String[] content = human_interest.split(" ");human.put(content[0], content[1]); }//将机器标注的放于predict中BufferedReader predict_br = new BufferedReader(new FileReader(new File(predictpath)));String predict_interest = "";while((predict_interest = predict_br.readLine()) != null){String[] content1 = predict_interest.split(" ");predict.put(content1[0], content1[1]);}//计算准确率和召回率//先转成setSet human_set = human.entrySet();Set predict_set = predict.entrySet();int i = 0;double accuracy = 0;double recall = 0;for(Iterator iter1 = predict_set.iterator(); iter1.hasNext();){String[] predictinterests = {};String[] humaninterests = {};//交集个数double result_insect =0;Map.Entry<String , String> entry1 = (Map.Entry<String, String>) iter1.next();String predictkey = entry1.getKey();String predictvalue = entry1.getValue();predictinterests = predictvalue.split(",");for(Iterator iter2 = human_set.iterator();iter2.hasNext();){Map.Entry<String, String> entry2 = (Map.Entry<String, String>) iter2.next();String humankey = entry2.getKey();String humanvalue = entry2.getValue();
// System.out.println(humanvalue);humaninterests = humanvalue.split(",");if(humankey.equals(predictkey)){//求交集i++;result_insect = intersect(predictinterests, humaninterests);
// System.out.println(result_insect);double a = predictinterests.length;double b = humaninterests.length;accuracy = (result_insect/predictinterests.length + accuracy*(i-1))/i;recall =( result_insect/humaninterests.length + recall *(i-1))/i;
// System.out.println(i+ " "+ result_insect + " "+ a + " "+ b);}
结果如图:
反思
准确率和召回率都惊人的低,个人感觉原因应该有以下几点:
1.人工标注会有些疏忽,另外就是微博兴趣的特征词所构建的词典会随时间的问题有一些特征词不再适用;
2.朴素贝叶斯本身的缺点导致,由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。
3.朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。
接下来会继续改进兴趣分类的实现,各位大佬走过路过也可以提提建议~谢谢O(∩_∩)O
基于朴素贝叶斯的兴趣分类相关推荐
- 朴素贝叶斯网络matlab实现_基于朴素贝叶斯的文本分类方法实战
基于朴素贝叶斯的文本分类方法 一.朴素贝叶斯原理的介绍 二.朴素贝叶斯分类器的代码实现 分类器有时会产生错误结果,这时可以要求分类器给出一个最优的类别猜测结果,同时会给出这个猜测的概率估计值.朴素贝叶 ...
- 基于朴素贝叶斯实现文本分类
基于朴素贝叶斯实现文本分类 数据集介绍 数据集为网上公开的新闻数据,其中数据集包含10个类别. 模型选择 贝叶斯分类 贝叶斯公式 朴素贝叶斯 拉普拉斯平滑引入 某个属性的条件概率为0,则会导致整体概率 ...
- 基于朴素贝叶斯的文本分类算法
基于朴素贝叶斯的文本分类算法 摘要:常用的文本分类方法有支持向量机.K-近邻算法和朴素贝叶斯.其中朴素贝叶斯具有容易实现,运行速度快的特点,被广泛使用.本文详细介绍了朴素贝叶斯的基本原理,讨论多项式模 ...
- 朴素贝叶斯基于朴素贝叶斯的文本分类算法
朴素贝叶斯 以及 基于朴素贝叶斯的文本分类算法 参考文章: https://www.cnblogs.com/jorbin/articles/1915888.html
- 朴素贝叶斯文本分类java_基于朴素贝叶斯的文本分类算法
基于朴素贝叶斯的文本分类算法 摘要:常用的文本分类方法有支持向量机.K-近邻算法和朴素贝叶斯.其中朴素贝叶斯具有容易实现,运行速度快的特点,被广泛使用.本文详细介绍了朴素贝叶斯的基本原理,讨论多项式模 ...
- HanLP 基于朴素贝叶斯 训练 文本分类
一.HanLP 朴素贝叶斯分类器 HanLP 针对文本分类算法已经帮我们实现 朴素贝叶斯法 ,用户可以无需关心内部细节,HanLP 也提供了相关自定义训练接口,前提需要将数据集根据分类放到不同的目录中 ...
- 基于朴素贝叶斯的垃圾邮件分类-着重理解拉普拉斯变换
1. 引言 在正式学习朴素贝叶斯之前,需要明确的是机器学习所要实现的是基于有限的训练样本集尽可能准确地估计出后验概率P(c|x),即根据特征得到所属类别的概率,首先引入两个概念. 判别式模型(disc ...
- 详解基于朴素贝叶斯的情感分析及 Python 实现
相对于「 基于词典的分析 」,「 基于机器学习 」的就不需要大量标注的词典,但是需要大量标记的数据,比如: 还是下面这句话,如果它的标签是: 服务质量 - 中 (共有三个级别,好.中.差) ╮(╯-╰ ...
- 朴素贝叶斯情感分析评分python_详解基于朴素贝叶斯的情感分析及 Python 实现
相对于「 基于词典的分析 」,「 基于机器学习 」的就不需要大量标注的词典,但是需要大量标记的数据,比如: 还是下面这句话,如果它的标签是: 服务质量 - 中 (共有三个级别,好.中.差) �r(�s ...
- 朴素贝叶斯情感分析评分python_详解基于朴素贝叶斯的情感分析及Python实现
朴素贝叶斯 1.贝叶斯定理 假设对于某个数据集,随机变量C表示样本为C类的概率,F1表示测试样本某特征出现的概率,套用基本贝叶斯公式,则如下所示: 上式表示对于某个样本,特征F1出现时,该样本被分为C ...
最新文章
- 3分钟4 步快速带你在win10电脑装上openCV3.4 (python使用)
- 力扣(LeetCode)刷题,简单题(第24期)
- pyqt webview 执行js
- 久违了我的博客园《人生的体会》
- python当中的生成器
- CSS文本对齐text-align详解
- [ZJJOI2013]K大数查询 整体二分
- mysql8 距离计算_MySQL8 的 Hash join 算法
- java面试的计算机网络_Java面试总结之计算机网络(二)
- python验证码校验代码_python 图片验证码代码
- 数据-第9课-静态链表
- 国内自动化测试软件,AutoRunner-国内测试行业专业自动化测试工具成长史
- 国人自研开源项目,一款简单易用的 GitLab 替代品
- 魅族7.0系统最简单激活Xposed框架的经验
- PhotoZoom pro8官方激活下载免费版无损放大图片工具
- 电脑蓝牙耳机,蓝牙耳机,详细教您蓝牙耳机怎么连接电脑
- Day13_JavaWeb
- 软件设计师下午真题及参考答案
- 【深度强化学习】6. Q-Learning技巧及其改进方案
- 传输层协议 —— UDP