TF-IDF算法

简介: TF-IDF(Term Frequency-Inverse Document Frequency, 词频-逆文件频率).

一. 什么是TF-IDF


TF-IDF(Term Frequency-Inverse Document Frequency, 词频-逆文件频率).

是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。


上述引用总结就是, 一个词语在一篇文章中出现次数越多, 同时在所有文档中出现次数越少, 越能够代表该文章.


这也就是TF-IDF的含义.


词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化(一般是词频除以文章总词数), 以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否。)


但是, 需要注意, 一些通用的词语对于主题并没有太大的作用, 反倒是一些出现频率较少的词才能够表达文章的主题, 所以单纯使用是TF不合适的。权重的设计必须满足:一个词预测主题的能力越强,权重越大,反之,权重越小。所有统计的文章中,一些词只是在其中很少几篇文章中出现,那么这样的词对文章的主题的作用很大,这些词的权重应该设计的较大。IDF就是在完成这样的工作.


公式:

image.png

TFw=在某一类中词条w出现的次数该类中所有的词条数目


逆向文件频率 (inverse document frequency, IDF) IDF的主要思想是:如果包含词条t的文档越少, IDF越大,则说明词条具有很好的类别区分能力。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。


公式:

image.png

IDF=log(语料库的文档总数包含词条w的文档数+1),分母之所以要加1,是为了避免分母为0


 某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。


一个语料库有N篇文档,从中随机抽取一篇文档,切词后该文档长度为T(个词),词“data”在该文中出现K次,同时词“data”在整个语料库的1/3的文档中出现过,则词“data”对抽出的这篇文档而言的tfidf为()


该文中出现K次/总次数T * log ( N篇文档/整个语料库的1/3的文档中出现过N/3 )= K * Log(3) / T


正确答案: K * Log(3) / T


二、实践


案例一: 基于TF-IDF的关键词提取

TF-IDF:衡量某个词对文章的重要性由TF和IDF组成


TF:词频(因素:某词在同一文章中出现次数)


IDF:反文档频率(因素:某词是否在不同文章中出现)


TF-IDF = TF*IDF



TF :一个单词在一篇文章出现次数越多越重要


IDF: 每篇文章都出现的单词(如的,你,我,他) ,越不重要



案例二: 相似度计算公式

(1)余弦相似度cosine

 举例:A(1,2,3) B(2,3,4)

         

cosine(A, B) = 分子 / 分母 = 20 / 20.12 =
                分子:A*B = 1*2 + 2*3 + 3*4 = 20
                分母:    ||A||*    ||B|| = 3.74 * 5.38 = 20.12
                            ||A|| = sqrt(A*A) = sqrt(1*1 + 2*2 + 3* 3) = 3.74
                            ||B|| = sqrt(B*B) = sqrt(4*4 + 2*2 + 3* 3) = 5.38

A表示一个句子,B表示另外一个句子            


cosine(A, B) = 表示两个句子的相似程度


(二)Jaccard 相似度:

A 用户(香蕉、苹果、鸭梨)


B 用户(苹果、橘子、桃子)


A∩B=苹果 1


A∪B=香蕉、苹果、鸭梨、橘子、桃子 5


相似度为1/5=0.2


# Step 1 文件整合 把不同文本整合到一起
import os
import sys
import math
file_path_dir = './data'
raw_path = './raw.data'
idf_path = './idf.data'
def read_file_handler(f):
    fd = open(f, 'r', encoding='utf-8')
    return fd
file_raw_out = open(raw_path, 'w', encoding='utf-8')
# 遍历整个原始数据目录,将零散的文章整合到一个文件中,便于后续数据处理
file_name = 0
for fd in os.listdir(file_path_dir):
    file_path = file_path_dir + '/' + fd
    content_list = []
    file_fd = read_file_handler(file_path)
    for line in file_fd:
        content_list.append(line.strip())
    content = '\t'.join([str(file_name), ' '.join(content_list)]) + '\n'
    file_raw_out.writelines(content)    
    file_name += 1
