基于SVMLight的文本分类
支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本 、非线性及高维模式识别 中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中。支持向量机方法是建立在统计学习理论的VC 维理论和结构风险最小 原理基础上的,根据有限的样本信息在模型的复杂性(即对特定训练样本的学习精度,Accuracy)和学习能力(即无错误地识别任意样本的能力)之间寻求最佳折衷,以期获得最好的推广能力(或称泛化能力)。SVM理论的学习,请参考jasper的博客 。
LIBSVM 是台湾大学林智仁(Chih-Jen Lin)博士等开发设计的一个操作简单、易于使用、快速有效的通用 SVM 软件包,可以解决分类问题(包括 C−SVC 、ν−SVC ), 回归问题(包括 ε − SVR 、v− SVR ) 以及分布估计(one − class − SVM ) 等问题,提供了线性、多项式、径向基和 S 形函数四种常用的核函数供选择,可以有效地解决多类问题、交叉验证选择参数、对不平衡样本加权、多类问题的概率估计等。LIBSVM 是一个开源的软件包,。他不仅提供了
LIBSVM 的 C++语言的算法源代码,还提供了 Python、Java、R、MATLAB、Perl、Ruby、LabVIEW以及 C#.net 等各种语言的接口,可以方便的在 Windows 或 UNIX 平台下使用,也便于科研工作者根据自己的需要进行改进(譬如设计使用符合自己特定问题需要的核函数等)。
文本分类,大致分为如下几件事情:样本 ,分词 ,特征提取 ,向量计算 ,分类训练 ,测试和调试 。
1.样本选择
搜狗语料 http://www.sogou.com/labs/dl/c.html ,下精简版吧,如果实验用用,这足够了,你要下107M的也可以。当然,你也可以自己找语料,不过麻烦点而已,把各大门户网站的对应频道下的文章都爬下来。
2.分词
Bamboo分词,这是基于CRF++的分词模块,既然是研究统计学习,分词也得用基于统计的不是,如果还是用一字典来分词,那就太out啦。
http://code.google.com/p/nlpbamboo/wiki/GettingStarted 。安装完毕bamboo,还要下载训练好的模型(这个模型是基于人民日报1月语料)
http://code.google.com/p/nlpbamboo/downloads/list ,下载index.tar.bz2, 解压到/opt/bamboo/index下。
因为咱主要目的是研究分类,不是分词,就不要去搞分词的训练了,如果想训练可以看我的另外一篇博客:CRF++中文分词指南 。
nlpbamboo安装的几个要点
2、编译完nlpbamboo后执行下/opt/bamboo/bin/bamboo看看bamboo是否安装成功
如果提示ERROR: libcrfpp.so.0: cannot open shared object file: No such file or directory需要执行以下操作
ln -s /usr/local/lib/libcrfpp.so.* /usr/lib/
ldconfig
3、安装PHP扩展后下载index.tar.bz2这个模型,然后在php.ini中添加
bamboo.parsers = crf_seg
因为官方的 index.tar.bz2 中只包含 crf_seg 的 model,所以不加 crf_pos 那些;否则php将无法
可以试试:/opt/bamboo/bin/bamboo -p crf_seg filename,如果成功证明装好了。
稍微注意以下,搜狗的词库是gb2312的,所以,请转为utf8,再分词,这是python写的函数:输入一个文件名,转为utf8,再分词,分词文件以.seg为后缀。
- def seg(fn):
- if not os.path.isfile(fn+'.utf8'):
- cmd = 'iconv -f gb2312 -t utf8 -c %s > %s.utf8' %(fn,fn)
- print cmd
- os.system(cmd)
- cmd = '/opt/bamboo/bin/bamboo -p crf_seg %s.utf8 > %s.seg' % (fn,fn)
- print cmd
- os.system(cmd)
分词结果如下:
一 家 刚刚 成立 两 年 的 网络 支付 公司 , 它 的 目标 是 成为 市值 100亿 美元 的 上市 公司 。
这家 公司 叫做 快 钱 , 说 这 句 话 的 是 快钱 的 CEO 关 国光 。 他 之前 曾 任 网易 的 高级 副 总裁 , 负责 过 网易 的 上市 工作 。 对于 为什么 选择 第三 方 支付 作为 创业 方向 , 他 曾经 对 媒体 这样 说 : “ 我 能 看到 这个 胡同 对面 是 什么 , 别人 只能 看到 这个 胡同 。 ” 自信 与 狂妄 只 有 一 步 之 遥 ―― 这 几乎 是 所有 创业者 的 共同 特征 , 是 自信 还是 狂妄 也许 需要 留待 时间 来 考证 。
3.特征提取
svm不是在高维模式识别具有优势吗,咋还要特征提取呢,把所有词都当成特征不就行了吗?对于词库来说,十几万的词是很常见的,把对类别区分度(GDP,CPI,股票对经济类的区分度就高,其他一些高频词,如我们,大家,一起等就没有区分度)高的词挑选出来,一来可以减少计算量,二来应该是可以提高分类效果。
据说,开方检验(CHI)信息增益(IG)对于挑选特征好,我选择的是CHI。两者的概念,请google。
首先统计词在文档中的次数
- #ingore some term
- def ingore(s):
- return s == 'nbsp' or s == ' ' or s == ' ' or s == '/t' or s == '/n' /
- or s == ',' or s == '。' or s == '!' or s == '、' or s == '―'/
- or s == '?' or s == '@' or s == ':' /
- or s == '#' or s == '%' or s == '&' /
- or s == '(' or s == ')' or s == '《' or s == '》' /
- or s == '[' or s == ']' or s == '{' or s == '}' /
- or s == '*' or s == ',' or s == '.' or s == '&' /
- or s == '!' or s == '?' or s == ':' or s == ';'/
- or s == '-' or s == '&'/
- or s == '<' or s == '>' or s == '(' or s == ')' /
- or s == '[' or s == ']' or s == '{' or s == '}'
- #term times
- def getterm(fn):
- fnobj = open(fn,'r')
- data = fnobj.read()
- fnobj.close()
- arr = data.split(' ')
- docterm = dict()
- for a in arr:
- a = a.strip(' /n/t')
- :
- times = docterm.get(a)
- if times:
- else:
- return docte
- #cls_term:cls,term,artcount
- #term_cls:term,cls,artcount
- def stat(cls,fn,cls_term,term_cls):
- docterm = getterm(fn)
- termdi = cls_term.get(cls)
- if not termdi:
- termdi = dict()
- cls_term[cls] = termdi
- #term,times
- for t in docterm.iterkeys():
- artcount = termdi.get(t)
- if not artcount:
- clsdi = term_cls.get(t)
- if not clsdi:
- clsdi = {}
- term_cls[k] = clsdi
- artcount = clsdi.get(cls)
- if not artcount:
分别计算每个词的a/b/c/d
a:在这个分类下包含这个词的文档数量
b:不在该分类下包含这个词的文档数量
c:在这个分类下不包含这个词的文档数量
d:不在该分类下,且不包含这个词的文档数量
因为前面统计了每个类下,每个词,文章数和每个词,每个类,文章数。所以很容易得到a,b,c,d的值。
z1 = a*d - b*c
x2 = (z1 * z1 * float(N)) /( (a+c)*(a+b)*(b+d)*(c+d) )
计算之后,排序,并取出前1000个词(这里指的每个类别的特征词)。
li = sorted(termchi.iteritems(), key=lambda d:d[1], reverse = True)
循环每个分类,并把每个类别的特征合并(合并成一个文件,作为特征词典),合并后存为feature文件,第一列是序号,第二列是对应的词,序号就是特征号。
1 逐项
2 深市
3 九寨沟
4 岛内
5 期望
6 第20分钟
7 合理
8 谢杏芳
9 赛迪
10 ***
注:特征选择的目的就是选择在该类下,不在其他类下的特征,但是重复是避免不了的,合并的文件肯定是排重过的。先选择每个类下的1000个词,假如10个类,则共选择10 * 1000个词,然后去重,并生成特征的唯一id。
4.训练和测试样本组织
搜狐语料的1990篇中的1890作为训练集,100篇作为测试集,分别形成train和test文件,libsvm的训练集的格式为:
lable1 index1:featureValue1 index2:featureValue2 index3:featureValue3 ...
lable2 index1:featureValue1 index2:featureValue2 index3:featureValue3 ...
对应到文本分类上就是:类别ID 特征序号(第3步计算的特征序号):特征值(TFIDF值)......
如,我摘了一行,这是一篇文章的例子,8就是类别ID,189是特征“189 指导"的序号,0.171153是特征值:
8 189:0.171153 253:0.081381 298:0.630345 504:0.135512 562:79.423503 578:0.072219 698:0.078896 710:0.036074 740:0.215368 868:0.263524 1336:0.114355 1365:0.076494 1372:0.085780 1555:0.572497 1563:3.932806 1598:0.114717 1685:0.129870 1972:0.193693 2282:0.061828
2865:0.026699 2897:0.099020 3040:0.039621 3041:0.258073 3191:0.091276 3377:0.125544 3454:0.062189 3623:0.139698 3653:0.128304 3932:2.990233 4353:0.202133 4394:0.312992 4420:0.356354 4424:0.482424 4522:0.447795 4675:3.618182 4767:0.065334 4848:0.270417 4875:0.213588
4941:0.407453 5004:0.070447 5125:0.717893 5214:3.222299 5250:0.052897 5251:0.281352 5310:2.010101 5357:0.203956 5474:0.034037 5504:0.193900 5861:0.859426 6120:1.320504 6129:0.107941 6364:0.184225 6373:0.287843 6379:0.080727 6385:0.712241 6847:0.209023 7007:0.147802
7121:1.320504 7547:0.248161 7636:0.108981
采用TFIDF的算法,数据处理和特征选择类似,计算每个类,每篇文档,每个词的次数,以包含这个词的文档数。每篇文章的每个特征项,用TF/DF的值作为特征值。(后记:用TF * IDF,然后用svm-scale缩放到0,1之间,效果比TF/DF要好,准确率能达到82%。,计算方式如下:
tf = float(times) / total
idf = math.log( N / float(term_count[term]) )
term_times[term] = tf * idf
)
- #doc_term: class doc term times
- #term_doc: term doccount
- def tfidf(doc_term,term_doc):
- print 'begin compute tf * idf'
- for cls,docdi in doc_term.iteritems():
- for doc,termdi in docdi.iteritems():
- for term,times in termdi.iteritems():
- total += times
- for term,times in termdi.iteritems():
- tf = float(times) / total
- df = float(term_doc[term]) / N
- termdi[term] = tf / df
注意:用CHI是提取类别的特征词,而这里用TFIDF是计算文档的特征向量,前者是要体现类别的区分度,后者要体现文档的区分度,两者概念和所做的事情不一样,所以采用的方法也不一样。
5.用libsvm训练
你看,忙活了半天,还没有到libsvm呢,其实前面几步很麻烦的,libsvm的资料不少,但是都是一个几行数据的简单例子,这不具有实际应用的价值,只有把样本,分词,特征提取/特征计算搞定了,分类才能做好。
下载libsvm:http://www.csie.ntu.edu.tw/~cjlin/cgi-bin/libsvm.cgi?+http://www.csie.ntu.edu.tw/~cjlin/libsvm+zip
解压,make
svm-scale:特征缩放的工具 svm-train:训练工具 svm-predict:测试工具
toos/grid.py:寻找参数的工具
用默认参数试试:
./svm-train train.s model.s
./svm-predict test.s model.s result.s
结果
Accuracy = 74.3889% (1339/1800) (classification)
不算太理想,也不算太差。如果只是2个类,结果能到95%。我想可以从如下几个方面改进:
- 增加分词的样本数,训练更好的分词模型。
- 特征提取后,用人工进行调整,因为很多词对于类别区分度不高。
- 用grid.py寻找合适的参数。
参考资料:
jasper的博客,SVM理论的学习资料:http://www.blogjava.net/zhenandaci/category/31868.html
通俗易懂,要好好读读。
libsvm的官方网站:http://www.csie.ntu.edu.tw/~cjlin/libsvm/
看了理论性的东西,最好实践以下,libsvm就是很好的实践工具。
Vapnik的两本书,我买了第二本,发现公式太多,好晦涩。准备买第一本,据说第一本比较浅显易懂一些
《统计学习理论的本质》
http://product.dangdang.com/product.aspx?product_id=20602023&ref=search-0-A
《统计学习理论》
http://product.dangdang.com/product.aspx?product_id=20529098&ref=search-0-A
基于SVMLight的文本分类的更多相关文章
- tensorflow实现基于LSTM的文本分类方法
tensorflow实现基于LSTM的文本分类方法 作者:u010223750 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实 ...
- 一文详解如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)
雷锋网按:本文作者陆池,原文载于作者个人博客,雷锋网已获授权. 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实例,这个星期就用 ...
- 基于weka的文本分类实现
weka介绍 参见 1)百度百科:http://baike.baidu.com/link?url=V9GKiFxiAoFkaUvPULJ7gK_xoEDnSfUNR1woed0YTmo20Wjo0wY ...
- 基于tensorflow的文本分类总结(数据集是复旦中文语料)
代码已上传到github:https://github.com/taishan1994/tensorflow-text-classification 往期精彩: 利用TfidfVectorizer进行 ...
- Python 基于 NLP 的文本分类
这是前一段时间在做的事情,有些python库需要python3.5以上,所以mac请先升级 brew安装以下就好,然后Preference(comm+',')->Project: Text-Cl ...
- NLP第9章 NLP 中用到的机器学习算法——基于统计学(文本分类和文本聚类)
- 基于Text-CNN模型的中文文本分类实战 流川枫 发表于AI星球订阅
Text-CNN 1.文本分类 转眼学生生涯就结束了,在家待就业期间正好有一段空闲期,可以对曾经感兴趣的一些知识点进行总结. 本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个基于T ...
- 基于Text-CNN模型的中文文本分类实战
Text-CNN 1.文本分类 转眼学生生涯就结束了,在家待就业期间正好有一段空闲期,可以对曾经感兴趣的一些知识点进行总结. 本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个基于T ...
- 使用libsvm实现文本分类
@Hcy(黄灿奕) 文本分类,首先它是分类问题,应该对应着分类过程的两个重要的步骤,一个是使用训练数据集训练分类器,另一个就是使用测试数据集来评价分类器的分类精度.然而,作为文本分类,它还具有文本这样 ...
随机推荐
- 给定一个数列a1,a2,a3,...,an和m个三元组表示的查询,对于每个查询(i,j,k),输出ai,ai+1,...,aj的升序排列中第k个数。
给定一个数列a1,a2,a3,...,an和m个三元组表示的查询,对于每个查询(i,j,k),输出ai,ai+1,...,aj的升序排列中第k个数. #include <iostream> ...
- 侧滑面板(对viewGroup的自定义)
额,好吧,最近一直在做侧滑的事情,到目前为止一共是学了三种方法了,一个是直接加第三方开源框架SlidingMenu,第二给是用DrawerLayout,今天这个是用谷歌官方提供的在新的support- ...
- 学习TensorFlow,打印输出tensor的值
在学习TensorFlow的过程中,我们需要知道某个tensor的值是什么,这个很重要,尤其是在debug的时候.也许你会说,这个很容易啊,直接print就可以了.其实不然,print只能打印输出sh ...
- POI操作excel中的日期格式处理
转载:http://blog.csdn.net/fuxiaohui/article/details/6239925 7.3.3 POI中Excel文件Cell的类型 在读取每一个Cell的值的时候,通 ...
- 基于V4L2摄像头采集图片程序设计
#ifndef __COMMON_H #define __COMMON_H //该头文件定义的是摄像头在屏幕上显示的宽度和高度 #include<stdio.h> #include< ...
- Sql Server服务远程过程调用失败
由于开发系统,需要vs版本统一,于是经过了昨天一整天艰苦卓绝的斗争,小编终于成功的写在了13版本的vs,重新装上了12版本的vs,本来想着,12版本的vs搭建成功了,就赶快搭建框架,然后敲例子,可是天 ...
- Eclipse 主题
Eclipse开发环境默认都是白底黑字的,看到同事的Xcode中设置的黑灰色背景挺好看的,就去网络上查了一下.发现Eclipse也可以设置主题. http://eclipsecolorthemes.o ...
- >/dev/null 2>&1
>/dev/null 2>&1 大部分在 crontab 计划任务中都会年到未尾带 >/dev/null 2>&1,是什么意思呢? > 是重定向 /dev ...
- 采购申请 POCIRM-001:ORA-01403: 未找到任何数据
今天同事让帮忙看一个问题,在销售模块提交销售订单生成采购订单的请求时报错 查看请求日志 +------------------------------------------------------- ...
- OpenCV Python教程(1、图像的载入、显示和保存)
原文地址:http://blog.csdn.net/sunny2038/article/details/9057415 转载请详细注明原作者及出处,谢谢! 本文是OpenCV 2 Computer ...