当前位置: 首页 > news >正文

关于Zipf定律与TF—IDF的一个实践

在这篇文章中,我将通过机器学习中的线性回归来计算zipf定律中一个经验常数alpha,还会画TF-IDF的图像,此外还将简单介绍下与zipf、TF-IDF有关的知识。

在之前的一篇文章中我曾介绍过TF-IDF,但之后我又阅读了Ricardo Baeza-Yates和Berthier Ribeiro-Neto所写的《Modern Information Retrieval》,发现其中所讲述的有关IF-IDF部分的内容与我之前了解的有许多不同,所以便又写了这篇文章。

一、 Zipf定律

1.1 介绍

Zipf's Law 是一种经验观察到的语言现象,它最初是由语言学家 George Kingsley Zipf 在 20 世纪初提出的。虽然 Zipf's Law 主要在语言学领域被讨论,但它也在自然语言处理(Natural Language Processing, NLP)和信息检索(Information Retrieval, IR)等领域得到了广泛应用。在这些领域中,Zipf's Law 被用来研究词汇频率分布,并且在建模文本数据的统计特性方面发挥着重要作用。

1.2 概念

Zipf's Law 描述了词汇的使用频率与其在频率表中的排名之间的关系。按照 Zipf's Law,最常用的词汇出现频率最高,而随着词汇排名的降低,其出现频率也会迅速下降。

1.3 表达式

^{n_{i}}是索引项k_{i}的文档频率。对所有的索引项的文档频率按降序排列,并设n(r)是第r个项的文档频率,那么根据Zipf定律就会有:n(r) \sim r^{-\alpha }

其中,α是经验常数。

那么,我们就可以将之改写为:n(r)=Cr^{-\alpha }

其中的C同样是经验常数。在英语中可以用α=1来提供一种简单的近似,而在中文里,本篇文章正是要去计算它。

在我们先取α等于1等情况下,我们可以对等式左右同时取log,变形为:

logn(r)=logC-logr

其中的log都是以2为底。

在之后还可以变形,这样就得到了IDF的公式:

IDF_{i}=log\frac{N}{n_{i}}

其中的IDFi称为索引项ki的反比文档频率。(关于TF的表达式一会再说)

1.4 python计算

接下来,我就将用python的线性回归模型来计算α在中文中的大小,注意,因为我引用的是一个kaggle中的一个数据集,其规模很大,所以我只在代码中对其进行切片,并只取用一小部分来计算。代码如下:

import jieba
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer'''文本预处理&停用词库'''
data_normal = pd.read_csv(r"C:\Users\20349\Desktop\ArtificialIntelligence\data_set\dataset\chinese_news.csv")
data = data_normal.iloc[:500]
data.dropna(inplace=True)# 删除有缺失值的行
N = len(data)
# 停用词库
with open(r"C:\Users\20349\Desktop\ArtificialIntelligence\wordCloud\stopWords.txt", 'r', encoding='utf-8') as swfile:stopwords = set(line.strip() for line in swfile)
# 文本预处理函数
def preprocess_text(text,stopwords):words = jieba.lcut(text)after_word = [w for w in words if w not in stopwords]# 处理后return ''.join(after_word)
data = data.copy()
for i in range(1,N):data.iloc[i,-1] = preprocess_text(data.iloc[i,-1],stopwords)'''计算alpha'''
word_str = ''.join(data.iloc[:,-1])
word_ls = list(jieba.cut(word_str))
# 统计词频
word_freq_dict = {word: word_ls.count(word) for word in set(word_ls)}
word_freq_df = pd.DataFrame(list(word_freq_dict.items()), columns=['word', 'frequency'])
# 排序
word_freq_df.sort_values(by='frequency', ascending=False, inplace=True)
# 排名与频率
rank = np.arange(1, len(word_freq_df) + 1)
freq = word_freq_df['frequency'].values
# log
log_rank = np.log(rank)
log_freq = np.log(freq)
# 线性回归
model = LinearRegression()
log_rank = log_rank.reshape(-1, 1)  # 转换为二维数组
model.fit(log_rank, log_freq)
# 计算
alpha = -model.coef_[0]
print("Alpha(α) is:{}".format(alpha))

那么,最后输出的α值是这样的:Alpha(α) is:0.9978112574757174

(关于我引用的文本数据集所在的url如下:新闻联播(Chinese official daily news) (kaggle.com))

1.5 代码解释

然后是关于代码的一个解释。

我先给出流程图:

可以看见代码分为两部分,一部分是停用词库的文本预处理,一部分是α的计算,关于预处理方面,我们要做的就是单独拿出每一项中的文本内容然后用jieba函数库的函数进行分词处理并将存在于停用词库中的词语直接忽略,将其余部分再重新组合成字符串写入即可;而在α的计算方面,我们需要获得排序于频率,但此时式子是相除的形式,无法引用线性回归的模型,所以我们需要log化,这样就变为相加的形式了,如此带入模型即可求得结果。

