当前位置:   article > 正文

TF-IDF介绍(原来+代码)_tfidf需要引入外部语料库吗

tfidf需要引入外部语料库吗

TF-IDF原理

    对于一篇比较长的文章,想要不加人为干预的迅速了解文章的关键词,该怎么做到呢?这时候要送到经典算法IF-IDF,TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术。
    直观上理解,如果一个词很关键,那么这个词在文本中出现的次数就会比较多,此时我们就用 TF(词频) 来表示。而你又要问了,那么文章中出现最多的一定是一些类似 “的”,‘是’,‘在’等停用词 需要将这些词事先过滤掉在对文本进行处理。还有一个问题,我们要考虑词语的关键程度,如果文章中有些词出现的次数一样多,比如 “中国”,“蜜蜂”,“养殖” ,是否就能简单的认为这三个词语重要程度一样呢?答案是否定的,我们很容易看出 “中国” 是一个很常见的词语,在很多文献中都是经常出现的词语,就算给你这个词语,你并不知道这篇文章是干什么的。而 “蜜蜂”,“养殖” 却不常见,很能反应文章的内容,其俩关键性要大于 中国 ,所以还需要采取一种方法来解决。
    所以,我们需要一个重要性调整系数,衡量一个词是不是常见词。如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性,正是我们所需要的关键词。
    用统计语言来表示,就是在 词频的基础上,对每个词分配一个表示“重要性”的 权重 ,比如最常见的词 “是”,“的” 等停用词给与最小的权重,“中国” 给与较小的权重,而 “蜜蜂”,“养殖” 这类少见的词语给予较大的权重。我们把这个权重叫做 “逆文档频率(IDF)” ,它的大小与一个词的常见程度成 反比
    我们已经了解了什么是 频率(TF)逆文档频率(IDF) 的概念。将两个值相乘,就得到了一个词的 TF-IDF值 ,值越大,说明词对文章的重要性越高。根绝词语的TF-IDF值排名来选择文章的关键词。

I F − I D F IF-IDF IFIDF 的计算步骤如下:

     1 、 1、 1 计算词频
    词频(TF) = 该词在文章中出现的次数
    考虑到文章有长短之分,这里对文章进行 “词频”标准化
    词频(TF) = 该词在文章出现的次数/文章总词数
     2 、 2、 2 计算逆文档频率
    这是,需要一个语料库(corpus),用来模拟语言的使用环境。计算公式为
    逆文档频率(IDF) = log10(语料库的文档总数/包含该词的文档数+1)
     分母加1是为了防止所有文档都不包含该词,避免分母为0
     3 、 3、 3 计算TF-IDF
    TF-IDF = 词频(TF) X 逆文档频率(IDF)
    从最终的结果来看,TF-IDF值与一个词在文档中出现的次数成 正比 ,与该词在整个语言中的出现次数成 反比 ,所以提取文章关键词就要计算TF-IDF值,按照大小顺序进行选择。
下面以 《中国的蜜蜂养殖》 为例子,为大家计算一下。假定文章长度为1000个词,“中国”,“蜜蜂”,“养殖” 各出现了15次,则这三个词的 “词频(TF)” 都为0.015,然后搜索Google发现,包含 “的” 的网页共有250亿张,包含 “中国” 的网页共有62.3亿张,包含 “蜜蜂” 的网页为0.484亿张,包含 “养殖” 的网页为0.973亿张,则他们的 逆文档频率(IDF)IF-IDF值 如下:

包含该词的文档数(亿)IDFTF-IDF
中国62.30.6030.009
蜜蜂0.4842.7130.041
养殖0.9732.4100.036
2500.0023e-5

    从结果来看,“蜜蜂” 的TF-IDF值最高,**"养殖"其次,“的”**最低,近乎于 0。所以,如果只选择一个词,"蜜蜂"就是这篇文章的关键词。
    TF-IDF算法的优点是简单快速,结果比较符合实际情况。缺点是,单纯以"词频"衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多。而且,这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。(一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。)

使用三种方法计算TF-IDF值

1 、 g e n s i m 库 来 计 算 T F − I D F 值 1、gensim库来计算TF-IDF值 1gensimTFIDF
首 先 构 建 语 料 库 为 首先构建语料库为

