一些经常出现(频次较高)的单词对实际意义几乎没有帮助(如英语中的 “the”、“a”、“is”),会掩盖掉频次较低的有意义词。
通过将频次较低、有意义的稀有词汇增加权重,可以更好地突出文档的特征。
TF-IDF 加权
TF(term-frequrency,术语频率或称为词频率),IDF(inverse document-frequency,逆文档频率)
tf-idf
(
t
,
d
)
=
tf
(
t
,
d
)
×
idf
(
t
)
\textsf{tf-idf}(t,d)=\textsf{tf}(t,d)\times \textsf{idf}(t)
tf-idf(t,d)=tf(t,d)×idf(t)
其中
t
t
t 代表词,在语料库矩阵中也代表着
f
e
a
t
u
r
e
feature
feature 列,
d
d
d 代表文档,在语料库矩阵中代表样本,也就是行。因此,上述计算可以看作是对语料库矩阵中的每一列(代表特征
t
t
t )做加权运算,权值为
idf
(
t
)
\textsf{idf}(t)
idf(t) 。
idf
(
t
)
\textsf{idf}(t)
idf(t) 的计算公式为
idf ( t ) = log 1 + n 1 + df ( t ) + 1 \textsf{idf}(t)=\log\frac{1+n}{1+\textsf{df}(t)}+1 idf(t)=log1+df(t)1+n+1
其中 n n n 是指文档集合中的文档总数量, df ( t ) \textsf{df}(t) df(t) 指文档集合中包含有词 t t t 的文档数量。
因为 df ( t ) ≤ n \textsf{df}(t) \leq n df(t)≤n 总是成立的,所以对数值内的数值是大于等于 1 的,并且当 df ( t ) \textsf{df}(t) df(t) 越接近 n n n 时(此时也代表 t t t 这个词在绝大部分文档中都有出现,也就是一个常见词), idf ( t ) \textsf{idf}(t) idf(t) 值越小。概括地说, idf ( t ) \textsf{idf}(t) idf(t) 是一个词稀有程度的度量,词越稀有则 idf ( t ) \textsf{idf}(t) idf(t) 越大。
tf-idf ( t , d ) \textsf{tf-idf}(t,d) tf-idf(t,d) 计算完成后,对每行(也就是每个文档,固定 d d d )进行归一化处理,从而使得特征值代表词 t t t 在文档 d d d 中出现的概率。
scikit-learn 实现
scikit-learn 库使用 TfidfTransformer
和 TfidfVectorizer
(相当于由 TfidfTransformer
和 CountVector
组成)实现 TF-IDF 加权。
scikit-learn 库中的 TfidfTransformer
和 TfidfVectorizer
将 idf 定义为
idf ( t ) = log n 1 + df ( t ) \textsf{idf}(t)=\log\frac{n}{1+\textsf{df}(t)} idf(t)=log1+df(t)n
如果 TfidfTransformer
和 TfidfVectorizer
参数 smooth_idf=False
,则 idf 计算方式为
idf ( t ) = log n df ( t ) + 1 \textsf{idf}(t)=\log\frac{n}{\textsf{df}(t)} + 1 idf(t)=logdf(t)n+1
代码实现
from sklearn.feature_extraction.text import TfidfTransformer
# 创建 TF-IDF 的变换器
transformer = TfidfTransformer(smooth_idf=False)
# 简单语料库例子,共有 6 个(行)样本,3个(列)特征
# 其中第 1 列代表的特征在所有文档中都有出现,且比例较高
# 剩下的 2 个特征都比较稀有
counts = [[3, 0, 1],
[2, 0, 0],
[3, 0, 0],
[4, 0, 0],
[3, 2, 0],
[3, 0, 2]]
tfidf = transformer.fit_transform(counts)
tfidf.toarray()
输出结果为
array([[0.81940995, 0. , 0.57320793],
[1. , 0. , 0. ],
[1. , 0. , 0. ],
[1. , 0. , 0. ],
[0.47330339, 0.88089948, 0. ],
[0.58149261, 0. , 0.81355169]])
参考资料:
6.2. Feature extraction — scikit-learn 1.3.2 documentation