自然语言处理任务3

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

一1. TF-IDF原理。
在文本挖掘预处理之向量化与Hash Trick中我们讲到在文本挖掘的预处理中,向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的原理做一个总结。

  1. 文本向量化特征的不足
        在将文本分词并向量化后,我们可以得到词汇表中每个词在各个文本中形成的词向量,比如在文本挖掘预处理之向量化与Hash Trick这篇文章中,我们将下面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]]

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

https://www.cnblogs.com/pinard/p/6693230.html
二. 文本矩阵化,使用词袋模型,以TF-IDF特征值为权重。(可以使用Python中TfidfTransformer库)
1.使用gensim提取文本的tfidf特征
首先来看我们的语料库

corpus = [
    'this is the first document',
    'this is the second second document',
    'and the third one',
    'is this the first document'
]

接下来看我们的处理过程
1)把语料库做一个分词的处理

[输入]:
word_list = []
for i in range(len(corpus)):
    word_list.append(corpus[i].split(' '))
print(word_list)
    
[输出]:
[['this', 'is', 'the', 'first', 'document'],
 ['this', 'is', 'the', 'second', 'second', 'document'],
 ['and', 'the', 'third', 'one'],
 ['is', 'this', 'the', 'first', 'document']]


得到每个词的id值及词频

[输入]:
from gensim import corpora

赋给语料库中每个词(不重复的词)一个整数id

dictionary = corpora.Dictionary(word_list)
new_corpus = [dictionary.doc2bow(text) for text in word_list]
print(new_corpus)

元组中第一个元素是词语在词典中对应的id,第二个元素是词语在文档中出现的次数

[输出]:
[[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)], 
 [(0, 1), (2, 1), (3, 1), (4, 1), (5, 2)], 
 [(3, 1), (6, 1), (7, 1), (8, 1)], 
 [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)]]
 
 [输入]:
 # 通过下面的方法可以看到语料库中每个词对应的id
 print(dictionary.token2id)
 [输出]:
 {'document': 0, 'first': 1, 'is': 2, 'the': 3, 'this': 4, 'second': 5, 'and': 6,
 'one': 7,   'third': 8}

3)训练gensim模型并且保存它以便后面的使用
[输入]:

训练模型并保存

from gensim import models
tfidf = models.TfidfModel(new_corpus)
tfidf.save("my_model.tfidf")

载入模型

tfidf = models.TfidfModel.load("my_model.tfidf")

使用这个训练好的模型得到单词的tfidf值

tfidf_vec = []
for i in range(len(corpus)):
    string = corpus[i]
    string_bow = dictionary.doc2bow(string.lower().split())
    string_tfidf = tfidf[string_bow]
    tfidf_vec.append(string_tfidf)
print(tfidf_vec)

[输出]:
[[(0, 0.33699829595119235),
  (1, 0.8119707171924228),
  (2, 0.33699829595119235),
  (4, 0.33699829595119235)],
 [(0, 0.10212329019650272),
  (2, 0.10212329019650272),
  (4, 0.10212329019650272),
  (5, 0.9842319344536239)],
 [(6, 0.5773502691896258), (7, 0.5773502691896258), (8, 0.5773502691896258)],
 [(0, 0.33699829595119235),
  (1, 0.8119707171924228),
  (2, 0.33699829595119235),
  (4, 0.33699829595119235)]]

通过上面的计算我们发现这向量的维数和我们语料单词的个数不一致呀,我们要得到的是每个词的tfidf值,为了一探究竟我们再做个小测试

小测试现出gensim计算的原形

[输入]:

我们随便拿几个单词来测试

string = 'the i first second name'
string_bow = dictionary.doc2bow(string.lower().split())
string_tfidf = tfidf[string_bow]
print(string_tfidf)

[输出]:
[(1, 0.4472135954999579), (5, 0.8944271909999159)]

结论

gensim训练出来的tf-idf值左边是词的id,右边是词的tfidf值
gensim有自动去除停用词的功能,比如the
gensim会自动去除单个字母,比如i
gensim会去除没有被训练到的词,比如name
所以通过gensim并不能计算每个单词的tfidf值

