基于TFIDF实现文本分类,并比较词集模型与词袋模型的分类效果

【方法原理】

TF-IDF是一种统计方法,用以评估某一字词对于一个文件集或一个语料库的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。
TF-IDF的主要思想是,如果某个词或短语在一篇文章中出现的频率TF(Term Frequency,词频),词频高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF实际上是:TF * IDF。TF表示词条在文档d中出现的频率。IDF(inverse document frequency,逆向文件频率)的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其他类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其他类文档。

文本特征提取有两个非常重要的模型:词集模型:单词构成的集合,集合自然每个元素都只有一个,也即词集中的每个单词都只有一个。词袋模型:在词集的基础上如果一个单词在文档中出现不止一次,统计其出现的次数(频数)。
两者本质上的区别,词袋是在词集的基础上增加了频率的维度,词集只关注有和没有,词袋还要关注有几个。
在使用词集模型时只需将词袋模型的词频矩阵转化为01矩阵,可使用np.int64(arr>0)。

【结果】

在这里插入图片描述

【代码】

import nltk
from nltk.corpus import movie_reviews
from pylab import plot,show
from numpy import array
from numpy.random import rand
from scipy.cluster.vq import kmeans,vq,whiten
import numpy as np
import random
import collections

documents = [(' '.join(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]
#转化为词列表的影评,与标签,组成二元组
random.shuffle(documents)	
documents_words=[w for (w,t) in documents]

'''基于SKLearn的TFIDF实现'''
from sklearn import feature_extraction  
from sklearn.feature_extraction.text import TfidfTransformer  
from sklearn.feature_extraction.text import CountVectorizer  

'''TFIDF'''
vectorizer=CountVectorizer(min_df=100,stop_words='english')#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频  
transformer=TfidfTransformer()#该类会统计每个词语的tf-idf权值
tfidf=transformer.fit_transform(vectorizer.fit_transform(documents_words))#fit_transform计算tf-idf,fit_transform将文本转为词频矩阵  
word=vectorizer.get_feature_names()#获取词袋模型中的所有词语  
features=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
'''词袋模型'''
bag_of_word=features
'''词集模型'''
set_of_word=np.int64(features>0)#将词频矩阵转化为01矩阵

target=[c for (d,c) in documents]
train_set1=bag_of_word[:1500,:]
train_set2=set_of_word[:1500,:]
target_train=target[:1500]
test_set1=bag_of_word[1500:,:]#切片操作,第一维取1500往后所有,第二维取所有
test_set2=set_of_word[1500:,:]
target_test=target[1500:]

print('【使用词袋模型】')
from sklearn.svm import SVC
svclf = SVC(kernel ='linear',probability=True)
svclf.fit(train_set1, target_train)  
pred_svc = svclf.predict(test_set1)
print('SVM=',sum(pred_svc==target_test)/len(target_test))

from bio import kNN
from scipy import spatial
model = kNN.train(train_set1, target_train, 7)
dd=[kNN.classify(model, t, distance_fn=spatial.distance.cosine) for t in test_set1]
print('KNN_cos=',sum(np.array(dd)==np.array(target_test))/len(target_test))

from sklearn.neighbors import KNeighborsClassifier
knnclf = KNeighborsClassifier(n_neighbors=7)#default with k=5  
knnclf.fit(train_set1, target_train)  
pred_knn = knnclf.predict(test_set1);
print('KNN_eu=',sum(pred_knn==target_test)/len(target_test))

print('【使用词集模型】')
svclf.fit(train_set2, target_train)  
pred_svc2 = svclf.predict(test_set2)
print('SVM=',sum(pred_svc2==target_test)/len(target_test))

model2 = kNN.train(train_set2, target_train, 7)
dd2=[kNN.classify(model2, t, distance_fn=spatial.distance.cosine) for t in test_set2]
print('KNN_cos=',sum(np.array(dd2)==np.array(target_test))/len(target_test))

knnclf.fit(train_set2, target_train)  
pred_knn2 = knnclf.predict(test_set2);
print('KNN_eu=',sum(pred_knn2==target_test)/len(target_test))
发布了54 篇原创文章 · 获赞 26 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43629813/article/details/103846646