Task3笔记+代码

TF-IDF原理

参考文章:阮一峰的网络日志
这个标题看上去好像很复杂,其实我要谈的是一个很简单的问题。

有一篇很长的文章,我要用计算机提取它的关键词(Automatic Keyphrase extraction),完全不加以人工干预,请问怎样才能正确做到?

这个问题涉及到数据挖掘、文本处理、信息检索等很多计算机前沿领域,但是出乎意料的是,有一个非常简单的经典算法,可以给出令人相当满意的结果。它简单到都不需要高等数学,普通人只用10分钟就可以理解,这就是我今天想要介绍的TF-IDF算法。

让我们从一个实例开始讲起。假定现在有一篇长文《中国的蜜蜂养殖》,我们准备用计算机提取它的关键词。

一个容易想到的思路,就是找到出现次数最多的词。如果某个词很重要,它应该在这篇文章中多次出现。于是,我们进行"词频"(Term Frequency,缩写为TF)统计。

结果你肯定猜到了,出现次数最多的词是----“的”、“是”、“在”----这一类最常用的词。它们叫做"停用词"(stop words),表示对找到结果毫无帮助、必须过滤掉的词。

假设我们把它们都过滤掉了,只考虑剩下的有实际意义的词。这样又会遇到了另一个问题,我们可能发现"中国"、“蜜蜂”、"养殖"这三个词的出现次数一样多。这是不是意味着,作为关键词,它们的重要性是一样的?

显然不是这样。因为"中国"是很常见的词,相对而言,"蜜蜂"和"养殖"不那么常见。如果这三个词在一篇文章的出现次数一样多,有理由认为,“蜜蜂"和"养殖"的重要程度要大于"中国”,也就是说,在关键词排序上面,"蜜蜂"和"养殖"应该排在"中国"的前面。

所以,我们需要一个重要性调整系数,衡量一个词是不是常见词。如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性,正是我们所需要的关键词。

用统计学语言表达,就是在词频的基础上,要对每个词分配一个"重要性"权重。最常见的词(“的”、“是”、“在”)给予最小的权重,较常见的词(“中国”)给予较小的权重,较少见的词(“蜜蜂”、“养殖”)给予较大的权重。这个权重叫做"逆文档频率"(Inverse Document Frequency,缩写为IDF),它的大小与一个词的常见程度成反比。

知道了"词频"(TF)和"逆文档频率"(IDF)以后,将这两个值相乘,就得到了一个词的TF-IDF值。某个词对文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的几个词,就是这篇文章的关键词。

下面就是这个算法的细节。

第一步,计算词频。
t f = 该 词 再 文 档 中 出 现 的 次 数 文 章 的 总 词 数 tf = \frac{该词再文档中出现的次数}{文章的总词数} tf=

第二步,计算逆文档频率。

这时,需要一个语料库(corpus),用来模拟语言的使用环境。
i d f = l o g ( 语 料 库 的 文 档 总 数 包 含 该 词 的 文 档 数 + 1 ) idf = log(\frac{语料库的文档总数}{包含该词 的 文档数+1}) idf=log(+1)

如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数。

第三步,计算TF-IDF。

t f − i d f = t f × i d f tf-idf = tf\times idf tfidf=tf×idf
可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。

互信息的原理

