赞
踩
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)。
TF-IDF的原始公式为:
公式中各个变量的含义在此不再赘述,与网上的TF-IDF公式一致。但是第二个公式由于分母可能为0,因此此次我们采用平滑处理后的TF-IDF公式:
作为源码实现所依据的公式。
# TF_IDF_weight函数功能:传入corpus,返回其特征向量值向量 # 输入的corpus格式:["我 来到 中国 旅游", "中国 欢迎 你","我 喜欢 来到 中国 天安门"] def TF_IDF_weight(corpus): # 词库的构建 import math weight_long = [eve.split() for eve in corpus] word_all = [] for eve in weight_long: for x in eve: if len(x)>1: word_all.append(x) word_all = list(set(word_all)) # 集合去重词库 # 开始计算tf-idf weight = [[] for i in corpus] weight_idf = [[] for i in corpus] for word in word_all: for i in range(len(corpus)): temp_list = corpus[i].split() n1 = temp_list.count(word) n2 = len(temp_list) tf = n1/n2 n3 = len(corpus) n4 = 0 for eve in corpus: temp_list_ = eve.split() if word in temp_list_: n4 += 1 idf = math.log(((n3+1)/(n4+1))+1,10) weight_idf[i].append(idf) weight[i].append(tf*idf) # L2范式归一化过程 l2_weight = [[] for i in range(len(corpus))] for e in range(len(weight)): all2plus = 0 for ev in weight[e]: all2plus += ev**2 for ev in weight[e]: l2_weight[e].append(ev/(all2plus**0.5)) return l2_weight # 返回最终结果
对源码的几点说明:
a.在构建词库的过程中,词的前后顺序没有要求,但是词语不能有重复。
b.在得到tf-idf计算结果之后,需要对其进行归一化操作,才能为分类等后续操作使用。
c.在此处将长度小于1的词语去掉了,如“我”,“你”。
使用分完词的汉语语料corpus,传入上面的函数TF_IDF_weight中:
corpus = ["我 来到 中国 旅游", "中国 欢迎 你","我 喜欢 来到 中国 天安门"]
result_list = TF_IDF_weight(corpus)
for weight in result_list:
print(weight)
输出结果:
[0.0, 0.44692991362032153, 0.5463237392780342, 0.7083671535387552, 0.0, 0.0]
[0.8457366985068379, 0.5336004467752572, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.3646999329959496, 0.44580643415615906, 0.0, 0.5780357178140985, 0.5780357178140985]
使用同样的语料数据,调用sklearn下的方法求TF-IDF:
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer() # 实例化
transformer = TfidfTransformer()
corpus = ["我 来到 中国 旅游", "中国 欢迎 你","我 喜欢 来到 中国 天安门"]
result_list2 = transformer.fit_transform(vectorizer.fit_transform(corpus)).toarray().tolist()
for weight in result_list2:
print(weight)
输出结果:
[0.4254405389711991, 0.0, 0.0, 0.7203334490549893, 0.5478321549274363, 0.0]
[0.5085423203783267, 0.0, 0.0, 0.0, 0.0, 0.8610369959439764]
[0.34520501686496574, 0.5844829010200651, 0.5844829010200651, 0.0, 0.444514311537431, 0.0]
对于同一个语料数据corpus而言,现在按照第一句话 “我 来到 中国 旅游” 对比两种方法得到的向量值。
词语 | 自实现的TF-IDF | sklearn中的TF-IDF |
---|---|---|
我 | 去掉 | 去掉 |
来到 | 0.5463237392780342 | 0.5478321549274363 |
中国 | 0.44692991362032153 | 0.4254405389711991 |
旅游 | 0.7083671535387552 | 0.7203334490549893 |
可以看到二者得到的向量值非常类似,但是不完全一致。除了这一点以外,sklearn中的TF-IDF方法运行速度较快。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。