2.使用sklearn提取文本tfidf特征
我们的语料库不变,还是上面那个

corpus = [
    'this is the first document',
    'this is the second second document',
    'and the third one',
    'is this the first document'
]

然后来看我们的处理过程

[输入]:
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vec = TfidfVectorizer()
tfidf_matrix = tfidf_vec.fit_transform(corpus)

得到语料库所有不重复的词

print(tfidf_vec.get_feature_names())

得到每个单词对应的id值

print(tfidf_vec.vocabulary_)

得到每个句子所对应的向量

向量里数字的顺序是按照词语的id顺序来的

print(tfidf_matrix.toarray())

[输出]:
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

{'this': 8, 'is': 3, 'the': 6, 'first': 2, 'document': 1, 'second': 5, 'and': 0, 'third': 7, 'one': 4}

[[0.         0.43877674 0.54197657 0.43877674 0.         0.
  0.35872874 0.         0.43877674]
 [0.         0.27230147 0.         0.27230147 0.         0.85322574
  0.22262429 0.         0.27230147]
 [0.55280532 0.         0.         0.         0.55280532 0.
  0.28847675 0.55280532 0.        ]
 [0.         0.43877674 0.54197657 0.43877674 0.         0.
  0.35872874 0.         0.43877674]]

3.python提取文本的tfidf特征
我们的语料库依旧不变

corpus = [
    'this is the first document',
    'this is the second second document',
    'and the third one',
    'is this the first document'
]

对语料进行分词

[输入]:
word_list = []
for i in range(len(corpus)):
    word_list.append(corpus[i].split(' '))
print(word_list)

[输出]:
[['this', 'is', 'the', 'first', 'document'],
 ['this', 'is', 'the', 'second', 'second', 'document'],
 ['and', 'the', 'third', 'one'],
 ['is', 'this', 'the', 'first', 'document']]

统计词频

[输入]:
countlist = []
for i in range(len(word_list)):
    count = Counter(word_list[i])
    countlist.append(count)
countlist

[输出]:
[Counter({'document': 1, 'first': 1, 'is': 1, 'the': 1, 'this': 1}),
 Counter({'document': 1, 'is': 1, 'second': 2, 'the': 1, 'this': 1}),
 Counter({'and': 1, 'one': 1, 'the': 1, 'third': 1}),
 Counter({'document': 1, 'first': 1, 'is': 1, 'the': 1, 'this': 1})]

定义计算tfidf公式的函数

word可以通过count得到,count可以通过countlist得到

count[word]可以得到每个单词的词频, sum(count.values())得到整个句子的单词总数

def tf(word, count):
    return count[word] / sum(count.values())

统计的是含有该单词的句子数

def n_containing(word, count_list):
    return sum(1 for count in count_list if word in count)

len(count_list)是指句子的总数,n_containing(word, count_list)是指含有该单词的句子的总数,加1是为了防止分母为0

def idf(word, count_list):
    return math.log(len(count_list) / (1 + n_containing(word, count_list)))

将tf和idf相乘

def tfidf(word, count, count_list):
    return tf(word, count) * idf(word, count_list)

计算每个单词的tfidf值

[输入]:
import math
for i, count in enumerate(countlist):
    print("Top words in document {}".format(i + 1))
    scores = {word: tfidf(word, count, countlist) for word in count}
    sorted_words = sorted(scores.items(), key=lambda x: x[1], reverse=True)
    for word, score in sorted_words[:]:
        print("\tWord: {}, TF-IDF: {}".format(word, round(score, 5)))

[输出]:
Top words in document 1
    Word: first, TF-IDF: 0.05754
    Word: this, TF-IDF: 0.0
    Word: is, TF-IDF: 0.0
    Word: document, TF-IDF: 0.0
    Word: the, TF-IDF: -0.04463
