- 浏览: 230513 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
清林小篆:
引用[/col[size=xx-small][/size]or ...
tomcat ssl配置以及CAS单点登录探究 -
cyxy99:
u012534143 写道我用同样的方法,同样的节点关系,为什 ...
PageRank算法java实现版本 -
cyxy99:
schaha123 写道楼主还有一个问题想请教一下,下面这2段 ...
PageRank算法java实现版本 -
njthnet:
Participle 和 IkParticiple 这2个类找 ...
贝叶斯文本分类 java实现 -
u012534143:
我用同样的方法,同样的节点关系,为什么的得到的结果与您不一样呢 ...
PageRank算法java实现版本
昨天实现了一个基于贝叶斯定理的的文本分类,贝叶斯定理假设特征属性(在文本中就是词汇)对待分类项的影响都是独立的,道理比较简单,在中文分类系统中,分类的准确性与分词系统的好坏有很大的关系,这段代码也是试验不同分词系统才顺手写的一个。
试验数据用的sogou实验室的文本分类样本,一共分为9个类别,每个类别文件夹下大约有2000篇文章。由于文本数据量确实较大,所以得想办法让每次训练的结果都能保存起来,以便于下次直接使用,我这里使用序列化的方式保存在硬盘。
训练代码如下:
在试验过程中,发觉某篇文章的分类不太准,某篇IT文章分到招聘类别下了,在仔细对比了训练数据后,发觉这是由于招聘类别每篇文章下面都带有“搜狗”的标志,而待分类的这篇IT文章里面充斥这搜狗这类词汇,结果招聘类下的概率比较大。由此想到,在除了做常规的贝叶斯计算时,需要把不同文本中出现次数多的词汇权重降低甚至删除(好比关键词搜索中的tf-idf),通俗点讲就是,在所有训练文本中某词汇(如的,地,得)出现的次数越多,这个词越不重要,比如IT文章中“软件”和“应用”这两个词汇,“应用”应该是很多文章类别下都有的,反而不太重要,但是“软件”这个词汇大多只出现在IT文章里,出现在大量文章的概率并不大。 我这里原本打算计算每个词的idf,然后给定一个阀值来判断是否需要纳入计算,但是由于词汇太多,计算量较大(等待结果时间较长),所以暂时注释掉了。
By 阿飞哥 转载请说明
腾讯微博:http://t.qq.com/duyunfeiRoom
新浪微博:http://weibo.com/u/1766094735
试验数据用的sogou实验室的文本分类样本,一共分为9个类别,每个类别文件夹下大约有2000篇文章。由于文本数据量确实较大,所以得想办法让每次训练的结果都能保存起来,以便于下次直接使用,我这里使用序列化的方式保存在硬盘。
训练代码如下:
/** * 训练器 * * @author duyf * */ class Train implements Serializable { /** * */ private static final long serialVersionUID = 1L; public final static String SERIALIZABLE_PATH = "D:\\workspace\\Test\\SogouC.mini\\Sample\\Train.ser"; // 训练集的位置 private String trainPath = "D:\\workspace\\Test\\SogouC.mini\\Sample"; // 类别序号对应的实际名称 private Map<String, String> classMap = new HashMap<String, String>(); // 类别对应的txt文本数 private Map<String, Integer> classP = new ConcurrentHashMap<String, Integer>(); // 所有文本数 private AtomicInteger actCount = new AtomicInteger(0); // 每个类别对应的词典和频数 private Map<String, Map<String, Double>> classWordMap = new ConcurrentHashMap<String, Map<String, Double>>(); // 分词器 private transient Participle participle; private static Train trainInstance = new Train(); public static Train getInstance() { trainInstance = new Train(); // 读取序列化在硬盘的本类对象 FileInputStream fis; try { File f = new File(SERIALIZABLE_PATH); if (f.length() != 0) { fis = new FileInputStream(SERIALIZABLE_PATH); ObjectInputStream oos = new ObjectInputStream(fis); trainInstance = (Train) oos.readObject(); trainInstance.participle = new IkParticiple(); } else { trainInstance = new Train(); } } catch (Exception e) { e.printStackTrace(); } return trainInstance; } private Train() { this.participle = new IkParticiple(); } public String readtxt(String path) { BufferedReader br = null; StringBuilder str = null; try { br = new BufferedReader(new FileReader(path)); str = new StringBuilder(); String r = br.readLine(); while (r != null) { str.append(r); r = br.readLine(); } return str.toString(); } catch (IOException ex) { ex.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } str = null; br = null; } return ""; } /** * 训练数据 */ public void realTrain() { // 初始化 classMap = new HashMap<String, String>(); classP = new HashMap<String, Integer>(); actCount.set(0); classWordMap = new HashMap<String, Map<String, Double>>(); // classMap.put("C000007", "汽车"); classMap.put("C000008", "财经"); classMap.put("C000010", "IT"); classMap.put("C000013", "健康"); classMap.put("C000014", "体育"); classMap.put("C000016", "旅游"); classMap.put("C000020", "教育"); classMap.put("C000022", "招聘"); classMap.put("C000023", "文化"); classMap.put("C000024", "军事"); // 计算各个类别的样本数 Set<String> keySet = classMap.keySet(); // 所有词汇的集合,是为了计算每个单词在多少篇文章中出现,用于后面计算df final Set<String> allWords = new HashSet<String>(); // 存放每个类别的文件词汇内容 final Map<String, List<String[]>> classContentMap = new ConcurrentHashMap<String, List<String[]>>(); for (String classKey : keySet) { Participle participle = new IkParticiple(); Map<String, Double> wordMap = new HashMap<String, Double>(); File f = new File(trainPath + File.separator + classKey); File[] files = f.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.getName().endsWith(".txt")) { return true; } return false; } }); // 存储每个类别的文件词汇向量 List<String[]> fileContent = new ArrayList<String[]>(); if (files != null) { for (File txt : files) { String content = readtxt(txt.getAbsolutePath()); // 分词 String[] word_arr = participle.participle(content, false); fileContent.add(word_arr); // 统计每个词出现的个数 for (String word : word_arr) { if (wordMap.containsKey(word)) { Double wordCount = wordMap.get(word); wordMap.put(word, wordCount + 1); } else { wordMap.put(word, 1.0); } } } } // 每个类别对应的词典和频数 classWordMap.put(classKey, wordMap); // 每个类别的文章数目 classP.put(classKey, files.length); actCount.addAndGet(files.length); classContentMap.put(classKey, fileContent); } // 把训练好的训练器对象序列化到本地 (空间换时间) FileOutputStream fos; try { fos = new FileOutputStream(SERIALIZABLE_PATH); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(this); } catch (Exception e) { e.printStackTrace(); } } /** * 分类 * * @param text * @return 返回各个类别的概率大小 */ public Map<String, Double> classify(String text) { // 分词,并且去重 String[] text_words = participle.participle(text, false); Map<String, Double> frequencyOfType = new HashMap<String, Double>(); Set<String> keySet = classMap.keySet(); for (String classKey : keySet) { double typeOfThis = 1.0; Map<String, Double> wordMap = classWordMap.get(classKey); for (String word : text_words) { Double wordCount = wordMap.get(word); int articleCount = classP.get(classKey); /* * Double wordidf = idfMap.get(word); if(wordidf==null){ * wordidf=0.001; }else{ wordidf = Math.log(actCount / wordidf); } */ // 假如这个词在类别下的所有文章中木有,那么给定个极小的值 不影响计算 double term_frequency = (wordCount == null) ? ((double) 1 / (articleCount + 1)) : (wordCount / articleCount); // 文本在类别的概率 在这里按照特征向量独立统计,即概率=词汇1/文章数 * 词汇2/文章数 。。。 // 当double无限小的时候会归为0,为了避免 *10 typeOfThis = typeOfThis * term_frequency * 10; typeOfThis = ((typeOfThis == 0.0) ? Double.MIN_VALUE : typeOfThis); // System.out.println(typeOfThis+" : "+term_frequency+" : // "+actCount); } typeOfThis = ((typeOfThis == 1.0) ? 0.0 : typeOfThis); // 此类别文章出现的概率 double classOfAll = classP.get(classKey) / actCount.doubleValue(); // 根据贝叶斯公式 $(A|B)=S(B|A)*S(A)/S(B),由于$(B)是常数,在这里不做计算,不影响分类结果 frequencyOfType.put(classKey, typeOfThis * classOfAll); } return frequencyOfType; } public void pringAll() { Set<Entry<String, Map<String, Double>>> classWordEntry = classWordMap .entrySet(); for (Entry<String, Map<String, Double>> ent : classWordEntry) { System.out.println("类别: " + ent.getKey()); Map<String, Double> wordMap = ent.getValue(); Set<Entry<String, Double>> wordMapSet = wordMap.entrySet(); for (Entry<String, Double> wordEnt : wordMapSet) { System.out.println(wordEnt.getKey() + ":" + wordEnt.getValue()); } } } public Map<String, String> getClassMap() { return classMap; } public void setClassMap(Map<String, String> classMap) { this.classMap = classMap; } }
在试验过程中,发觉某篇文章的分类不太准,某篇IT文章分到招聘类别下了,在仔细对比了训练数据后,发觉这是由于招聘类别每篇文章下面都带有“搜狗”的标志,而待分类的这篇IT文章里面充斥这搜狗这类词汇,结果招聘类下的概率比较大。由此想到,在除了做常规的贝叶斯计算时,需要把不同文本中出现次数多的词汇权重降低甚至删除(好比关键词搜索中的tf-idf),通俗点讲就是,在所有训练文本中某词汇(如的,地,得)出现的次数越多,这个词越不重要,比如IT文章中“软件”和“应用”这两个词汇,“应用”应该是很多文章类别下都有的,反而不太重要,但是“软件”这个词汇大多只出现在IT文章里,出现在大量文章的概率并不大。 我这里原本打算计算每个词的idf,然后给定一个阀值来判断是否需要纳入计算,但是由于词汇太多,计算量较大(等待结果时间较长),所以暂时注释掉了。
By 阿飞哥 转载请说明
腾讯微博:http://t.qq.com/duyunfeiRoom
新浪微博:http://weibo.com/u/1766094735
评论
3 楼
njthnet
2016-06-07
Participle 和 IkParticiple 这2个类找不到,能给个提示吗?
2 楼
u010402518
2015-10-15
分类还是可行的,如果学习的在多一点那就会更准了。
给大家一个调用的例子
Train train = Train.getInstance();
// 训练,训练好模型之后序列化到磁盘就不用再次训练了
//train.realTrain();
Map<String, Double> resultMap = train.classify("胡润研究院今日发布《胡润百富榜》,61岁的王健林及其家族以2200亿财富超过马云,第二次成为中国首富,财富比去年增长52%。大陆十亿美金富豪人数首度超越美国,达596位。51岁的马云及其家族以1450亿元退居第二,财富比去年减少3%");
train.pringAll();
给大家一个调用的例子
Train train = Train.getInstance();
// 训练,训练好模型之后序列化到磁盘就不用再次训练了
//train.realTrain();
Map<String, Double> resultMap = train.classify("胡润研究院今日发布《胡润百富榜》,61岁的王健林及其家族以2200亿财富超过马云,第二次成为中国首富,财富比去年增长52%。大陆十亿美金富豪人数首度超越美国,达596位。51岁的马云及其家族以1450亿元退居第二,财富比去年减少3%");
train.pringAll();
1 楼
u010402518
2015-10-15
文章写的不错,思路很清晰,终于找到了一篇可以用的文章 。
发表评论
-
招Java培训老师(还是论坛招人靠谱)
2015-05-10 13:39 556好久没来坛子了,一来就搞这么有目的的事儿。。。 好吧, ... -
动手开发自己的mvc-3----容器该帮我们做什么?(非常的重点)
2013-01-22 13:55 1782注解注入 我们知道,Spring只有一个角色:工厂。这个工厂可 ... -
动手开发自己的mvc-2----完善控制层,提供自动注入和注解上传等功能
2013-01-22 13:44 2502当表单提交的内容过多 ,让懒惰的程序员一个个getPara ... -
动手开发自己的mvc-1----实现初步的控制层,实现各种配置和资源获取
2013-01-22 13:28 2741mvc框架最基础的功能就是跳转,struts2支持注 ... -
动手开发自己的mvc (系列)
2013-01-22 14:08 1890到年尾了,整理了一下我Evernote藏的各种文档,打算把ys ... -
linux下安装配置svn服务
2013-01-21 17:12 2635今天在阿里云架了一个svn,打算放平时的代码片段,还是记下过程 ... -
整合了一个小的爬取流程框架
2013-01-08 13:04 1270弄了一个小的爬取流程框架,把之前工作中用到的一些小经验 ... -
Mahout各种推荐器的主要特点
2012-12-06 15:17 2927Mahout有很多推荐的实现,各有特点,在这里一并记录 ... -
怎样通过词频得到这个词频的排序?
2012-12-03 14:35 2038在大规模检索中,我们怎样通过已经的词频得到词频的排序 ... -
drools实现自定义业务规则
2012-10-12 11:49 2790最近做财务相关的积分规则,由于这个功能以后涉及到方方面面 ... -
假如现在路边看到一个黑人,他是非洲人的概率怎么算?
2012-08-30 12:49 129假如现在路边看到一个黑人,他是非洲人的概率怎么算? ... -
我常用的js组件,包含自动补全,js字典,table动态增减
2012-08-10 10:42 2140这几个是我自写的常用的js组件,包含自动补全,js字典,t ... -
前段时间做了一个小型的MVC
2012-07-20 13:23 0前端时间做了一个小型的MVC,麻雀虽小,五脏俱全,目前实现的功 ... -
聚类算法之MST算法 java实现版本
2012-07-17 14:20 2736在介绍最小生成树算法(MST)之前,简单说一下平均链接算 ... -
聚类算法之单链接算法java实现
2012-07-05 10:09 4247聚类算法中基于链接的算法大致有三种:单链接算法(s ... -
朴素贝叶斯分类器
2012-05-20 15:25 0NaiveBayes分类器的优点是能得到已知Y的条件下X的 ... -
PageRank算法java实现版本
2012-05-16 16:03 17242PageRank算法是Google的核心搜索算法,在所有 ... -
聚类算法之kmeans算法java版本
2012-04-22 21:34 20803聚类的意思很明确,物以类聚,把类似的事物放在一起。 ... -
昨天做了个小工具DB转pojo,html,sql
2012-03-21 13:15 1708做dbutils时为了方便就做了个小工具,省点小事儿吧。 -
我这儿的讨论(项目小组)区可以进来了
2012-02-28 10:38 150java项目小组群,前几天清了几个破坏气氛者,和不发言 ...
相关推荐
朴素贝叶斯算法文本分类JAVA实现
本项目为一个Hadoop课程设计,使用Java语言和map/reduce实现贝叶斯文本分类器。项目的具体内容如下:1:用MapReduce算法实现贝叶斯分类器的训练过程,并输出训练模型; 2:用输出的模型对测试集文档进行分类测试。...
本程序实现了基于朴素贝叶斯方法的文本分类,附有源代码、实验报告、可执行程序以及语料库(包括训练集和测试集)
使用贝叶斯分类器实现文本文件的分类判别。 1、可以指定训练集进行文本训练; 2、使用训练好的特征值进行未知文件类型的判别。
java 代码实现的网络新闻文本自动分类,采用朴素贝叶斯和支持向量机两种方法实现!
java语言实现的贝叶斯文本分类器,带两个包,记着导好包哦,
贝叶斯文本分类器JAVA,有lucene-core-2.9.4,je-analysis-1.5.1包
Hadoop课程设计-基于Java和mapreduce实现的贝叶斯文本分类器设计; Hadoop课程设计-基于Java和mapreduce实现的贝叶斯文本分类器设计;
基于朴素贝叶斯分类算法
采用贝叶斯算法实现文本基本分类,程序用JAVA实现,运行不错
朴素贝叶斯 文本分类,注释详细,一看就明白,JAVA实现。下载导入即可使用
朴素贝叶斯文本分类算法的java代码 完整版
一个有效的贝叶斯分类器,可以实现简单文本的分类。使用Eclipse可直接运行。
针对Newsgroup20数据集,基于朴素贝叶斯的英文文本分类程序 具体实现实际参考了网上一个博客啦…… Java语言
采用贝叶斯算法实现的文本分类。本源码中已经包含了训练集和测试集数据,分词采用je和lucene包(源码包含),具有简单的界面。当然,你如果想要正常运行自然需要对这两个包进行导入,并且在源码中重新设置文件路径的...
朴素贝叶斯的实现
简单的贝叶斯文本分类器,用java编写,并且有数据挖掘的实验报告
朴素贝叶斯完成文本分类,包含现在常用的文档、单词、混合 3种模型。引入了拉普拉斯平滑技术,通俗易懂。
本文为基于贝叶斯算法和KNN算法的文本分类器Java实现,很详细,在网上找的,给大家共享看看
该项目为Hadoop课程项目,基于MapReduce设计朴素贝叶斯文本分类器,并评估分类结果。 以下简单介绍项目内容与运行说明: ## 项目内容 1. 用MapReduce算法实现贝叶斯分类器的训练过程,并输出训练模型; 2. 用输出...