【Sklearn】 基于Sklearn-TfidfVectorizer文本分类

目录

一、关于TF-IDF介绍

二、构建词袋(Words of bag)

三、使用DataFrame构建TF-IDF矩阵

四、使用sklearn构建TF-IDF矩阵

五、TD-IDF矩阵总结


 

一、关于TF-IDF介绍

重要思想:
        如果某个词在某篇文档中出现的频率TF高,并且在其他文本中很少出现,则认为,此词有很好的的类别区分能力,适合用来分类;
重要说明:TF-IDF矩阵
        TF(Term Frequency):词项频率,即词频,每个词在文本中出现的次数;
        IDF(Inverse Document Frequency):逆文档频率,文本总数除以出现某词的文本数;

        TF-IDF就是词项频率乘以逆文档频率

eq?TD-IDF%3DTF*IDF

二、构建词袋(Words of bag)

        基于网上的新闻数据,选取了四篇文章,使用jieba分词进行构建TF-IDF矩阵,四篇文章标题如下;

文章一:公安部回应唐山烧烤店打人事件:一定会彻底查清全案

文章二:吴啊萍受审画面曝光,南京玄奘寺涉事住持道歉!中纪委网站最新发声

文章三:“唐山打人”事件,与我们每个人有关,一夜,全网都在为一件事揪心

文章四:吴啊萍身份终于查清,90后女护士,供奉是个人行为无境外势力参与

导入数据,构建词袋(语料库)

with open(r'C:\Users\GDY\Desktop\Study\CNDS\小刀试牛 构建TF-IDF矩阵\doc1.txt',encoding='utf-8') as file:
    doc1=file.read().rstrip()
#     print(doc1)     ##rstrip()删除字符串末尾的空   
with open(r'C:\Users\GDY\Desktop\Study\CNDS\小刀试牛 构建TF-IDF矩阵\doc2.txt',encoding='utf-8') as file:
    doc2=file.read().rstrip()
#     print(doc2)     ##rstrip()删除字符串末尾的空 
with open(r'C:\Users\GDY\Desktop\Study\CNDS\小刀试牛 构建TF-IDF矩阵\doc3.txt',encoding='utf-8') as file:
    doc3=file.read().rstrip()
#     print(doc3)     ##rstrip()删除字符串末尾的空 
with open(r'C:\Users\GDY\Desktop\Study\CNDS\小刀试牛 构建TF-IDF矩阵\doc4.txt',encoding='utf-8') as file:
    doc4=file.read().rstrip()
#     print(doc3)     ##rstrip()删除字符串末尾的空 
doc_tokens=[]
docs=[doc1,doc2,doc3,doc4]
for doc in docs:
    doc_tokens+=[sorted(jieba.cut(doc,cut_all=False))]
all_doc_tokens=sum(doc_tokens,[])
lexicon=sorted(set(all_doc_tokens))
#删除换行符
lexicon.remove('\n')
df=pd.DataFrame(lexicon,columns=['words_of_bag'])
df['vec']=0
df.head()

57747edd70a546d4a8d995bda220c0cf.png

 

三、使用DataFrame构建TF-IDF矩阵

计算TF词项频率

doc_vector=[]
i=1
for doc in docs:
    doc_tokens=sorted(jieba.cut(doc,cut_all=False))
    doc_tokens.remove('\n')
    column_name='doc'+str(i)
    vec_name='TF'+str(i)
    df_tokens=pd.DataFrame(doc_tokens,columns=[column_name])
    df_tokens=df_tokens.groupby(column_name).agg({column_name:'count'})
    df_tokens.rename(columns={column_name:vec_name},inplace=True)
    df_tokens=df_tokens.reset_index()
    df_tokens.rename(columns={column_name:'words_of_bag'},inplace=True)
    df=pd.merge(df,df_tokens,how='left',on='words_of_bag')
    i+=1
#     print(df_tokens.head())
#     vec=copy.copy
df=df.fillna(0)
df.head()

99965bd708584c5ebbc812ea819ab6ff.png

 计算IDF:逆文档频率

