自然语言处理第四期

    TF-IDF原理。
    文本矩阵化,使用词袋模型,以TF-IDF特征值为权重。(可以使用Python中TfidfTransformer库)
    互信息的原理。
    使用第二步生成的特征矩阵,利用互信息进行特征筛选

TF-IDF原理

感觉在word2vec 特别是现在的contextual word embedding之后,利用tf-idf直接向量化文本几乎已经弃用了,但是tf-idf作为权重,用来进行句子或者篇章中词向量的加权,也依然在被使用。
tf-idf实际上是两个指标,即tf Term Frequency,词频,idf Inverse Document Frequency 逆文本频率 。

TF-IDF的主要思想是:如果某个词在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词具有很好的类别区分能力,适合用来分类。
形式化的表达为: tfi,j=ni,j∑knk,j
tfi,j​=∑k​nk,j​ni,j​​,idfi=∣D∣∣j:ti∈Dj∣idfi​=∣j:ti​∈Dj​∣∣D∣​,tftf-idfi=tfi,j∗idfiidfi​=tfi,j​∗idfi​。其中i 表示词 ii , jj 表示所属文章 DjDj​, ∣x∣∣x∣ 表示集合 x

x中元素的个数。
以TF-IDF特征值为权重的文本矩阵化

直接上代码

# -*- coding: utf-8 -*-
# @Time : 2019/4/12 11:43
# @Author : Lei Wang
# @Site :
# @File : tfidf.py
# @Software: PyCharm


import pkuseg
from sklearn.feature_extraction.text import CountVectorizer

from sklearn.feature_extraction.text import TfidfTransformer

text = []
with open(r'..\cnews\cnews.train.txt', 'r', encoding = 'utf-8') as fsource:
    text_line= fsource.readline()
    seg = pkuseg.pkuseg()
    seg_list = seg.cut(text_line)
    text.extend(seg_list)

with open(r'..\stoplist_baidu.txt', 'r', encoding = 'utf-8') as fstop:
    content = fstop.read()
    stop_words = content.split('\n')


count_vectorizer = CountVectorizer(stop_words=stop_words)
tfidf_transformer = TfidfTransformer()
tfidf = tfidf_transformer.fit_transform(count_vectorizer.fit_transform(text))
print (tfidf)

print('-------------给个小一点的例子--------------')

corpus = [          'This is the first document.',
        'This is the second second document.',
        'And the third one.',
        'Is this the first document?',
        ]

s_count_vectorizer = CountVectorizer()
s_tfidf_transformer = TfidfTransformer()
s_tfidf = s_tfidf_transformer.fit_transform(s_count_vectorizer.fit_transform(corpus))
print (s_tfidf)

  

结果截图:
在这里插入图片描述
互信息的原理

谈起互信息这个话题,还是依着《数学之美》[5]思路,先从信息和熵的定义开始说。信息是用来消除不确定性的。换句话说,知道的信息越多,不确定性就越低。对于一个变量X
X,如果我们知道,我们知道它的分布P(X)P(X), 则可以定义它的信息熵为:H(X)=−∑x∈XP(x)logP(x)H(X)=−∑x∈X​P(x)logP(x)。 这里继续给出条件熵的概念,类比于条件概率分布,H(X∣Y)=−∑x∈X,y∈YP(x,y)logP(x∣y)

H(X∣Y)=−∑x∈X,y∈Y​P(x,y)logP(x∣y)那么问题来了,互信息呢? 互信息其实是用来度量两个事件的相关性,其定义如下:

I(X;Y)=−∑x∈X,y∈YP(x,y)P(x)P(y)=H(X)−H(X∣Y)

I(X;Y)=−∑x∈X,y∈Y​P(x)P(y)P(x,y)​=H(X)−H(X∣Y)

关于互信息,其实我当年做过一个很有意思的推导,就是想推导多元的互信息熵。我当时只是推导了三元,基本结论是
I(X;Y;Z)=I(X;Y)−I(X;Y∣Z)=I(X;Y)−∑logP(xyz)P(z)P(xz)P(yz)

I(X;Y;Z)=I(X;Y)−I(X;Y∣Z)=I(X;Y)−∑logP(xz)P(yz)P(xyz)P(z)​
正确性有待各位有心的观众检验,多元互信息的表达我参考文献[6]。
关于互信息,数学之美上还有一个关于tf-idf的信息学解释,有兴趣可以去看书的108-109页的相关内容,写的非常清晰易懂,这里就不再赘述了。

既然写到这里,那就顺便写一下深度学习中最常用的相对熵和交叉熵。相对熵,也就是KL散度的定义,他是用来衡量两个取值为正的函数f(X)和g(X)的相似性,即
KL(f(X)∣∣g(X))=∑x∈Xf(x)logf(x)g(x)
KL(f(X)∣∣g(X))=∑x∈X​f(x)logg(x)f(x)​, 而交叉熵则是H(f(x),g(x))=−∑x∈Xf(x)logg(x)=H(f(x))+KL(f(x)∣∣g(x))

H(f(x),g(x))=−∑x∈X​f(x)logg(x)=H(f(x))+KL(f(x)∣∣g(x))。当然这两个熵也都有对应的连续变量形式的表达。可以看出:

    两个完全相同的函数,交叉熵为0
    交叉熵越大,两个函数差异越大;反之亦然
    对于概率密度或者概率分布函数,如果取值均大于0,交叉熵可以度量两个随机分布的差异性