二、 TF-IDF

2.1 概念

TF-IDF(Term Frequency-Inverse Document Frequency)是一种在信息检索与数据挖掘领域中广泛使用的统计方法,用于评估一个词在一个文档或语料库中的重要程度。TF-IDF是两个独立度量的乘积:词频(TF)和逆文档频率(IDF)。

2.2 TF

TF是指词频,意思是某个词在文档中出现的次数。一个词出现得越多,通常意味着它对文档内容越重要。然而,一些非常常见的词汇(如“的”、“是”等)可能频繁出现,但并不具有多少实际意义。因此,词频只是一个局部指标,并不能单独决定一个词的重要性。

其表达式如下:

tf_{i}=\left\{\begin{matrix} 1& + & logf_{i,j}&f_{i,j} >0\\ 0 & & & other \end{matrix}\right.

2.3 IDF

IDF是指逆文档频率,逆文档频率是一个全局性的度量,它考虑了整个文档集或者语料库的情况。一个词如果在整个文档集合中出现的频次越多,那么该词的IDF就越低;反之则越高。通过这种方式,可以降低常见词汇的影响,增加独特或罕见词汇的重要性。

其表达式在刚才Zipf中已经推出。

2.4 TF-IDF

最流行的权重公式就是将IDF因素于词频结合起来的权重计算方法,公式如下:

w_{i,j}=\left\{\begin{matrix} (1 &+ &logf_{i,j} ) &* & log\frac{N}{n_{i}} & f_{i,j}>0\\ 0& & & & & otherwise \end{matrix}\right.

2.5 python计算

代码如下:

# 计算IDF
IDF = {}
for key in total_words_freq.keys():IDF[key] = 0times = 0for i in range(N):if key in contentList[i]:times += 1idf_value = log(N / times, 2)IDF[key] = idf_value# 计算TF-IDF
tf_list = []
idf_list = []
tfidf = []
word_indices = []
number = 1
for key, value in sorted_TF.items():tf_list.append(value)idf_list.append(IDF[key])tfidf.append(value * IDF[key])word_indices.append(number)number += 1# 绘制TF和IDF散点图
X = [log(i+1, 10) for i in range(len(sorted_TF))]
x_index = [0, 1, 2, 3, 4, 5]
labels = [1, 10, 100, 1000, 10000, 100000]plt.figure()
plt.scatter(X, tf_list, color='red', marker='+', label='TF')
plt.scatter(X, idf_list, color='blue', marker='x', label='IDF')
plt.xticks(x_index, labels)
plt.xlabel("Log Word Number")
plt.ylabel("TF or IDF")
plt.legend()
plt.show()# 绘制TF-IDF图
plt.figure()
plt.scatter(X, tfidf, color='black', marker='+', label='TF-IDF')
plt.xticks(x_index, labels)
plt.xlabel("Log Word Number")
plt.ylabel("TF-IDF")
plt.legend()
plt.show()

代码所绘制出的图像为:

 

这两幅图像与书中所给出的用《Wall Street Journal》的文档集绘制的图像极为相似,不过应该是我的数据量远远小于书中这个华尔街日报的数据量的缘故,我的图像略显杂乱,有许多异常的数据点。

此上


http://www.mrgr.cn/news/43763.html

相关文章:

  • 初识微服务
  • 【性能测试】使用JMeter性能工具做测试的基本过程及案例分析
  • 使用指标进行量化交易时,有哪些需要注意的风险点呢
  • 力扣6~10题
  • 大语言模型中文本分割策略的综合指南
  • Day02-MySQL数据库服务体系结构
  • Java 注释新手教程一口气讲完!ヾ(≧▽≦*)o
  • 校企合作必备无人机兴趣班技术详解
  • P10185 [YDOI R1] Necklace
  • Qt开发技巧(十四)文字的分散对齐,设置动态库路径,进度条控件的文本,文件对话框的卡顿,滑块控件的进度颜色,停靠窗体的排列,拖拽事件的坑
  • 2025秋招LLM大模型多模态面试题(九)-- LoRA 面试问题大全:从理论到实践
  • Chromium 搜索引擎功能浅析c++
  • 重生之我们在ES顶端相遇第 20 章 - Mapping 参数设置大全(进阶)
  • 【表达式的值II】
  • 终于有人把多模态大模型讲这么详细了
  • [Python] 轻松入门输出语句与条件语句
  • ElasticSearch 备考 -- Snapshot Restore
  • 《浔川社团官方通报 —— 为何明确 10 月 2 日上线的浔川 AI 翻译 v3.0 再次被告知延迟上线》
  • 教育技术革新:SpringBoot在线教育系统开发
  • 【数学分析笔记】第4章第4节 复合函数求导法则及其应用(3)