目录
一、关于TF-IDF介绍
重要思想:
如果某个词在某篇文档中出现的频率TF高,并且在其他文本中很少出现,则认为,此词有很好的的类别区分能力,适合用来分类;
重要说明:TF-IDF矩阵
TF(Term Frequency):词项频率,即词频,每个词在文本中出现的次数;
IDF(Inverse Document Frequency):逆文档频率,文本总数除以出现某词的文本数;
TF-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()
三、使用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()
计算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()
计算余弦相似度
#计算余弦相似度
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)
余弦相似度前三个值分别为: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)
计算余弦相似度
#计算余弦相似度
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)
由Sklearn构建的TF-IDF矩阵,矩阵中的每个词条构成矩阵的行,因为分词的方式不同,而且去掉了标点符号,所以词袋中只有609个词项。对于像上面的构建方式,Sklrean预优化的TF-IDF模型为我们省去了大量的工作,但是上面的第一种方法是构建TF-IDF矩阵的基本运行理论,基于TF-IDF矩阵,可以进行一些其它有趣的分析,比如主题向量分析,语义分析等工作。
五、构建TD-IDF矩阵总结
通过计算TF词项频率和IDF逆文档频率,我们实现了由文字处理到数学计算的转变;
TF词项频率和IDF逆文档频率计算公式
注:IDF=词袋中的文档数除以包含某词的文档数,通常使用lg函数对IDF进行放缩处理。
余弦相似度计算公式:
TF-IDF矩阵是自然语言处理(NLP)的入门思想方法,本文通过DataFrame的方式构建TF-IDF矩阵希望能给到大家一些启发,掌握构建TF-IDF的基本构建过程。初步接触自然语言处理,有很多不足之处,望各位大神多多指教。
文章使用资料已放至我的网盘,提取:TFID。关于线性代数基础知识向大家推荐之前的文章三个通宵万字写的 线代的基础知识(一),自己总结的同时,希望能帮助到大家,共同进步。