TF-IDF(Term Frequency-InversDocument Frequency)是一种常用于信息处理和数据挖掘的加权技术。
该技术采用一种统计方法,根据字词的在文本中出现的次数和在整个语料中出现的文档频率来计算一个字词在整个语料中的重要程度。
它的优点是能过滤掉一些常见的却无关紧要本的词语,同时保留影响整个文本的重要字词。
TF(Term Frequency)表示某个关键词在整篇文章中出现的频率。
IDF(InversDocument Frequency)表示计算倒文本频率。
文本频率是指某个关键词在整个语料所有文章中出现的次数。
倒文档频率又称为逆文档频率,它是文档频率的倒数,主要用于降低所有文档中一些常见却对文档影响不大的词语的作用。
步骤:
(1)计算词频
TF = 某个词在文档出现的次数 / 文档的总词数
(2)计算逆文档频率
IDF = lg( 语料库的文档总数 / 包含该词的文档数+1 )
(3)计算TF-IDF
TF-IDF = TF * IDF
ID | 训练文档 |
---|---|
1 | iphone guuci huawei watch huawei |
2 | huawei watch iphone watch iphone guuci |
3 | xiaomi xiaomi xiaomi flower |
4 | watch watch huawei |
测试数据:iphone guuci huawei watch xiaomi flower
sklearn中实现
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
def sklearn_tfidf():
tag_list = ['iphone guuci huawei watch huawei',
'huawei watch iphone watch iphone guuci',
'xiaomi xiaomi xiaomi flower',
'watch watch huawei']
test = ['iphone iphone guuci xiaomi watch']
vect = CountVectorizer() #将文本中的词语转换为词频矩阵
X = vect.fit_transform(tag_list) #计算每个词语出现的次数
X_test = vect.transform(test)
print("文章生成的词典:",vect.get_feature_names())
print("每个词语出现的次数:",X)
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X) #将词频矩阵X统计成TF-IDF值
print('训练集的TFIDF:',tfidf.toarray())
#计算测试文档的TF-IDF值时,用的是训练集的IDF值
print('测试集的TF-IDF:',transformer.transform(X_test).toarray())
sklearn_tfidf()
结果
文章生成的词典: ['flower', 'guuci', 'huawei', 'iphone', 'watch', 'xiaomi']
每个词语出现的次数: (0, 3) 1
(0, 1) 1
(0, 2) 2
(0, 4) 1
(1, 3) 2
(1, 1) 1
(1, 2) 1
(1, 4) 2
(2, 5) 3
(2, 0) 1
(3, 2) 1
(3, 4) 2
训练集的TFIDF: [[0. 0.43531168 0.70484465 0.43531168 0.35242232 0. ]
[0. 0.34758387 0.2813991 0.69516774 0.5627982 0. ]
[0.31622777 0. 0. 0. 0. 0.9486833 ]
[0. 0. 0.4472136 0. 0.89442719 0. ]]
测试集的TF-IDF: [[0. 0.37102749 0. 0.74205499 0.30037873 0.47060133]]
下面手动实现以下TF-IDF值
拿训练文档中第一条文档为例,即:iphone guuci huawei watch huawei
中每个词在所有文档中的TF-IDF的值
[0. 0.43531168 0.70484465 0.43531168 0.35242232 0. ]
这条结果的意识是:
第一条文档中的单词 | 在所有文档中的TF-IDF |
---|---|
flower | 0 |
guuci | 0.43531168 |
huawei | 0.70484465 |
iphone | 0.43531168 |
watch | 0.35242232 |
xiaomi | 0 |
flower与xiaomi因为没有在第一条文档中出现过,所以TF值为0
'''
人肉实现 TF-IDF
CF:文档集的频率,是指词在文档集中出现的次数
DF:文档频率,是指出现词的文档数
TF:词在文档中的频率
IDF:逆文档频率,idf = lg(N/(1+df)),N为所有文档的数目,为了兼容df=0情况,将分母弄成1+df。
TF-IDF:TF-IDF= TF*IDF
'''
import numpy as np
def tfidf_alg():
docs = np.array(['iphone guuci huawei watch huawei',
'huawei watch iphone watch iphone guuci',
'xiaomi xiaomi xiaomi flower',
'watch watch huawei'])
words = np.array(['iphone', 'guuci', 'huawei', 'watch', 'xiaomi', 'flower'])
#计算words中每个词在文档中出现的个数
cfs = []
for e in docs:
cf = [e.count(word) for word in words]
cfs.append(cf)
#计算words中每个词在文档中的频率
tfs = []
for e in cfs:
tf = e/(np.sum(e))
tfs.append(tf)
#包含words中每个词的文档个数
dfs = list(np.zeros(words.size, dtype=int))
for i in range(words.size):
for doc in docs:
if doc.find(words[i]) != -1:
dfs[i] += 1
#计算每个词的idf(逆向文件频率inverse document frequency)
#lg(N/(1+DF))
N = np.shape(docs)[0]
idfs = [( np.log10(N*1.0/(1+e) ) ) for e in dfs]
#计算TF-IDF(term frequency - inverse document frequency)
tfidfs = []
for i in range(np.shape(docs)[0]):
word_tfidf = np.multiply(tfs[i], idfs)
tfidfs.append(word_tfidf)
#print('word_tfidf:',word_tfidf)
print('\ndocs:\n', np.array(docs))
print('\nwords:\n', np.array(words))
print('\nCF:\n', np.array(cfs))
print('\nTF:\n', np.array(tfs))
print('\nDF:\n', np.array(dfs))
print('\nIDF:\n', np.array(idfs))
print('\nTF-IDF:\n', np.array(tfidfs))
tfidf_alg()