NLP基础学习4--tfidf和互信息
继续做早鸟,首先这一期的任务提纲:
- TF-IDF原理。
- 文本矩阵化,使用词袋模型,以TF-IDF特征值为权重。(可以使用Python中TfidfTransformer库)
- 互信息的原理。
- 使用第二步生成的特征矩阵,利用互信息进行特征筛选
TF-IDF原理
感觉在word2vec 特别是现在的contextual word embedding之后,利用tf-idf直接向量化文本几乎已经弃用了,但是tf-idf作为权重,用来进行句子或者篇章中词向量的加权,也依然在被使用。
第一次接触tf-idf是很早以前,读吴军先生的《数学之类》[5]的时候,当时就被一系列文本向量化的表示和操作所吸引。回到主题,tf-idf实际上是两个指标,即tf Term Frequency,词频,idf Inverse Document Frequency 逆文本频率 。
TF-IDF的主要思想是:如果某个词在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词具有很好的类别区分能力,适合用来分类。
形式化的表达为: t f i , j = n i , j ∑ k n k , j tf_{i,j} = \frac{n_{i,j}}{\sum_k n_{k,j}} tfi,j=∑knk,jni,j, i d f i = ∣ D ∣ ∣ j : t i ∈ D j ∣ idf_i = \frac{|D|}{|{j:t_i \in D_j}|} idfi=∣j:ti∈Dj∣∣D∣, t f tf tf- i d f i = t f i , j ∗ i d f i idf _i= tf_{i,j} * idf_i idfi=tfi,j∗idfi。其中i 表示词 i i i , j j j 表示所属文章 D j D_j Dj, ∣ x ∣ |x| ∣x∣ 表示集合 x x x中元素的个数。
以TF-IDF特征值为权重的文本矩阵化
直接上代码
# -*- coding: utf-8 -*-
# @Time : 2019/4/12 11:43
# @Author : Lei Wang
# @Site :
# @File : tfidf.py
# @Software: PyCharmimport pkuseg
from sklearn.feature_extraction.text import CountVectorizerfrom sklearn.feature_extraction.text import TfidfTransformertext = []
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 X,如果我们知道,我们知道它的分布 P ( X ) P(X) P(X), 则可以定义它的信息熵为: H ( X ) = − ∑ x ∈ X P ( x ) l o g P ( x ) H(X) = - \sum_{x \in X} P(x) logP(x) H(X)=−∑x∈XP(x)logP(x)。 这里继续给出条件熵的概念,类比于条件概率分布, H ( X ∣ Y ) = − ∑ x ∈ X , y ∈ Y P ( x , y ) l o g P ( x ∣ y ) H(X|Y)=-\sum_{x \in X,y \in Y} P(x,y)logP(x|y) H(X∣Y)=−∑x∈X,y∈YP(x,y)logP(x∣y)那么问题来了,互信息呢? 互信息其实是用来度量两个事件的相关性,其定义如下:
I ( X ; Y ) = − ∑ x ∈ X , y ∈ Y P ( x , y ) P ( x ) P ( y ) = H ( X ) − H ( X ∣ Y ) I(X;Y) = -\sum_{x \in X,y \in Y} \frac{P(x,y)}{P(x)P(y)} = H(X) - H(X|Y) I(X;Y)=−∑x∈X,y∈YP(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 ) − ∑ l o g P ( x y z ) P ( z ) P ( x z ) P ( y z ) I(X;Y;Z) = I(X;Y) - I(X;Y|Z) = I(X;Y) - \sum log\frac{P(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)的相似性,即
K L ( f ( X ) ∣ ∣ g ( X ) ) = ∑ x ∈ X f ( x ) l o g f ( x ) g ( x ) KL(f(X)||g(X))=\sum_{x \in X} f(x) log\frac{f(x)}{g(x)} KL(f(X)∣∣g(X))=∑x∈Xf(x)logg(x)f(x), 而交叉熵则是 H ( f ( x ) , g ( x ) ) = − ∑ x ∈ X f ( x ) l o g g ( x ) = H ( f ( x ) ) + K L ( f ( x ) ∣ ∣ g ( x ) ) H(f(x),g(x))=-\sum_{x \in X} f(x) logg(x) = H(f(x)) +KL(f(x)||g(x)) H(f(x),g(x))=−∑x∈Xf(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
(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: PyCharmfrom sklearn.feature_extraction.text import CountVectorizerfrom 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 codecspos_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_liststop_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 )
NLP基础学习4--tfidf和互信息相关推荐
- NLP基础学习6--神经网络基础
左手肿了两个手指,写博客敲代码这酸爽... 言归正传,这一次的学习开始转入神经网络,主要任务是: 前馈神经网络.网络层数.输入层.隐藏层.输出层.隐藏单元.激活函数的概念. 感知机相关:利用tenso ...
- NLP文本相似度(TF-IDF)
前言 我们在比较事物时,往往会用到"不同","一样","相似"等词语,这些词语背后都涉及到一个动作--双方的比较.只有通过比较才能得出结论, ...
- 2021秋招-NLP基础任务模型-NER
NLP基础任务模型-NER 注: 基本全是转载,也都附加了转载链接,侵删. 多谢各位大佬的总结. 目录: 任务定义 简单综述 数据集细节总结 模型细节总结 损失函数计算 总结 NLP实战-中文命名实体 ...
- 【NLP】NLP爱好者学习资源推荐汇总
导读:本文旨在整理汇总一些NLPer的学习资源,包括书籍.在线课程.博客等.本文中涉及的原始失效链接均已剔除或替换,博客部分均整理为近期仍在更新的博客,欢迎文末留言区交流补充. 书籍篇 <Spe ...
- 微软开源项目 NeuronBlocks:像搭积木一样构建 NLP 深度学习模型!
作者 | 微软亚洲互联网工程院 (STCA) NLP Group 责编 | 胡巍巍 在构建自然语言理解深度学习模型过程中,研究人员或者工程师们经常需要在编程细节和代码调试上花费大量精力,而不是专注于模 ...
- 使用Pytorch实现NLP深度学习
原文链接:https://pytorch.org/tutorials/beginner/deep_learning_nlp_tutorial.html 本文将会帮助你了解使用Pytorch进行深度学习 ...
- NLP训练营学习记录(一)
文章目录 NLP训练营学习记录(一) 理解性小案例:机器翻译 概率语言模型 优化 自然语言处理的四个维度 算法复杂度 归并排序以及Master Theorem(主定理分析) P.NP hard.NP ...
- Pytorch:NLP 迁移学习、NLP中的标准数据集、NLP中的常用预训练模型、加载和使用预训练模型、huggingface的transfomers微调脚本文件
日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) run_glue.py微调脚本代码 python命令执行run ...
- 零基础学习深度学习_深度学习的基础!!!
零基础学习深度学习 The ability to learn from experience and perform better when confronted with similar chall ...
最新文章
- 移动互联网时代之用户名和密码何去何从(1)
- 在layui中使用ajax传值给后台,解决layui批量传值到后台操作时出现传值为空的问题...
- openresty开发系列24--openresty中lua的引入及使用
- 熟悉linux的安全与优化
- jenkins sonar-scanner 安装测试
- oracle从入门到精通_【论文】基于SPSS Modeler和Oracle的学生行为数据分析
- Workflow WF Reference Links for 2009-02-13
- -----------简单排序-------------
- wireshark之不显示ip问题(五)
- IEqualityComparerT
- 如何养成良好的生活习惯 — 饮食、睡眠、运动
- 怎么把一张暗的照片调亮_美图秀秀教你批量将偏暗的照片提亮
- w10恢复出厂设置_笔记本电脑w10怎么恢复出厂设置
- 计算机的组策略在什么地方,WINDOWS的常用组策略
- 设x、y、t均为int型变量,则执行语句:t=3; x=y=2; t=x++||++y; 后,变量t和y的值分别为
- 都2020年了,别再迷信啤酒与尿布!数据分析的真相在这
- oracle 配置不能保存,Oracle Net Manager保存网络配置提示无效条目Error writing entr
- 利用USB接口转串口芯片,做一个简单的闪光灯
- 「产品战略管理 」产品策略工具 - BCG增长 - 共享矩阵
- 图像处理(6)--图像深度