一、文本特征的特点
1、特征项能够区分文章的不同
2、特征项能够表达该文章的信息
3、特征的个数选择不能太多
二、特征选择的方法
1、TF-IDF
Frequency-Inverse Document Frequency:词频(TF)-逆文档频率(IDF),其中
词频(TF)= 某个词在文章中的出现次数 / 文章的总词数
逆文档频率(IDF) = log(语料库的文档总数 / (包含该词的文档数+1))
TF-IDF = TF * IDF
优缺点:
1)有效评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。因为它综合表征了该词在文档中的重要程度和文档区分度。
2)没有考虑特征词在类间的分布
例子如下:
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
text = ['我喜欢吃苹果',
'我爱吃香蕉',
'他不想吃桃子',
'我想去上海玩',
'她游玩的地点在重庆',
'他正在北京玩']
category = [1,1,1,2,2,2]
corpus = []
for t in text:
corpus.append(" ".join(list(jieba.cut(t))))
print(corpus)
#['我 喜欢 吃 苹果', '我 爱 吃 香蕉', '他 不想 吃 桃子', '我 想 去 上海 玩', '她 游玩 的 地点 在 重庆', '他 正在 北京 玩']
tfidf = TfidfVectorizer()
transform = tfidf.fit_transform(corpus)
print(transform.data)
#[0.70710678 0.70710678 1. 0.70710678 0.70710678 1.
0.57735027 0.57735027 0.57735027 0.70710678 0.70710678]
print(tfidf.vocabulary_)
#{'喜欢': 3, '苹果': 8, '香蕉': 10, '不想': 1, '桃子': 5, '上海': 0, '游玩': 7, '地点': 4, '重庆': 9, '正在': 6, '北京': 2}
从上面可以看到,关键词“吃”以及“玩”是区分类别1,2的重要依据,TFIDF未考虑到该因素。
2、互信息
互信息衡量的是某个词和类别之间的统计独立关系。互信息是计算语言学模型分析的常用方法,它度量两个对象之间的相互性。在过滤问题中用于度量特征对于主题的区分度。
使用互信息理论进行特征选择是基于此假设:在某个特定类别出现频率高,但在其他类别出现频率比较低的词条与该类的互信息比较大。通常用互信息作为特征词和类别之问的测度,如果特征词属于该类的话,它们的互信息量最大。由于该方法不需要对特征词和类别之问关系的性质作任何假设,因此非常适合于文本分类的特征和类别的配准工作。
互信息计算的时间复杂度类似于信息增益, 互信息的平均值就是信息增益。互信息的不足之处在于得分非常受词条边缘概率的影响。
例子如下:
from sklearn.feature_selection import mutual_info_classif
from gensim import corpora
#TF_IDF结果的互信息
print(mutual_info_classif(transform.toarray(), category, discrete_features=False))
#array([0. , 0. , 0.11666667, 0. , 0.03333333,
0. , 0. , 0.2 , 0. , 0. ,
0. ])
#{喜欢': 3, '苹果': 8, '香蕉': 10, '不想': 1, '桃子': 5,
'上海': 0, '游玩': 7, '地点': 4, '重庆': 9, '正在': 6,
'北京': 2}
#原始的文本的互信息
dic = corpora.Dictionary(words)
corpus = []
for t in text:
split_word = list(jieba.cut(t))
word = []
for w in dic.token2id.keys():
if w in split_word:
word.append(1)
else:
word.append(0)
corpus.append(word)
print(corpus)
mic = mutual_info_classif(corpus, category, discrete_features=False)
for i in range(len(dic.token2id.keys())):
print(list(dic.token2id.keys())[i],mic[i])
output
吃 0.45000000000000007
喜欢 0.0
我 0.0
苹果 0.0
爱 0.25555555555555554
香蕉 0.0
不想 0.0
他 0.0
桃子 0.0
上海 0.0
去 0.0
想 0.0
玩 0.436111111111111
在 0.0
地点 0.0
她 0.0
游玩 0.25555555555555565
的 0.0
重庆 0.15833333333333344
北京 0.0
正在 0.0
可以看到:“吃”与“玩”两个词的互信息的值较高,能够很好的区分类别之间的分布。