利用互信息进行特征筛选

特征选择指的是删除了原始特征里和结果预测关系不大的特征,而不像降维会去做特征的计算组合构成了新的特征。 这里参考了文献[7]
常用的方法有:过滤法,包裹法和嵌入法
1. 过滤型

方法:评价单个特征和结果之间的相关程度,排序留下Top相关的部分。
评价方式:Pearson相关系数、互信息
缺点:没有考虑到特征之间的关联作用,可能把有用的关联特征踢掉。因此工业界使用的比较少
python包:SelectKBest指定过滤个数、SelectPercentile指定过滤的百分比

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target
X.shape

  

(150, 4)

X_new = SelectKBest(chi2, k = 2).fit_transform(X, y)
X_new.shape

    1
    2

(150, 2)
2.包裹型

方法:把特征选择看做一个特征子集搜索问题,筛选各种特征子集,用模型评估效果(递归特征删除算法,RFE)。
应用在LR上过程:用全量特征跑一个模型;删掉5~10%的弱特征,观察准确率/AUC的变化;逐步进行,直至准确率/AUC出现大的下滑停止。
python:RFE

from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_boston
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
lr = LinearRegression()
rfe = RFE(lr, n_features_to_select = 1)
rfe.fit(X, Y)
print("Features sorted by their rank:")
print(sorted(zip(map(lambda x: round(x, 4), rfe.ranking_),names)))

Features sorted by their rank:
[(1, ‘NOX’), (2, ‘RM’), (3, ‘CHAS’), (4, ‘PTRATIO’), (5, ‘DIS’), (6, ‘LSTAT’), (7, ‘RAD’), (8, ‘CRIM’), (9, ‘INDUS’), (10, ‘ZN’), (11, ‘TAX’), (12, ‘B’), (13, ‘AGE’)]
3.嵌入型

方法:根据模型来分析特征重要性,最常见的方式为正则化方式来做特征选择
举例:举个例子,最早在电商用LR做CRT预估,在3-5亿维系数的特征上用L1正则化的LR模型。剩余2-3千万的feature,意味着其他的feature的重要程度不够。
python:feature_selection.SelectFromModel选出权重不为0的特征

from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
X.shape

  

(150, 4)

lsvc = LinearSVC(C = 0.01, penalty = "l1", dual = False).fit(X, y)
model = SelectFromModel(lsvc, prefit = True)
X_new = model.transform(X)
X_new.shape

   

(150, 3)

回到主题,如何利用互信息进行特征筛选, 还是利用sklearn的库,因为这个需要标签,所以用了IMDB,代码如下

# -*- coding: utf-8 -*-
# @Time : 2019/4/13 12:11
# @Author : Lei Wang
# @Site :
# @File : feature_selection.py
# @Software: PyCharm

from sklearn.feature_extraction.text import CountVectorizer

from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import mutual_info_classif


#选择K个最好的特征,返回选择特征后的数据
#arr = SelectKBest(mutual_info_classif, k=2).fit_transform(tfidf, target[:99])


from nltk.corpus import stopwords
import collections
import pandas as pd
import numpy as np
import os
import codecs

pos_list=[]

with open('../Sentiment_IMDB/aclImdb/train/pos_all.txt','r',encoding='utf8')as f:
    line=f.readlines()
    pos_list.extend(line)
neg_list=[]
with open('../Sentiment_IMDB/aclImdb/train/neg_all.txt','r',encoding='utf8')as f:
    line=f.readlines()
    neg_list.extend(line)
#创建标签
label=[1 for i in range(12500)]
label.extend([0 for i in range(12499)])
#评论内容整合
content=pos_list.extend(neg_list)
content=pos_list

stop_words=set(stopwords.words('english'))
count_vectorizer = CountVectorizer(stop_words=stop_words)
tfidf_transformer = TfidfTransformer()
tfidf = tfidf_transformer.fit_transform(count_vectorizer.fit_transform(content))
print (tfidf.shape)

arr = SelectKBest(mutual_info_classif, k=2).fit_transform(tfidf[:24999], label)
print(arr)

 

互信息特征筛选
参考文献

    文本挖掘预处理之TF-IDF:文本挖掘预处理之TF-IDF - 刘建平Pinard - 博客园 (https://www.cnblogs.com/pinard/p/6693230.html)
    使用不同的方法计算TF-IDF值:使用不同的方法计算TF-IDF值 - 简书(https://www.jianshu.com/p/f3b92124cd2b)
    sklearn-点互信息和互信息:sklearn:点互信息和互信息 - 专注计算机体系结构 - CSDN博客 (https://blog.csdn.net/u013710265/article/details/72848755)
    如何进行特征选择(理论篇)机器学习你会遇到的“坑”:如何进行特征选择(理论篇)机器学习你会遇到的“坑” (https://baijiahao.baidu.com/s?id=1604074325918456186&wfr=spider&for=pc)
    吴军. 数学之美[M]. 人民邮电出版社, 2012
    Multivariate mutual information, wiki,(https://en.wikipedia.org/wiki/Multivariate_mutual_information)
    bd-liuming ,CSDN(https://blog.csdn.net/fisherming/article/details/79925574 )
---------------------
作者:有莘不殁
来源:CSDN
原文:https://blog.csdn.net/shark803/article/details/89228875
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值