下面是设计分类器,用训练集训练,用测试集测试。在做这些工作之前,一定要记住,首先要把测试数据也映射到上面这个TF-IDF词向量空间中,也就是说,测试集和训练集处在同一个词向量空间(vocabulary相同),只不过测试集有自己的tdm,与训练集(train_word_bag/tfdifspace.dat)中的tdm不同而已。
最常见的文本分类方法有KNN最邻近算法、朴素贝叶斯算法和支持向量机算法。一般而言,KNN最邻近算法的原理最简单,分类精度尚可,但是速度最慢;朴素贝叶斯算法对于短文本分类的效果最好,精度很高;支持向量机算法的优势是支持线性不可分的情况,精度上取中。
本文选用Scikit-Learn的朴素贝叶斯算法进行文本分类,测试集随机抽取自训练集中的文档集合,每个分类取10个文档,过滤掉1KB以下的文档。分类器有封装好了的函数,MultinomialNB,获取训练集的权重矩阵和标签,进行训练,然后获取测试集的权重矩阵,进行预测(给出预测标签)。 训练步骤与训练集相同,首先是分词,之后生成文件词向量文件,直至生成词向量模型。不同的是,在训练词向量模型时,需要加载训练集词袋,将测试集产生的词向量映射到训练集词袋的词典中,生成向量空间模型。 首先,把测试数据也映射到TF-IDF词向量空间上:import sysimport osfrom sklearn.datasets.base import Bunch #引入Bunch类import cPickle as pickle #引入持久化类from sklearn import feature_extractionfrom sklearn.feature_extraction.text import TfidfTransformer #向量转换类from sklearn.feature_extraction.text import TfidfVectorizer #向量生成类#配置UTF-8输出环境reload(sys)sys.setdefaultencoding('utf-8')#读取Bunch对象def readbunchobj(path): file_obj=open(path,"rb") bunch=pickle.load(file_obj) file_obj.close() return bunch#写入Bunch对象def writebunchobj(path,bunchobj): file_obj=open(path,"wb") pickle.dump(bunchobj,file_obj) file_obj.close() #读取文件#1读取停用词表stopword_path="train_word_bag/hlt_stop_words.txt"#停用词表的路径stpwrdlst=readfile(stopword_path).splitlines()#2导入分词后的词向量Bunch对象path="test_word_bag/test_set.dat" #词向量空间保存路径bunch=readbunchobj(path)#3构建测试集TF-IDF词向量空间对象testspace=Bunch(target_name=bunch.target_name,label=bunch.label,filenames=bunch.filenames,tdm=[],vocabulary={})#导入训练集的词袋trainbunch=readbunchobj("train_word_bag/tfdifspace.dat")#使用Tfidfvectorizer初始化向量空间模型vectorizer=TfidfVectorizer(stop_words=stpwrdlst,sublinear_tf=True,max_df=0.5,vocabulary=trainbunch.vocabulary) #使用训练集词袋向量transformer=TfidfTransformer()#文本转换为词频矩阵,单独保存字典文件testspace.tdm=vectorizer.fit_transform(bunch.contents)testspace.vocabulary=trainbunch.vocabulary#创建词袋的持久化space_path="test_word_bag/testspace.dat" #词向量词袋保存路径writebunchobj(space_path,testspace)
测试集进行了上述处理后,接下来执行多项式贝叶斯算法进行测试文本分类,并返回分类精度。
#导入多项式贝叶斯算法包import sys import cPickle as pickle from sklearn.naive_bayes import MultinomialNBreload(sys) sys.setdefaultencoding('utf-8') def readbunchobj(path): file_obj=open(path,"rb") bunch=pickle.load(file_obj) file_obj.close() return bunch #导入训练集向量空间trainpath="train_word_bag/tfdifspace.dat"train_set=readbunchobj(trainpath)#导入测试集向量空间testpath="test_word_bag/testspace.dat"test_set=readbunchobj(testpath)#应用朴素贝叶斯算法。训练分类器:输入词袋向量和分类标签#alpha:0.001,越小,迭代次数越多,精度越高clf = MultinomialNB(alpha=0.001).fit(train_set.tdm, train_set.label) #预测分类结果predicted = clf.predict(test_set.tdm)total=len(predicted);rate=0for flabel,file_name,expct_cate in zip(test_set.label,test_set.filenames,predicted): if flabel != expct_cate: rate+=1 print file_name,": 实际类别:",flabel," -->预测类别:",expct_cate print "error rate:",float(rate)*100/float(total),"%"