corpus = [
	'this is the first document',
	'this is the second second document',
	'and the third one',
	'is this the first document'
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

开 始 处 理 开始处理
1 ) 对 文 本 进 行 分 词 1)对文本进行分词 1

seg_list = []
for i in range(len(corpus)):
    seg_list.append(corpus[i].split(' '))
seg_list
结果为:
[['this', 'is', 'the', 'first', 'document'],
 ['this', 'is', 'the', 'second', 'second', 'document'],
 ['and', 'the', 'third', 'one'],
 ['is', 'this', 'the', 'first', 'document']]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2 ) 对 每 个 词 分 配 I d 以 及 计 算 词 频 2)对每个词分配Id以及计算词频 2Id

from gensim import corpora
dictionary = corpora.Dictionary(seg_list)  #生成字典,且对词语编号Id
for key,value in dictionary.items():
    print(key,value)

结果为:
0 document
1 first
2 is
3 the
4 this
5 second
6 and
7 one
8 third
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
#词频统计
new_corpus = [dictionary.doc2bow(text) for text in seg_list]
print(new_corpus)
结果为:
[[(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,第二个数表示词频(词语出现的个数),比如(0,1)表示第一个文本中document出现了1词,(5,2)表示第二个文本中second出现了2次。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3 ) 训 练 g e n s i m 模 型 并 且 保 存 它 以 便 后 面 的 使 用 3)训练gensim模型并且保存它以便后面的使用 3gensim便使

from gensim import models
tfidf = models.TfidfModel(new_corpus) #训练的模型
#载入模型得到单词的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)]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

g e n s i m 方 法 总 结 : gensim方法总结: gensim
1、gensim训练出来的tf-idf值左边是词的id,右边是词的tfidf值
2、gensim有自动去除停用词的功能,比如the
3、gensim有自动去除单个字母,比如i
4、所以通过gensim并不能计算每个单词的tfidf值

2 、 s k l e a r n 库 提 取 文 本 t f i d f 特 征 2、sklearn库提取文本tfidf特征 2sklearntfidf
代 码 代码

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vec = TfidfVectorizer()
tfidf_matrix = tfidf_vec.fit_transform(corpus)

#得到语料库中不重复的词
print('不重复词:\n',tfidf_vec.get_feature_names())

#得到每个单词对应的id值
print('词语对应的id:\n',tfidf_vec.vocabulary_)

#得到每个句子所对应的向量
#向量里数字的顺序是按照词语的id顺序来的
print(tfidf_matrix.toarray())

结果为:
不重复词:
 ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
词语对应的id:
 {'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]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3 、 自 定 义 p y t h o n 提 取 文 本 t f i d f 特 征 3、自定义python提取文本tfidf特征 3pythontfidf
基 于 原 来 的 语 料 库 以 及 分 词 处 理 基于原来的语料库以及分词处理
1 ) 词 频 统 计 1)词频统计 1

from collections import Counter
countlist = []
for i in range(len(seg_list)):
    count = Counter(seg_list[i])
    countlist.append(count)
print(countlist)

结果:
[Counter({'this': 1, 'is': 1, 'the': 1, 'first': 1, 'document': 1}), 
Counter({'second': 2, 'this': 1, 'is': 1, 'the': 1, 'document': 1}),
 Counter({'and': 1, 'the': 1, 'third': 1, 'one': 1}), 
Counter({'is': 1, 'this': 1, 'the': 1, 'first': 1, 'document': 1})]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2 ) 定 义 p y t h o n 计 算 t f i d f 公 式 的 函 数 2)定义python计算tfidf公式的函数 2pythontfidf

# 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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3 ) 计 算 每 个 单 词 的 t f i d f 值 3)计算每个单词的tfidf值 3tfidf

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

3、联合词袋模型和TF-IDF

    tf-idf的主要作用就是找出某个词或某些词用于区别于其他文本,而 词袋模型 恰好又是找出文本中出现频率高的词语,那么我们试想:如果我先用词袋模型筛选出一些高热度词汇,再用tf-idf计算其权值,我们将得到词袋模型中的词汇的tf-idf值,值越高说明该词却分每条语句的效果越好。

import numpy as np
from sklearn import preprocessing
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