参考1https://www.jianshu.com/p/ea48441d44a5
参考2https://www.jianshu.com/p/79de56cbb2c7
参考3http://blog.chinaunix.net/uid-20767210-id-1849628.html
机器学习相关文献里面,经常会用到PMI(Pointwise Mutual Information)这个指标来衡量两个事物之间的相关性(比如两个词)。其原理很简单,公式如下:
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)} PMI(x;y)=logp(x)p(y)p(x,y)=logp(x)p(xy)=logp(y)p(yx)
在概率论中,我们知道,如果x跟y不相关,则p(x,y)=p(x)p(y)。二者相关性越大,则p(x,y)就相比于p(x)p(y)越大。用后面的式子可能更好理解,在y出现的情况下x出现的条件概率p(x|y)除以x本身出现的概率p(x),自然就表示x跟y的相关程度。这里的log来自于信息论的理论,可以简单理解为,当对p(x)取log之后就将一个概率转换为了信息量(要再乘以-1将其变为正数),以2为底时可以简单理解为用多少个bits可以表示这个变量。至此,概念介绍完了,后面是例子和相关背景,不感兴趣的话就可以不用看了。例子举个自然语言处理中的例子来说,我们想衡量like这个词的极性(正向情感还是负向情感)。我们可以预先挑选一些正向情感的词,比如good。然后我们算like跟good的PMI,即:PMI(like,good)=logp(like,good)p(like)p(good)其中p(like)是like在语料库中出现的概率(出现次数除以总词数N),p(like,good)表示like跟good在一句话中同时出现的概率(like跟good同时出现的次数除以N2)。PMI(like,good)越大表示like的正向情感倾向就越明显。互信息(Mutual Information)点互信息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)} I(x;y)=xXyYp(x,y)logp(x)p(y)p(x,y)
其衡量的是两个随机变量之间的相关性,即一个随机变量中包含的关于另一个随机变量的信息量。所谓的随机变量,即随机试验结果的量的表示,可以简单理解为按照一个概率分布进行取值的变量,比如随机抽查的一个人的身高就是一个随机变量。可以看出,互信息其实就是对X和Y的所有可能的取值情况的点互信息PMI的加权和。因此,点互信息这个名字还是很形象的。

在对文本进行特征选择的时候,X表示某个词,Y表示类别,xi表示这个词的取值,在这里只有两种情况,出现和不出现,yi表示某一类,可能两类可能多类。xi 和yi同时出现在整个数据集中的概率:
P ( X = x i , Y = y i ) P(X = x_i,Y = y_i) P(X=xi,Y=yi)
xi在 整个数据集中出现的概率(词概率):
P ( X = x i ) P(X = x_i) P(X=xi)

yi在这个数据集中出现的概率(类概率):
P ( Y = y i ) P(Y = y_i) P(Y=yi)

对文本特征提取xi的取值只能是出现和不出现两种情况使用互信息理论进行特征抽取是基于如下假设:在某个特定类别出现频率高,但在其他类别出现频率比较低的词条与该类的互信息比较大。通常用互信息作为特征词和类别之问的测度,如果特征词属于该类的话,它们的互信息量最大。由于该方法不需要对特征词和类别之问关系的性质作任何假设,因此非常适合于文本分类的特征和类别的配准工作。特征项和类别的互信息体现了特征项与类别的相关程度,是一种广泛用于建立词关联统计模型的标准。互信息与期望交叉熵的不同在于没有考虑特征出现的频率,这样导致互信息评估函数不选择高频的有用词而有可能选择稀有词作为文本的最佳特征。因为对于每一主题来讲,特征t的互信息越大,说明它与该主题的共现概率越大,因此,以互信息作为提取特征的评价时应选互信息最大的若干个特征。互信息计算的时间复杂度类似于信息增益,互信息的平均值就是信息增益。互信息的不足之处在于得分非常受词条边缘概率的影响。

代码

1.文本矩阵化,使用词袋模型,以TF-IDF特征值为权重

contents = []
labels = []
with open('.\cnews.train.txt',mode='r',encoding='utf-8') as f:
    for line in f:
        try:
            label, content = line.strip().split('\t')
            if content:
                contents.append(content)
                labels.append(label)
        except:
            pass
import jieba
jieba_content = []
for con in contents:
    jieba_content.append(' '.join(jieba.cut(con)))
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(jieba_content)

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

from sklearn.feature_selection import SelectKBest
from minepy import MINE

#由于MINE的设计不是函数式的,定义mic方法将其为函数式的,返回一个二元组,二元组的第2项设置成固定的P值0.5
def mic(x, y):
    m = MINE()
    m.compute_score(x, y)
    return (m.mic(), 0.5)

#选择K个最好的特征,返回特征选择后的数据
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=30000).fit_transform(X, np.array(labels))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值