关于TF-IDF算法

关于TF-IDF算法

TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术。
TF-IDF是一种统计方法,用以评估字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF-IDF的主要思想是:如果某个单词在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

(1)TF(Term Frequency)词频

词频(TF)表示词条(关键词)在一个文本中出现的频率。计算公式为:
在这里插入图片描述

其中表示单词在文档中的出现次数,分母表示文档中所有单词出现的次数之和。通俗理解为:
在这里插入图片描述

(2)IDF(Inverse Document Frequency)逆向文档频率

逆向文件频率 (IDF) :某一特定词语的IDF,可以由总文件数目除以包含该词语的文件的数目,再将得到的商取对数得到。如果包含单词的文档越少, IDF越大,则说明词条具有很好的类别区分能力。计算公式为:
在这里插入图片描述

其中|D|表示所有文档数,分母表示包含单词的所有文档数。通俗理解为(加1防止分母为0):
在这里插入图片描述
对IDF的理解:语料库的文档总数实际上是一个词分布的可能性大小,n篇文档,有n种可能。包含词的文档数m,表示词的真实分布有m个“可能”。那么log(n/m) = log(n) - log(m)就可以表示词在m篇文档中的出现,导致的词分布可能性的减少(即信息增益),这个值越小,表示词分布越散,我们认为一个词越集中出现在某一类文档,它对这类文档的分类越有贡献,那么当一个词分布太散了,那他对文档归类的作用也不那么大了。

(3)TF-IDF实际是TF*IDF

在这里插入图片描述

举例

给定3篇文档 ,“今天 上 NLP 课程”,“今天 的 课程 有 意思”,“数据 课程 也 有 意思”。计算TF-IDF值

# -*- coding: utf-8 -*-
from collections import defaultdict
import math
import operator
 
"""
函数说明:创建数据样本
Returns:
    dataset - 实验样本切分的词条
    classVec - 类别标签向量
"""
def loadDataSet():
    dataset = [ ['今天','上','NLP','课程'],    # 切分的词条
                   ['今天','的','课程','有','意思'],
                   ['数据','课程','也' ,'有','意思'],
                   ]
    return dataset
 
 
"""
函数说明:特征选择TF-IDF算法
Parameters:
     list_words:词列表
Returns:
     dict_feature_select:特征选择词字典
"""
def feature_select(list_words):
    #总词频统计
    doc_frequency=defaultdict(int)
    for word_list in list_words:
        for i in word_list:
            doc_frequency[i]+=1
            
    # 计算每个文档中每个词的TF值
    word_tf = {}
    index = 0
    doc_num = len(list_words)
    for i in range(doc_num):
        word_tf[i] = {}
    for word_list in list_words:
        doc_frequency_single = defaultdict(int)
        for i in word_list:
            doc_frequency_single[i] += 1
        for i in doc_frequency_single:
            word_tf[index][i] = doc_frequency_single[i] / sum(doc_frequency_single.values())
        index += 1
 
 
    #计算每个词的IDF值
    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 range(doc_num):
        word_tf_idf[i] = {} 
    index=0
    for word_list in list_words:
        doc_frequency_single = defaultdict(int)
        for i in word_list:
            doc_frequency_single[i] += 1
        for i in doc_frequency_single:
            word_tf_idf[index][i]=word_tf[index][i]*word_idf[i]
        index+=1
    
    return word_tf_idf
 
if __name__=='__main__':
    data_list=loadDataSet() #加载数据
    features=feature_select(data_list) #所有词的TF-IDF值
    print(features)

运行结果为:

{0: {'今天': 0.0, '上': 0.1013662770270411, 'NLP': 0.1013662770270411, '课程': -0.07192051811294523}, 1: {'今天': 0.0, '的': 0.08109302162163289, '课程': -0.05753641449035618, '有': 0.0, '意思': 0.0}, 2: {'数据': 0.08109302162163289, '课程': -0.05753641449035618, '也': 0.08109302162163289, '有': 0.0, '意思': 0.0}}

本代码基于博文提供的例题和代码修改。

posted @ 2022-11-13 21:53  pengchen  阅读(95)  评论(0编辑  收藏  举报