#计算包含词的文档数
doc_counts=[]
for i in range(df.shape[0]):
    doc_counts.append(df.iloc[:,2:].T.iloc[:,i][df.iloc[:,2:].T.iloc[:,i]!=0].count())
df['doc_counts']=doc_counts
#使用lg函数对词频进行尺度放缩处理
df['TF-IDF1']=np.log10(3/df['doc_counts'])*df['TF1']
df['TF-IDF2']=np.log10(3/df['doc_counts'])*df['TF2']
df['TF-IDF3']=np.log10(3/df['doc_counts'])*df['TF3']
df['TF-IDF4']=np.log10(3/df['doc_counts'])*df['TF4']
df.head()

4854d190b873452cb90fa0ea0c507810.png

计算余弦相似度

 

#计算余弦相似度
TF_IDF1=np.array(df['TF-IDF1'])
TF_IDF2=np.array(df['TF-IDF2'])
TF_IDF3=np.array(df['TF-IDF3'])
TF_IDF4=np.array(df['TF-IDF4'])

cos_sim12=round(np.dot(TF_IDF1,TF_IDF2)/np.linalg.norm(TF_IDF1)*np.linalg.norm(TF_IDF2),4)
cos_sim13=round(np.dot(TF_IDF1,TF_IDF3)/np.linalg.norm(TF_IDF1)*np.linalg.norm(TF_IDF3),4)
cos_sim14=round(np.dot(TF_IDF1,TF_IDF4)/np.linalg.norm(TF_IDF1)*np.linalg.norm(TF_IDF4),4)
cos_sim23=round(np.dot(TF_IDF2,TF_IDF3)/np.linalg.norm(TF_IDF2)*np.linalg.norm(TF_IDF3),4)
cos_sim24=round(np.dot(TF_IDF2,TF_IDF4)/np.linalg.norm(TF_IDF2)*np.linalg.norm(TF_IDF4),4)
cos_sim34=round(np.dot(TF_IDF3,TF_IDF4)/np.linalg.norm(TF_IDF3)*np.linalg.norm(TF_IDF4),4)

print(cos_sim12,cos_sim13,cos_sim14,cos_sim23,cos_sim24,cos_sim34)

52111cb42bd541d39eb9117c5847914c.png

         余弦相似度前三个值分别为:333.5473,443.2086和242.046。分别对应了第一三篇文章,第二三篇文章和第二四篇文章,一三篇文章均为“唐山打人”事件,二三篇文章为“唐山打人”事件和“吴啊萍”事件,二四篇文章为“吴啊萍”事件。

四、使用sklearn构建TF-IDF矩阵

构建TF-IDF矩阵

from sklearn.feature_extraction.text import TfidfVectorizer
corpus=docs
vectorizer=TfidfVectorizer(min_df=1)
model=vectorizer.fit_transform(corpus)
itidf=model.todense().round(4)
print(itidf)

338177fbe1e44c1981f0fa17dd1cac58.png

 

 

计算余弦相似度

#计算余弦相似度
TF_IDF1=itidf[0]
TF_IDF2=itidf[1]
TF_IDF3=itidf[2]
TF_IDF4=itidf[3]

cos_sim12=round(np.dot(TF_IDF1,TF_IDF2)/np.linalg.norm(TF_IDF1)*np.linalg.norm(TF_IDF2),4)
cos_sim13=round(np.dot(TF_IDF1,TF_IDF3)/np.linalg.norm(TF_IDF1)*np.linalg.norm(TF_IDF3),4)
cos_sim14=round(np.dot(TF_IDF1,TF_IDF4)/np.linalg.norm(TF_IDF1)*np.linalg.norm(TF_IDF4),4)
cos_sim23=round(np.dot(TF_IDF2,TF_IDF3)/np.linalg.norm(TF_IDF2)*np.linalg.norm(TF_IDF3),4)
cos_sim24=round(np.dot(TF_IDF2,TF_IDF4)/np.linalg.norm(TF_IDF2)*np.linalg.norm(TF_IDF4),4)
cos_sim34=round(np.dot(TF_IDF3,TF_IDF4)/np.linalg.norm(TF_IDF3)*np.linalg.norm(TF_IDF4),4)