file_raw_out.close()
# Step 2 输出IDF
docs_cnt = file_name
wc_tulist = []
with open(raw_path, 'r', encoding='utf-8') as fd:
    for line in fd:
        # 遍历每一篇文章,文章=line
        ss = line.strip().split('\t')
        if len(ss) != 2:
            continue
        # 对文章的解析,区分出文章的名字和文章的内容   
        file_name, file_content = ss
        # 对文章的内容进行切词,因为内容已经按“ ”空格区分好了,所以直接按空格做split就好
        word_list = file_content.strip().split(' ')
        # 去重:对于idf,只关心词有没有出现在文章中,至于出现多少次,并不关心
        word_set = set(word_list)      
        for word in word_set:
            # 对于每个关键词,打一个标记“1”,来标识该次出现过
            wc_tulist.append((word, '1'))
# 将内容输出到指定目标文件中去
file_idf_out = open(idf_path, 'w', encoding='utf-8')
# 按照词的字典序,进行排序
wc_sort_tulist = sorted(wc_tulist, key=lambda x: x[0])
current_word = None
sum = 0
for tu in wc_sort_tulist:  
    word, val = tu
    if current_word == None:
        current_word = word
    if current_word != word:
        # 通过idf计算公式,得到每个关键词的idf score
        idf = math.log(float(docs_cnt) / (float(sum) + 1.0)) idf公式
        content = '\t'.join([current_word, str(idf)]) + '\n'
        file_idf_out.write(content)
        current_word = word
        sum = 0
    sum += int(val)
idf = math.log(float(docs_cnt) / (float(sum) + 1.0))
content = '\t'.join([current_word, str(idf)]) + '\n'
file_idf_out.write(content)
file_idf_out.close()
# Step 3
input_str = '我们 带来 阿里巴巴 希望 差 我们 我们 我们'
token_idf_dict = {}
# 将idf字典加载到内存
with open(idf_path, 'r', encoding='utf-8') as fd:
    for line in fd:
        ss = line.strip().split('\t')
        if len(ss) != 2:
            continue
        token, idf_score = ss
        token_idf_dict[token] = idf_score
def get_tfidf(input_str):
    token_dict = {}
    # 对输入字符串的每一个词,计算tf
    for t in input_str.strip().split(' '):
        if t not in token_dict:
            token_dict[t] = 1
        else:
            token_dict[t] += 1
    # res_tu_list = []
    for k, v in token_dict.items():
        tf_score = token_dict[k]
        if k not in token_idf_dict:
            continue
        idf_score = token_idf_dict[k]
        tf_idf = tf_score * float(idf_score)
        yield (k, tf_idf)
for k, v in get_tfidf(input_str):
    print(k, v)
求cos
# Step 1: Cosine
input1_str = '我们 带来 阿里巴巴 希望 差 差 差'
# input2_str = '我们 带来 阿里巴巴 好 好 好'
# input2_str = '我们 带来 搜狐 好 好 好'
input2_str = '你们 带来 搜狐 希望 好 好 好'
def cosine(input1_str, input2_str):
    t1_dict = {}
    sum = 0.
    for k, v in get_tfidf(input1_str):
        sum += pow(v, 2)
    sum = math.sqrt(sum)
    for k, v in get_tfidf(input1_str):
        t1_dict[k] = float(v / sum)
    sum = 0.
    for k, v in get_tfidf(input2_str):
        sum += pow(v, 2)
    sum = math.sqrt(sum)
    final_score = 0.
    for k, v in get_tfidf(input2_str):
        if k not in t1_dict:
            continue
        s1 = t1_dict[k]
        s2 = float(v / sum)
        final_score += s1 * s2
    return final_score
print(cosine(input1_str, input2_str))
#用Python手动实现TF-IDF算法
import math
corpus = [
    "what is the weather like today",
    "what is for dinner tonight",
    "this is a question worth pondering",
    "it is a beautiful day today"
]
words = []
# 对corpus分词
for i in corpus:
    words.append(i.split())
# 如果有自定义的停用词典,我们可以用下列方法来分词并去掉停用词
# f = ["is", "the"]
# for i in corpus:
#     all_words = i.split()
#     new_words = []
#     for j in all_words:
#         if j not in f:
#             new_words.append(j)
#     words.append(new_words)
# print(words)
# 进行词频统计
def Counter(word_list):
    wordcount = []
    for i in word_list:
        count = {}
        for j in i:
            if not count.get(j):
                count.update({j: 1})
            elif count.get(j):
                count[j] += 1
        wordcount.append(count)
    return wordcount
wordcount = Counter(words)
# 计算TF(word代表被计算的单词,word_list是被计算单词所在文档分词后的字典)
def tf(word, word_list):
    return word_list.get(word) / sum(word_list.values())
