TF-IDF算法

一、简介

TF-IDF(Term Frequency-inverse Document Frequency)是一种针对关键词的统计分析方法,用于评估一个词对一个文件或语料库的重要程度。一个词的重要程度跟它在文中出现的次数成正比,跟它在语料库中出现的次数成反比。这种计算方法能有效避免常用词对关键词的影响程度,提高关键词与文章之间的相关性。

TF-IDF算法的主要思想:如果一个词在某一篇文章中出现的频率TF高,而在其他文章中很少出现,就认为该词具有很好的类别分类能力,可用于分类。

二、词频(TF)

词频(TF):表示词条在文本中出现的频率
公式:
在这里插入图片描述
其中ni,j是该词在文件dj中出现的次数,分母是文件dj中所有词汇出现的次数总和,即:
在这里插入图片描述

三、逆向文件频率(IDF)

逆向文件频率(IDF):由文件总数目除以包含该词语的文件数,再将得到的商取对数得到。表示包含某个词条的文档数越少,IDF越大,说明该词条有很好的类别区分能力。
公式:
在这里插入图片描述
为了避免分母为0,需要加1.

四、python3实现TF-IDF算法

import math
import operator
from collections import defaultdict

def loadDataSet():
    """
    fuction:创建数据样本
    :return:
    dataset:实验样本切分的词条
    classVec:类别标签向量
    """
    dataset = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],  # 切分的词条
               ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
               ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
               ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
               ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
               ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0, 1, 0, 1, 0, 1]  # 类别标签向量,1代表好,0代表不好
    return dataset, classVec


def feature_select(list_words):
    """
    function:TF-IDF算法
    :param list_words:词列表
    :return:dict_feature_select:特征选择词典
    """
    # 总词频统计
    doc_frequency = defaultdict(int)
    for word_list in list_words:
        for i in word_list:
            doc_frequency[i] += 1

    # TF
    word_tf = {}
    for i in doc_frequency:
        word_tf[i] = doc_frequency[i] / sum(doc_frequency.values())

    # 计算每个词的IDF值
    doc_num = len(list_words)
    word_idf = {}  # 存储每个词的idf值
    word_doc = defaultdict(int)  # 存储包含该词的文档数
    for i in doc_frequency:
        for j in list_words:
            if i in j:
                word_doc[i] += 1
    for i in doc_frequency:
        word_idf[i] = math.log(doc_num / (word_doc[i] + 1))

    # 计算每个词的TF*IDF的值
    word_tf_idf = {}
    for i in doc_frequency:
        word_tf_idf[i] = word_tf[i] * word_idf[i]

    # 对字典按值由大到小排序
    dict_feature_select = sorted(word_tf_idf.items(), key=operator.itemgetter(1), reverse=True)
    return dict_feature_select

if __name__ == "__main__":
    data_list, label_list = loadDataSet()  # 加载数据
    features = feature_select(data_list)  # 所有词的TF-IDF值
    print(features)
    print(len(features))

运行结果:
在这里插入图片描述

五、Sklearn实现TF-IDF算法

# 导入需要的包
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

x_train = ['TF-IDF 主要 思想 是','算法 一个 重要 特点 可以 脱离 语料库 背景',
           '如果 一个 网页 被 很多 其他 网页 链接 说明 网页 重要']
x_test=['原始 文本 进行 标记','主要 思想']
 
#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
vectorizer = CountVectorizer(max_features=10)
#该类会统计每个词语的tf-idf权值
tf_idf_transformer = TfidfTransformer()
#将文本转为词频矩阵并计算tf-idf
tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
x_train_weight = tf_idf.toarray()
 
#对测试集进行tf-idf权重计算
tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
x_test_weight = tf_idf.toarray()  # 测试集TF-IDF权重矩阵
 
print('输出x_train文本向量:')
print(x_train_weight)
print('输出x_test文本向量:')
print(x_test_weight)

输出结果:
在这里插入图片描述
补充:
CountVectorizer
CountVectorizer 是文本特征提取方法,对于每一个训练样本,它只考虑每种词汇在训练文本中出现的频率。将文本中的词语转换为词频矩阵,通过fit_transform函数计算各个词语出现的次数。

参数详解

CountVectorizer(
    input='content',
    encoding='utf-8',
    decode_error='strict',
    strip_accents=None,
    lowercase=True,
    preprocessor=None,
    tokenizer=None,
    stop_words=None,
    token_pattern='(?u)\\b\\w\\w+\\b',
    ngram_range=(1, 1),
    analyzer='word',
    max_df=1.0,
    min_df=1,
    max_features=None,
    vocabulary=None,
    binary=False,
    dtype=<class 'numpy.int64'>,
)

一般要设置的参数是:ngram_range,max_df,min_df,max_features等,具体情况具体分析

