【NLP】Task3:特征选择

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012736685/article/details/88825554

背景

将下面4个短文本做了词频统计:

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"] 

不考虑停用词,处理后得到的词向量如下:

[[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0]
 [0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0]
 [1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
 [0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]]

存在的问题:“come”,"China"和“Travel”各出现1次,而“to“出现了两次。似乎看起来这个文本与”to“这个特征更关系紧密。但是实际上”to“是一个非常普遍的词,几乎所有的文本都会用到,因此虽然它的词频为2,但是重要性却比词频为1的"China"和“Travel”要低的多。如果我们的向量化特征仅仅用词频表示就无法反应这一点。因此我们需要进一步的预处理来反应文本的这个特征,而这个预处理就是TF-IDF。

一、TF_IDF原理

TF-IDF(Term Frequency - Inverse Document Frequency,词频-逆文本频率)。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。 字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

它由两部分组成,TF和IDF。

  • TF(词频),即统计文本中各个词的出现频率,并作为文本特征。
  • IDF,即“逆文本频率”。一个词语普遍重要性的度量。

1、TF(item frequency)

词频TF(item frequency)
某一给定词语在该文本中出现次数。该数字通常会被归一化(分子一般小于分母),以防止它偏向长的文件,因为不管该词语重要与否,它在长文件中出现的次数很可能比在段文件中出现的次数更大。

T F ( x ) = M ( x ) M TF(x)=\frac{M(x)}{M}
其中, M M 表示文章的总词数, M ( x ) M(x) 表示词 x x 在文章中的出现次数。

2、逆向文件频率IDF(inverse document frequency)

逆向文件频率IDF(inverse document frequency):一个词语普遍重要性的度量。
主要思想是:如果包含词条 t 的文档越少, IDF越大,则说明词条具有很好的类别区分能力。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。

对于 x x 的IDF的基本公式如下:
I D F ( x ) = l o g N N ( x ) IDF(x)=log\frac{N}{N(x)}
其中, N N 代表语料库中文本的总数, N ( x ) N(x) 代表语料库中包含词 x x 的文本总数。

为了避免特殊情况,对上式进行平滑处理,使得语料库中没有出现的词也可以得到一个合适的IDF值。最常见的IDF平滑后的公式如下
I D F ( x ) = l o g N + 1 N ( x ) + 1 + 1 IDF(x)=log\frac{N+1}{N(x)+1}+1

3、TF-IDF

T F I D F ( x ) = T F ( x ) × I D F ( x ) TF-IDF(x)=TF(x)\times IDF(x)

二、TF-IDF实现

使用两种方法实现TF-IDF:

  • 第一种方法是在用 CountVectorizer类 向量化之后再调用 TfidfTransformer类 进行预处理。
  • 第二种方法是直接用 TfidfVectorizer 完成向量化与TF-IDF预处理。

1、方法一

# -*- coding:utf-8 -*-
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

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 = CountVectorizer()

transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
print(tfidf)

输出的各个文本各个词的TF-IDF值如下:

  (0, 16)	0.4424621378947393
  (0, 15)	0.697684463383976
  (0, 4)	0.4424621378947393
  (0, 3)	0.348842231691988
  (1, 14)	0.45338639737285463
  (1, 9)	0.45338639737285463
  (1, 6)	0.3574550433419527
  (1, 5)	0.3574550433419527
  (1, 3)	0.3574550433419527
  (1, 2)	0.45338639737285463
  (2, 12)	0.5
  (2, 7)	0.5
  (2, 1)	0.5
  (2, 0)	0.5
  (3, 18)	0.3565798233381452
  (3, 17)	0.3565798233381452
  (3, 15)	0.2811316284405006
  (3, 13)	0.3565798233381452
  (3, 11)	0.3565798233381452
  (3, 10)	0.3565798233381452
  (3, 8)	0.3565798233381452
  (3, 6)	0.2811316284405006
  (3, 5)	0.2811316284405006

2、方法二

TfidfVectorizer()

推荐使用:一步到位完成向量化,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"]

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

输出的各个文本各个词的TF-IDF值和第一种的输出完全相同。

三、互信息原理

1、点互信息(PMI)

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

公式如下:
P M I ( x ; y ) = l o g p ( x , y ) p ( x ) p ( y ) = l o g p ( x y ) p ( x ) = l o g p ( y x ) p ( y ) PMI(x;y)=log\frac{p(x,y)}{p(x)p(y)}=log\frac{p(x|y)}{p(x)}=log\frac{p(y|x)}{p(y)}
x x y y 不相关,则 p ( x , y ) = p ( x ) p ( y ) p(x,y)=p(x)p(y) 。两者相关性越大,则 p ( x , y ) p(x,y) 就相比于 p ( x ) p ( y ) p(x)p(y) 越大。

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

2、互信息MI

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

可以看出,互信息其实就是对X和Y的所有可能的取值情况的点互信息PMI的加权和。
公式:
I ( X ; Y ) = x X y Y p ( x , y ) l o g p ( x , y ) p ( x ) p ( y ) I(X;Y)=\sum_{x\in X}\sum_{y\in Y}p(x,y)log\frac{p(x,y)}{p(x)p(y)}

四、对特征矩阵使用互信息进行特征筛选

1、sklearn.metrics.mutual_info_score

计算互信息

from sklearn import datasets
from sklearn import metrics as mr

iris = datasets.load_iris()
x = iris.data
label = iris.target
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、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
label = iris.target

mutual_info = mutual_info_classif(x, label, discrete_features=False)
print(mutual_info)

输出结果

[0.52034027 0.28205642 0.99381377 0.99660608]

猜你喜欢

转载自blog.csdn.net/u012736685/article/details/88825554