基于libsvm的中文文本分类原型支持向量机(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 平台下使用,也便于科研工作者根据自己的需要进行改进(譬如设计使用符合自己特定问题需要的核函数等)。
更多案例到WX 公zhong hao : datadw文本分类,大致分为如下几件事情:样本,分词,特征提取,向量计算,分类训练,测试和调试。
1.样本选择搜狗语料/labs/dl/c.html,下精简版吧,如果实验用用,这足够了,你要下107M的也可以。
当然,你也可以自己找语料,不过麻烦点而已,把各大门户网站的对应频道下的文章都爬下来。
2.分词Bamboo分词,这是基于CRF++的分词模块,既然是研究统计学习,分词也得用基于统计的不是,如果还是用一字典来分词,那就太out啦。
/p/nlpbamboo/wiki/GettingStarted。
安装完毕bamboo,还要下载训练好的模型(这个模型是基于人民日报1月语料)/p/nlpbamboo/downloads/list,下载index.tar.bz2,解压到/opt/bamboo/index下。
因为咱主要目的是研究分类,不是分词,就不要去搞分词的训练了,如果想训练可以看我的另外一篇博客:CRF++中文分词指南。
可以试试:/opt/bamboo/bin/bamboo -p crf_seg filename,如果成功证明装好了。
稍微注意以下,搜狗的词库是gb2312的,所以,请转为utf8,再分词,这是python写的函数:输入一个文件名,转为utf8,再分词,分词文件以.seg为后缀。
[python]view plain copy1.def seg(fn):2.if not os.path.isfile(fn+'.utf8'):3. cmd = 'iconv -f gb2312 -t utf8 -c %s > %s.utf8' %(fn,fn)4.print cmd5. os.system(cmd)6. cmd = '/opt/bamboo/bin/bamboo -p crf_seg %s.utf8 > %s.seg' % (fn,fn)7.print cmd8. os.system(cmd)分词结果如下:一家刚刚成立两年的网络支付公司,它的目标是成为市值100亿美元的上市公司。
这家公司叫做快钱,说这句话的是快钱的CEO 关国光。
他之前曾任网易的高级副总裁,负责过网易的上市工作。
对于为什么选择第三方支付作为创业方向,他曾经对媒体这样说:“ 我能看到这个胡同对面是什么,别人只能看到这个胡同。
” 自信与狂妄只有一步之遥―― 这几乎是所有创业者的共同特征,是自信还是狂妄也许需要留待时间来考证。
3.特征提取svm不是在高维模式识别具有优势吗,咋还要特征提取呢,把所有词都当成特征不就行了吗?对于词库来说,十几万的词是很常见的,把对类别区分度(GDP,CPI,股票对经济类的区分度就高,其他一些高频词,如我们,大家,一起等就没有区分度)高的词挑选出来,一来可以减少计算量,二来应该是可以提高分类效果。
据说,开方检验(CHI)信息增益(IG)对于挑选特征好,我选择的是CHI。
两者的概念,请google。
首先统计词在文档中的次数[python]view plain copy1.#ingore some term2.def ingore(s):3.return s == 'nbsp'or s == ' 'or s == ' 'or s == '/t'or s == '/n' /4.or s == ','or s == '。
'or s == '!'or s == '、'or s == '―'/5.or s == '?'or s == '@'or s == ':' /6.or s == '#'or s == '%'or s == '&' /7.or s == '('or s == ')'or s == '《'or s == '》' /8.or s == '['or s == ']'or s == '{'or s == '}' /9.or s == '*'or s == ','or s == '.'or s == '&' /10.or s == '!'or s == '?'or s == ':'or s == ';'/11.or s == '-'or s == '&'/12.or s == '<'or s == '>'or s == '('or s == ')' /13.or s == '['or s == ']'or s == '{'or s == '}'14.15.#term times16.def getterm(fn):17. fnobj = open(fn,'r')18. data = fnobj.read()19. fnobj.close()20. arr = data.split(' ')21. docterm = dict()22.for a in arr:23. a = a.strip(' /n/t')24.if not ingore(a) and len( a.decode('utf-8')) >=2:25. times = docterm.get(a)26.if times:27. docterm[a] = times + 128.else:29. docterm[a] = 130.return docte31.#cls_term:cls,term,artcount32.#term_cls:term,cls,artcount33.def stat(cls,fn,cls_term,term_cls):34. docterm = getterm(fn)35. termdi = cls_term.get(cls)36.if not termdi:37. termdi = dict()38. cls_term[cls] = termdi39.#term,times40.for t in docterm.iterkeys():41. artcount = termdi.get(t)42.if not artcount:43. artcount = 044. termdi[k] = artcount + 145. clsdi = term_cls.get(t)46.if not clsdi:47. clsdi = {}48. term_cls[k] = clsdi49. artcount = clsdi.get(cls)50.if not artcount:51. artcount = 052. clsdi[cls] = artcount + 1分别计算每个词的a/b/c/da:在这个分类下包含这个词的文档数量b:不在该分类下包含这个词的文档数量c:在这个分类下不包含这个词的文档数量d:不在该分类下,且不包含这个词的文档数量因为前面统计了每个类下,每个词,文章数和每个词,每个类,文章数。
所以很容易得到a,b,c,d的值。
z1 = a*d - b*cx2 = (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.1298701972:0.193693 2282:0.061828 2865:0.026699 2897:0.099020 3040:0.0396213041:0.258073 3191:0.091276 3377:0.125544 3454:0.062189 3623:0.1396983653:0.128304 3932:2.990233 4353:0.202133 4394:0.312992 4420:0.3563544424:0.482424 4522:0.447795 4675:3.618182 4767:0.065334 4848:0.2704174875:0.213588 4941:0.407453 5004:0.070447 5125:0.717893 5214:3.2222995250:0.052897 5251:0.281352 5310:2.010101 5357:0.203956 5474:0.0340375504:0.193900 5861:0.859426 6120:1.320504 6129:0.107941 6364:0.1842256373:0.287843 6379:0.080727 6385:0.712241 6847:0.209023 7007:0.1478027121:1.320504 7547:0.248161 7636:0.108981采用TFIDF的算法,数据处理和特征选择类似,计算每个类,每篇文档,每个词的次数,以包含这个词的文档数。