vec=CountVectorizer(min_df=3,ngram_range=(1,1))
content=[
    '<s[NULL]cript>alert(1)</s[NULL]cript>X</a>',
    '\'><video><source o?UTF-8?Q?n?error="alert(1)">',
    '\'><FRAMESET><FRAME RC=""+"javascript:alert(\'X\');"></FRAMESET>',
    '"></script>\'//<svg "%0Aonload=alert(1) //>',
    '"></script><img \'//"%0Aonerror=alert(1)// src>',
    'id%3Den%22%3E%3Cscript%3Ealert%28%22AKINCILAR%22%29%3C/script%3E',
    '?a%5B%5D%3D%22%3E%3Cscript%3Ealert%28document.cookie%29%3C/script%3E',
    '><iframe src="data:data:javascript:,% 3 c script % 3 e confirm(1) % 3 c/script %3 e">',
    '?mess%3D%3Cscript%3Ealert%28document.cookie%29%3C/script%3E%26back%3Dsettings1',
    'title%3D%3Cscript%3Ealert%28%22The%20Best%20XSSer%22%29%3C/script%3E',
    '<script charset>alert(1);</script charset>',
    '"><meta charset="x-mac-farsi">??script ??alert(1)//??/script ??',
    '</script><script>/*"/*\'/**/;alert(1)//</script>#',
]
X=vec.fit_transform(content)
trans=TfidfTransformer()
tfidf=trans.fit_transform(X)
print (vec.get_feature_names())
print (tfidf.toarray())

输出结果:
['22', '29', '3c', '3cscript', '3d', '3e', '3ealert', 'alert', 'script']
[[ 0.          0.          0.          0.          0.          0.          0.
   1.          0.        ]
 [ 0.          0.          0.          0.          0.          0.          0.
   1.          0.        ]
 [ 0.          0.          0.          0.          0.          0.          0.
   1.          0.        ]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.75787695  0.65239752]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.75787695  0.65239752]
 [ 0.60865989  0.27418507  0.27418507  0.27418507  0.          0.54837013
   0.27418507  0.          0.16767089]
 [ 0.33715382  0.30375763  0.30375763  0.30375763  0.33715382  0.60751526
   0.30375763  0.          0.18575524]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.          1.        ]
 [ 0.          0.38907452  0.38907452  0.38907452  0.43185075  0.38907452
   0.38907452  0.          0.23792861]
 [ 0.39646122  0.35719043  0.35719043  0.35719043  0.39646122  0.35719043
   0.35719043  0.          0.21843071]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.50226141  0.86471583]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.50226141  0.86471583]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.36109936  0.93252735]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

4、互信息原理

点 互 信 息 P M I 点互信息PMI PMI
点互信息PMI(Pointwise Mutual Information)这个指标常常用来衡量两个事物之间的相关性(比如两个词)。公式如下:
在这里插入图片描述

如果x跟y不相关,则p(x,y)=p(x)p(y)。二者相关性越大,则p(x, y)就相比于p(x)p(y)越大。
举个自然语言处理中的例子来说,我们想衡量like这个词的极性(正向情感还是负向情感)。我们可以预先挑选一些正向情感的词,比如good。然后计算like跟good的PMI。
互 信 息 M I 互信息MI MI
点互信息PMI其实就是从信息论里面的互信息这个概念里面衍生出来的。 互信息即:

在这里插入图片描述
其衡量的是两个随机变量之间的相关性,即一个随机变量中包含的关于另一个随机变量的信息量。
可以看出,互信息其实就是对X和Y的所有可能的取值情况的点互信息PMI的加权和。
利 用 互 信 息 进 行 筛 选 特 征 利用互信息进行筛选特征
在这里插入图片描述
s k l e a r n . f e a t u r e s e l e c t i o n . m u t u a l i n f o c l a s s i f sklearn.feature_selection.mutual_info_classif sklearn.featureselection.mutualinfoclassif

from sklearn import datasets
from sklearn.feature_selection import mutual_info_classif
 
iris = datasets.load_iris()
x = iris.data
label = iris.target
 
mutual_info = mutual_info_classif(x, label, discrete_features= False)
print(mutual_info)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

结果为
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/354429
推荐阅读
相关标签
  

闽ICP备14008679号