# 统计含有该单词的句子数
def count_sentence(word, wordcount):
    return sum(1 for i in wordcount if i.get(word))
# 计算IDF
def idf(word, wordcount):
    return math.log(len(wordcount) / (count_sentence(word, wordcount) + 1))
# 计算TF-IDF
def tfidf(word, word_list, wordcount):
    return tf(word, word_list) * idf(word, wordcount)
p = 1
for i in wordcount:
    print("part:{}".format(p))
    p = p+1
    for j, k in i.items():
        print("word: {} ---- TF-IDF:{}".format(j, tfidf(j, i, wordcount)))
目录
相关文章
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
"揭秘TF-IDF算法的神奇力量:如何一招制胜,让自然语言处理焕发新生?"
【8月更文挑战第20天】自然语言处理(NLP)是AI的关键领域,旨在使计算机理解人类语言。TF-IDF是一种重要的文本特征提取方法,用于衡量词汇的重要性。算法结合词频(TF)与逆文档频(IDF),强调文档独有词汇。示例代码展示了如何利用Python的scikit-learn库实现TF-IDF,并应用于文本分类任务,通过朴素贝叶斯分类器实现高效分类。此方法广泛应用于信息检索、文本挖掘等领域。
48 0
|
2月前
|
自然语言处理 算法 搜索推荐
NLP中TF-IDF算法
TF-IDF(词频-逆文档频率)是一种用于信息检索与数据挖掘的加权技术,通过评估词语在文档中的重要性来过滤常见词语,保留关键信息。本文介绍了TF-IDF的基本概念、公式及其在Python、NLTK、Sklearn和jieba中的实现方法,并讨论了其优缺点。TF-IWF是TF-IDF的优化版本,通过改进权重计算提高精度。
70 1
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】TF-IDF算法在人工智能方面的应用,附带代码
TF-IDF算法在人工智能领域,特别是自然语言处理(NLP)和信息检索中,被广泛用于特征提取和文本表示。以下是一个使用Python的scikit-learn库实现TF-IDF算法的简单示例,并展示如何将其应用于文本数据。
269 65
|
4月前
|
人工智能 自然语言处理 算法
【人工智能】TF-IDF算法概述
TF-IDF算法,全称Term Frequency-Inverse Document Frequency(词频-逆文档频率),是一种在信息检索和文本挖掘领域广泛应用的加权技术。它通过评估一个词语在文档中的重要程度,来挖掘文章中的关键词,进而用于文本分析、搜索引擎优化等场景。其核心思想是:如果某个词或短语在一篇文章中出现的频率高(TF高),且在其他文章中很少出现(IDF也高),则认为这个词或短语具有很好的类别区分能力,适合用来代表这篇文章的内容。 具体而言,TF-IDF由两部分组成,即词频(TF)和逆文档频率(IDF)。词频(TF)指的是某一个给定的词在该文件中出现的频率。这个数值通常会被归一化
60 3
|
7月前
|
算法
TF-IDF算法是什么呢?
TF-IDF(Term Frequency-Inverse Document Frequency)是一种常用于信息检索和文本挖掘的统计方法,用于评估一个词在文档集或一个语料库中的重要程度。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
|
5月前
|
自然语言处理 算法 搜索推荐
|
7月前
|
自然语言处理 算法
文本分析-使用jieba库实现TF-IDF算法提取关键词
文本分析-使用jieba库实现TF-IDF算法提取关键词
400 1
|
7月前
|
机器学习/深度学习 自然语言处理 算法
基于TF-IDF+KMeans聚类算法构建中文文本分类模型(附案例实战)
基于TF-IDF+KMeans聚类算法构建中文文本分类模型(附案例实战)
588 1
|
7月前
|
机器学习/深度学习 人工智能 自然语言处理
深入理解TF-IDF、BM25算法与BM25变种:揭秘信息检索的核心原理与应用
深入理解TF-IDF、BM25算法与BM25变种:揭秘信息检索的核心原理与应用
|
自然语言处理 算法 搜索推荐
TF-IDF、TextRank关键字抽取排序算法
TF-IDF称为词频逆文本,结果严重依赖文本分词之后的效果。其公式又可以分成词频(Term Frequency,TF)的计算和逆文档概率(IDF)的计算。
179 0