文章目录

  • 1. 利用TF-IDF进行特征选择
  • 1.1 TF-IDF原理
  • 1.2 用scikit-learn实现TF-IDF特征选择
  • 1.3 TF-IDF小结
  • 2. 利用互信息进行特征选择
  • 2.1 互信息介绍
  • 2.1.1 点互信息PMI
  • 2.2.1 互信息MI
  • 2.2 用scikit-learn实现TF-IDF特征选择
  • 2.2.1 sklearn.metricsmr.mutual_info_score
  • 2.2.2 sklearn.feature_selection.mutual_info_classif
  • 3. 参考资料


1. 利用TF-IDF进行特征选择

1.1 TF-IDF原理

TF-IDF是Term Frequency - Inverse Document Frequency的缩写,即“词频-逆文本频率”。它由两部分组成,TF和IDF。

前面的TF也就是我们前面说到的词频,我们之前做的向量化也就是做了文本中各个词的出现频率统计,并作为文本特征,这个很好理解。关键是后面的这个IDF,即“逆文本频率”如何理解。在上一节中,我们讲到几乎所有文本都会出现的"to"其词频虽然高,但是重要性却应该比词频低的"China"和“Travel”要低。我们的IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。

概括来讲, IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如上文中的“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。这样的词IDF值应该高。一个极端的情况,如果一个词在所有的文本中都出现,那么它的IDF值应该为0。

上面是从定性上说明的IDF的作用,那么如何对一个词的IDF进行定量分析呢?这里直接给出一个词x的IDF的基本公式如下:CNN提取特征的优点_NLP

其中,N代表语料库中文本的总数,而N(x)代表语料库中包含词x的文本总数。为什么IDF的基本公式应该是是上面这样的而不是像N/N(x)这样的形式呢?这就涉及到信息论相关的一些知识了。感兴趣的朋友建议阅读吴军博士的《数学之美》第11章。

上面的IDF公式已经可以使用了,但是在一些特殊的情况会有一些小问题,比如某一个生僻词在语料库中没有,这样我们的分母为0, IDF没有意义了。所以常用的IDF我们需要做一些平滑,使语料库中没有出现的词也可以得到一个合适的IDF值。平滑的方法有很多种,最常见的IDF平滑后的公式之一为:CNN提取特征的优点_特征选择_02

有了IDF的定义,我们就可以计算某一个词的TF-IDF值了:
CNN提取特征的优点_Datawhale_03

其中TF(x)指词x在当前文本中的词频。

1.2 用scikit-learn实现TF-IDF特征选择

直接用TfidfVectorizer完成向量化与TF-IDF预处理,输出的各个文本各个词的TF-IDF值。

from sklearn.feature_extraction.text import TfidfVectorizer

corpus = ["I come to China to travel",
          "This is a car polupar in China",
          "I love tea and Apple ",
          "The work is to write some papers in science"]

vectorizer = TfidfVectorizer()
re = vectorizer.fit_transform(corpus)
print(re)

1.3 TF-IDF小结

TF-IDF是非常常用的文本挖掘预处理基本步骤,但是如果预处理中使用了Hash Trick,则一般就无法使用TF-IDF了,因为Hash Trick后我们已经无法得到哈希后的各特征的IDF的值?。使用了IF-IDF并标准化以后,我们就可以使用各个文本的词特征向量作为文本的特征,进行分类或者聚类分析。

当然TF-IDF不光可以用于文本挖掘,在信息检索等很多领域都有使用。因此值得好好的理解这个方法的思想。

红字解析:

Hash Trick和PCA类似,Hash Trick降维后的特征,我们已经不知道它代表的特征名字和意义。此时我们不能像上一节向量化时候可以知道每一列的意义,所以Hash Trick的解释性不强。TF-idf 是 基于特征名称的统计计算的,当你不知道特征名称的时候,你就无法利用 TF-idf 。

一般来说,只要词汇表的特征不至于太大,大到内存不够用,肯定是使用一般意义的向量化比较好。因为向量化的方法解释性很强,我们知道每一维特征对应哪一个词,进而我们还可以使用TF-IDF对各个词特征的权重修改,进一步完善特征的表示。

而Hash Trick用大规模机器学习上,此时我们的词汇量极大,使用向量化方法内存不够用,而使用Hash Trick降维速度很快,降维后的特征仍然可以帮我们完成后续的分类和聚类工作。当然由于分布式计算框架的存在,其实一般我们不会出现内存不够的情况。因此,实际工作中我使用的都是特征向量化。

2. 利用互信息进行特征选择

2.1 互信息介绍

2.1.1 点互信息PMI

点互信息(Pointwise Mutual Information, PMI):用来衡量两个事物之间的相关性(比如两个词)。点互信息PMI其实就是从信息论里面的互信息这个概念里面衍生出来的。

公式如下:
CNN提取特征的优点_CNN提取特征的优点_04
若 x 与 y不相关,则 p(x,y)=p(x)p(y) 。两者相关性越大,则 p(x,y) 就相比于 p(x)p(y)越大。

例如:衡量like这个词的极性(正向情感还是负向情感)==》预先挑选一些正向情感的词,比如 good。然后计算 likegood 的PMI。

2.2.1 互信息MI

互信息:衡量两个随机变量之间的相关性。即一个随机变量中包含的关于另一个随机变量的信息量。

可以看出,互信息其实就是对X和Y的所有可能的取值情况的点互信息PMI的加权和。
公式如下:
CNN提取特征的优点_Datawhale_05

2.2 用scikit-learn实现TF-IDF特征选择

2.2.1 sklearn.metricsmr.mutual_info_score
from sklearn import datasets
from sklearn import metrics as mr

iris = datasets.load_iris()
x = iris.data  # 鸢尾花特征矩阵 shape = 4 * n
label = iris.target  # 鸢尾花目标信息 shape = 1 * n
x0 = x[:, 0]
x1 = x[:, 1]
x2 = x[:, 2]
x3 = x[:, 3]

# 计算各特征与label的互信息
print(mr.mutual_info_score(x0, label))
print(mr.mutual_info_score(x1, label))
print(mr.mutual_info_score(x2, label))
print(mr.mutual_info_score(x3, label))

[输出]
0.6078468394475832
0.35810955263431954
1.002510220562348
0.9952885384500019
2.2.2 sklearn.feature_selection.mutual_info_classif
from sklearn import datasets
from sklearn.feature_selection import mutual_info_classif

iris = datasets.load_iris()
x = iris.data  # 鸢尾花特征矩阵 shape = 4 * n
label = iris.target  # 鸢尾花目标信息 shape = 1 * n

mutual_info = mutual_info_classif(x, label)  # 返回鸢尾花四个特征与目标的互信息
"""
mutual_info_classif
计算离散目标的互信息
x:特征矩阵
lable:目标向量
返回值:各个特征与目标变量的互信息
"""
print(mutual_info)

[输出][0.47208165 0.2541436  0.98449648 0.99993525]
# 每次计算值不唯一 变动不大

3. 参考资料

1. 文本挖掘预处理之TF-IDF2. 如何进行特征选择(理论篇)3. sklearn:点互信息和互信息4. 使用不同的方法计算TF-IDF值