print(cos_sim12,cos_sim13,cos_sim14,cos_sim23,cos_sim24,cos_sim34)

662d77a98ebb4159bf1bbbffcdcf9f63.png

         由Sklearn构建的TF-IDF矩阵,矩阵中的每个词条构成矩阵的行,因为分词的方式不同,而且去掉了标点符号,所以词袋中只有609个词项。对于像上面的构建方式,Sklrean预优化的TF-IDF模型为我们省去了大量的工作,但是上面的第一种方法是构建TF-IDF矩阵的基本运行理论,基于TF-IDF矩阵,可以进行一些其它有趣的分析,比如主题向量分析,语义分析等工作。

五、构建TD-IDF矩阵总结

        通过计算TF词项频率IDF逆文档频率,我们实现了由文字处理到数学计算的转变;

        TF词项频率IDF逆文档频率计算公式

eq?TF%3D%5Cfrac%7Bword%5C_counts%7D%7Btotal%5C_counts%7D

eq?IDF%3D%5Cfrac%7Bdoc%5C_counts%7D%7Bword%5C_counts%7D

        注:IDF=词袋中的文档数除以包含某词的文档数,通常使用lg函数对IDF进行放缩处理。

        余弦相似度计算公式:

        eq?cos%5Ctheta%3D%5Cfrac%7BA%20B%7D%7B%7CA%7C%7CB%7C%7D

        TF-IDF矩阵是自然语言处理(NLP)的入门思想方法,本文通过DataFrame的方式构建TF-IDF矩阵希望能给到大家一些启发,掌握构建TF-IDF的基本构建过程。初步接触自然语言处理,有很多不足之处,望各位大神多多指教。

        文章使用资料已放至我的网盘,提取:TFID。关于线性代数基础知识向大家推荐之前的文章三个通宵万字写的 线代的基础知识(一),自己总结的同时,希望能帮助到大家,共同进步。

 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以通过sklearn中的CountVectorizerTfidfVectorizer来构建One-hot词向量。 首先,使用CountVectorizer来将文本转换为词频向量。代码如下: ```python from sklearn.feature_extraction.text import CountVectorizer corpus = ['This is the first document.', 'This is the second document.', 'And this is the third one.', 'Is this the first document?'] vectorizer = CountVectorizer() X = vectorizer.fit_transform(corpus) print(vectorizer.get_feature_names()) print(X.toarray()) ``` 输出结果如下: ``` ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this'] [[0 1 1 1 0 0 1 0 1] [0 1 0 1 0 1 1 0 1] [1 0 0 1 1 0 1 1 1] [0 1 1 1 0 0 1 0 1]] ``` 其中,vectorizer.get_feature_names()用来获取词汇表,即文本中所有出现过的单词。X.toarray()则是将文本转化为词频向量。 接下来,使用TfidfVectorizer来计算词语的TF-IDF值。代码如下: ```python from sklearn.feature_extraction.text import TfidfVectorizer corpus = ['This is the first document.', 'This is the second document.', 'And this is the third one.', 'Is this the first document?'] vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(corpus) print(vectorizer.get_feature_names()) print(X.toarray()) ``` 输出结果如下: ``` ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this'] [[0. 0.43877674 0.5519395 0.43877674 0. 0. 0.35872874 0. 0.43877674] [0. 0.43877674 0. 0.43877674 0. 0.61221722 0.35872874 0. 0.43877674] [0.51184851 0. 0. 0.26710379 0.51184851 0. 0.26710379 0.51184851 0.26710379] [0. 0.43877674 0.5519395 0.43877674 0. 0. 0.35872874 0. 0.43877674]] ``` 可以看到,TfidfVectorizer计算出的是TF-IDF值,对于常见的单词“this”、“is”、“the”等,它们的TF-IDF值都比较低。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西瓜WiFi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值