参数表作用
input一般使用默认即可,可以设置为"filename’或’file’
encodeing使用默认的utf-8即可,分析器将会以utf-8解码raw document
decode_error默认为strict,遇到不能解码的字符将报UnicodeDecodeError错误,设为ignore将会忽略解码错误,还可以设为replace,作用尚不明确
strip_accents默认为None,可设为ascii或unicode,将使用ascii或unicode编码在预处理步骤去除raw document中的重音符号
analyzer一般使用默认,可设置为string类型,如’word’, ‘char’, ‘char_wb’,还可设置为callable类型,比如函数是一个callable类型
preprocessor设为None或callable类型
tokenizer设为None或callable类型
ngram_range词组切分的长度范围
stop_words设置停用词,设为english将使用内置的英语停用词,设为一个list可自定义停用词,设为None不使用停用词,设为None且max_df∈[0.7, 1.0)将自动根据当前的语料库建立停用词表
lowercase将所有字符变成小写
token_pattern过滤规则,表示token的正则表达式,需要设置analyzer == ‘word’,默认的正则表达式选择2个及以上的字母或数字作为token,标点符号默认当作token分隔符,而不会被当作token
max_df可以设置为范围在[0.0 1.0]的float,也可以设置为没有范围限制的int,默认为1.0。这个参数的作用是作为一个阈值,当构造语料库的关键词集的时候,如果某个词的document frequence大于max_df,这个词不会被当作关键词。如果这个参数是float,则表示词出现的次数与语料库文档数的百分比,如果是int,则表示词出现的次数。如果参数中已经给定了vocabulary,则这个参数无效
min_df类似于max_df,不同之处在于如果某个词的document frequence小于min_df,则这个词不会被当作关键词
max_features默认为None,可设为int,对所有关键词的term frequency进行降序排序,只取前max_features个作为关键词集
vocabulary默认为None,自动从输入文档中构建关键词集,也可以是一个字典或可迭代对象?
binary默认为False,一个关键词在一篇文档中可能出现n次,如果binary=True,非零的n将全部置为1,这对需要布尔值输入的离散概率模型的有用的
dtype使用CountVectorizer类的fit_transform()或transform()将得到一个文档词频矩阵,dtype可以设置这个矩阵的数值类型
属性表作用
vocabulary_词汇表;字典型
get_feature_names()所有文本的词汇;列表型
stop_words_返回停用词表
方法表作用
fit_transform(X)拟合模型,并返回文本矩阵
fit(raw_documents[, y])Learn a vocabulary dictionary of all tokens in the raw documents.
fit_transform(raw_documents[, y])Learn the vocabulary dictionary and return term-document matrix.
  • 用数据输入形式为列表,列表元素为代表文章的字符串,一个字符串代表一篇文章,字符串是已经分割好的。CountVectorizer同样适用于中文;
  • CountVectorizer是通过fit_transform函数将文本中的词语转换为词频矩阵,矩阵元素a[i][j]表示j词在第i个文本下的词频。即各个词语出现的次数,通过get_feature_names()可看到所有文本的关键字,通过toarray()可看到词频矩阵的结果。
# "dog cat fish" 为输入列表元素,即代表一个文章的字符串
texts=["dog cat fish","dog cat cat","fish bird", 'bird'] 
cv = CountVectorizer() # 创建词袋数据结构
cv_fit=cv.fit_transform(texts)
# 等价于
#cv.fit(texts)
#cv_fit=cv.transform(texts)

print(cv.get_feature_names())
#### result ####
['bird', 'cat', 'dog', 'fish']

print(cv.vocabulary_)
#### result ####
{'dog': 2, 'cat': 1, 'fish': 3, 'bird': 0}

print(cv_fit)
# (0,3) 1  表示第0个列表元素,索引为3的元素即fish出现了一次
#### result ####
(0, 3)	1
(0, 1)	1
(0, 2)	1
(1, 1)	2
(1, 2)	1
(2, 0)	1
(2, 3)	1
(3, 0)	1

print(cv_fit.toarray())
#.toarray() 是将结果转化为稀疏矩阵矩阵的表示方式
# a[i][j] 表示第j个词在第i个文本下的词频
#### result ####
[[0 1 1 1]
 [0 2 1 0]
 [1 0 0 1]
 [1 0 0 0]]

print(cv_fit.toarray().sum(axis=0))  #每个词在所有文档中的词频
#### result ####
[2 3 2 2]

CountVectorizer 结合 TfidfTransformer
TfidfTransformer用于统计vectorizer中每个词语的TF-IDF值。

from sklearn.feature_extraction.text import TfidfTransformer
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(cv_fit)
print(tfidf)
tfidf.toarray()
#### result ####
 (0, 3)	0.5773502691896257
 (0, 2)	0.5773502691896257
 (0, 1)	0.5773502691896257
 (1, 2)	0.4472135954999579
 (1, 1)	0.8944271909999159
 (2, 3)	0.7071067811865475
 (2, 0)	0.7071067811865475
 (3, 0)	1.0
  
array([[0.        , 0.57735027, 0.57735027, 0.57735027],
       [0.        , 0.89442719, 0.4472136 , 0.        ],
       [0.70710678, 0.        , 0.        , 0.70710678],
       [1.        , 0.        , 0.        , 0.        ]])

TfidfVectorizer
将原始文档的集合转化为tf-idf特性的矩阵,相当于CountVectorizer配合TfidfTransformer使用的效果。
即TfidfVectorizer类将CountVectorizer和TfidfTransformer类封装在一起。

from sklearn.feature_extraction.text import TfidfVectorizer

texts=["dog cat fish","dog cat cat","fish bird", 'bird'] 
tv = TfidfVectorizer()
X_description = tv.fit_transform(texts)
print(X_description.toarray())
#### result ####
[[0.         0.57735027 0.57735027 0.57735027]
 [0.         0.89442719 0.4472136  0.        ]
 [0.70710678 0.         0.         0.70710678]
 [1.         0.         0.         0.        ]]

参考链接:
https://blog.csdn.net/asialee_bird/article/details/81486700
https://zhuanlan.zhihu.com/p/94446764
https://www.cnblogs.com/pinard/p/6693230.html

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页