Top words in document 2
    Word: second, TF-IDF: 0.23105
    Word: this, TF-IDF: 0.0
    Word: is, TF-IDF: 0.0
    Word: document, TF-IDF: 0.0
    Word: the, TF-IDF: -0.03719
Top words in document 3
    Word: and, TF-IDF: 0.17329
    Word: third, TF-IDF: 0.17329
    Word: one, TF-IDF: 0.17329
    Word: the, TF-IDF: -0.05579
Top words in document 4
    Word: first, TF-IDF: 0.05754
    Word: is, TF-IDF: 0.0
    Word: this, TF-IDF: 0.0
    Word: document, TF-IDF: 0.0
    Word: the, TF-IDF: -0.04463

作者:炼己者
链接:https://www.jianshu.com/p/f3b92124cd2b
来源:简书

三 互信息的原理。
1、点互信息PMI

机器学习相关文献里面,经常会用到点互信息PMI(Pointwise Mutual Information)这个指标来衡量两个事物之间的相关性(比如两个

词)。

其原理很简单,公式如下:

在概率论中,我们知道,如果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的相关程度。

举个自然语言处理中的例子来说,我们想衡量like这个词的极性(正向情感还是负向情感)。我们可以预先挑选一些正向情感的词,

比如good。然后我们算like跟good的PMI。

2、互信息MI

点互信息PMI其实就是从信息论里面的互信息这个概念里面衍生出来的。

互信息即:

其衡量的是两个随机变量之间的相关性,即一个随机变量中包含的关于另一个随机变量的信息量。所谓的随机变量,即随机试验结

果的量的表示,可以简单理解为按照一个概率分布进行取值的变量,比如随机抽查的一个人的身高就是一个随机变量。

可以看出,互信息其实就是对X和Y的所有可能的取值情况的点互信息PMI的加权和。因此,点互信息这个名字还是很形象的。

3、sklearn编程

from sklearn import metrics as mr
mr.mutual_info_score(label,x)
label、x为list或array。

计算x和label的互信息。

原文:https://blog.csdn.net/u013710265/article/details/72848755
版权声明:本文为博主原创文章,转载请附上博文链接!

四、使用第二步生成的特征矩阵,利用互信息进行特征筛选。
一个典型的机器学习任务,是通过样本的特征来预测样本所对应的值。如果样本的特征少了,我们会考虑增加特征,比如Polynomial Regression就是典型的增加特征的算法。在前一周的课程中,相信大家已经体会到,模型特征越多,模型的复杂度也就越高,越容易导致过拟合。事实上,如果我们的样本数少于特征数,那么过拟合就不可避免。
而现实中的情况,往往是特征太多了,需要减少一些特征。
首先是“无关特征”(irrelevant feature)。比如,通过空气的湿度,环境的温度,风力和当地人的男女比例来预测明天会不会下雨,其中男女比例就是典型的无关特征。
其次,要减少的另一类特征叫做“多余特征”(redundant feature),比如,通过房屋的面积,卧室的面积,车库的面积,所在城市的消费水平,所在城市的税收水平等特征来预测房价,那么消费水平(或税收水平)就是多余特征。证据表明,消费水平和税收水平存在相关性,我们只需要其中一个特征就够了,因为另一个能从其中一个推演出来。(如果是线性相关,那么我们在用线性模型做回归的时候,会出现严重的多重共线性问题,将会导致过拟合。)
减少特征有非常重要的现实意义,甚至有人说,这是工业界最重要的问题。因为除了降低过拟合,特征选择还可以使模型获得更好的解释性,加快模型的训练速度,一般的,还会获得更好的性能。
问题在于,在面对未知领域的时候,很难有足够的知识去判断特征与我们的目标是不是相关,特征与特征之间是不是相关。这时候,就需要一些数学和工程上的办法来帮助我们尽可能地把恰好需要的特征选择出来。
常见的方法包括过滤法(Filter)、包裹法(Warpper),嵌入法(Embedding)。
https://baijiahao.baidu.com/s?id=1604074325918456186&wfr=spider&for=pc

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值