背景
之前对tfidf处于应用的层级,本博文将从原理和实战上来对其进行阐述。
原理
白话
tfidf的核心思想:
- 一个单词在同
一个文档中
出现的次数越多,说明这个词越重要
- 一个单词出现在
不同的文档中
的次数越多,说明这个词越不重要
tfidf的输入和输出:
- 输入:文档分词
- 输出:词的重要性
举例输入:
文档1:我 爱 技术 人民。
文档2:我 爱 电脑。
文档3:我 爱 加班 的 人民。
重要程度输出:
技术 = 电脑 = 加班 > 人民 > 我 = 爱
数学过程
明确一下概念:
- tf,每篇文档的词频,比如文档1,“我”的词频就是 1 ÷ 4 = 0.25
- df,文档词频,“人民”在三篇文档中都出现了两次,所以df = 2 ÷ 3 = 0.6666
- idf,逆文档词频,“人民” idf = 3 ÷ 2 = 1.5,idf的数据公式里面需要加log, 也就是log (3 ÷ 2) = 0.4054651081081644
tf-idf就是tf × idf的数值。
注意:
- tf是针对每篇文档而言的
- idf是针对总文档数而言的
实战
# coding: utf-8
import math
docs = [
'我 爱 技术 人民',
'我 爱 电脑',
'我 爱 加班 的 人民'
]
# 每篇文档的词频
def tf(word, word_count):
return word_count.get(word, 0) / sum(word_count.values())
# 词的文档频率
def idf(word, df_count):
return math.log(len(docs) / df_count.get(word, 0))
# 词的所有文档计数
df_count = dict()
# 词的每篇文档计数
word_count_list = list()
for index, doc in enumerate(docs):
word_count = dict()
word_list = doc.split(" ")
term_word_set = set()
for word in word_list:
word_count[word] = word_count.get(word, 0) + 1
if word not in term_word_set:
df_count[word] = df_count.get(word, 0) + 1
term_word_set.add(word)
else:
word_count_list.append(word_count)
print("词频计数:")
print(word_count_list)
print('df:', df_count)
print()
# 每个词的idf数值(当全局文档确定以后,每个词的idf值只有一个)
idf_dict = dict()
for word in df_count.keys():
idf_dict[word] = idf(word, df_count)
print("全局idf计算:")
print(idf_dict)
print()
print("每篇文档tf-idf:")
for word_count in word_count_list:
tf_idf = list()
for word in word_count.keys():
# 利用全局的idf,计算当前文档的tfidf
tf_idf.append((word, tf(word, word_count) * idf_dict.get(word)))
print(tf_idf)
评价
tfidf是通过词的相对频率来体现单词的重要性,是文本机器学习中常用的基础指标,经常用于对每篇文档的特征量化(即把一篇文档,通过出现的词的tf-idf的值,来表示这个文档的特征)。