揭秘TF-IDF:如何从文本中提取关键信息

🔍 ​一、TF-IDF的核心思想

TF-IDF(Term Frequency-Inverse Document Frequency)是一种评估词语在文档集合中重要性的统计方法

。其核心逻辑基于两点:

  1. 词频(TF)​​:词在单篇文档中出现的频率越高,对该文档的代表性越强。
  2. 逆文档频率(IDF)​​:词在整个语料库中出现的文档越少,其区分不同文档的能力越强。

💡 ​简单来说​:​高频且稀有的词是文档的“关键词”(如技术术语),而“的”、“是”等高频常见词因IDF值低被过滤。


📊 ​二、算法原理与公式拆解

1. ​词频(TF)的计算

衡量词 t 在文档 d 中的局部重要性,通常进行归一化防止长文档主导结果

例如:文档 “苹果手机 苹果电脑” 中,“苹果”的TF = 2/3≈0.67。

2. ​逆文档频率(IDF)的计算

评估词 t 的全局稀缺性,​惩罚常见词​(如停用词)

加1平滑​:防止 nt​=0 时分母为零。若“苹果”在1000篇文档中出现20次,则IDF = log(1000/21)≈1.67。

3. ​TF-IDF的合成

将TF与IDF相乘,得到词的最终权重

上例中,“苹果”的TF-IDF = 0.67×1.67≈1.12。


🛠️三、API接口参数

方法作用调用时机
fit(raw_documents)学习词汇表和 IDF 值(不返回矩阵)仅需训练词汇表时使用
transform(raw_documents)将文本转换为 TF-IDF 矩阵(需先调用 fit处理测试集或新数据时使用
fit_transform(raw_documents)一步完成词汇表学习和矩阵生成最常用,训练阶段直接使用
get_feature_names_out()获取有序特征词列表(按列索引排列)查看词汇表或分析特征时使用
get_params()获取当前参数配置调试或保存配置时使用

💻 ​四、Python实现示例

使用sklearn库快速计算TF-IDF矩阵:

from sklearn.feature_extraction.text import TfidfVectorizer

# 文档集示例
documents = [
    "苹果手机 苹果电脑", 
    "华为手机 华为平板",
    "小米手机 小米手环"
]


vectorizer = TfidfVectorizer()  
tfidf_matrix = vectorizer.fit_transform(documents)

# 输出词表及TF-IDF矩阵
print("特征词列表:", vectorizer.get_feature_names_out())
print("TF-IDF矩阵:\n", tfidf_matrix.toarray())

输出说明​:

  • 每行对应一个文档的TF-IDF向量。(其中第几个表示特征表的第几个值)
  • 每列对应一个特征词(如“华为”、“苹果”)。
  • 值越高,表示该词对当前文档越重要 ✅。

💻 ​五、实战演练

下面我们来实现一个红楼梦书籍的重要词提取,这直接我们要进行数据处理。

初始我们的数据集就是一本数,全部内容在一个txt中。下面是步骤:

根据您提供的图片,我已准确识别并提取所有文字内容。以下是图片中的完整文字信息,严格按原始结构和步骤呈现:


步骤:​

  1. 处理数据集成标准格式
            a. 根据段落特征把文章进行分篇
            b. 把每篇的内容变成一行,然后放在一个文件中

  2. jjiaba分词

                a 导入红楼们专属的jieba词库

                b jieba分词,并且把早停词去除

        3 ​进行模型训练
                a. 训练模型
                b. 展示参数

代码展示

文章分卷
import os.path
import time

wz=open('红楼梦.txt','r',encoding='utf-8')

file=open('.\红楼梦卷\开头.txt','w',encoding='utf-8')
i=10
for line in wz:
    if '卷 第'in line:
        file.close()
        name=line.strip() + '.txt'
        path=os.path.join('.\红楼梦卷',name)
        file = open(path,'w',encoding='utf-8')
        i=0
    if i<=3:
        i=i+1
        continue
    file.write(line)
file.close()

#把数据处理成,要求的样子
import os.path


jg=open("结果.txt","w",encoding="utf-8")
a=os.walk("红楼梦卷")
print(a)
for root,dirs,files in a:
    for filename in files:
        jg.write(filename)
        path=os.path.join(root,filename)
        # print(path)
        file=open(path,encoding="utf-8")
        for line in file.readlines():
            line=line.strip()
            jg.write(line)
        jg.write("\n")
jg.close()

#jieba分词,并且去除
import pandas as pd
import jieba

stopwords=pd.read_table('StopwordsCN.txt',encoding='utf-8')
print(stopwords)

ck=open('红楼梦词库.txt',encoding='utf-8')
# print(ck.read())
jieba.load_userdict(ck)

file=open('结果.txt',encoding='utf-8')
a=jieba.lcut(file.read())
# print(a)

file1=open('结果1.txt','w',encoding='utf-8')
for i in a:
    if i in stopwords.values or i==' ':
        continue
    content=i+' '
    file1.write(content)
file1.close()


from sklearn.feature_extraction.text import TfidfVectorizer
model=TfidfVectorizer()
data=open('结果1.txt',encoding='utf-8')
jg=model.fit_transform(data)
# print(jg)
wordlist=model.get_feature_names_out()
print(wordlist)
import pandas as pd
df=pd.DataFrame(jg.T.todense(),index=wordlist)
print(df)
# featurelist = df.iloc[:,5].tolist()
# print(featurelist)
for i in range(120):
    series = df.iloc[:,i]
    sorted_series =series.sort_values(ascending=False)
    gjc = sorted_series.head(10)
    print('第{}回的核心关键词是:'.format(i+1),list(gjc.items()))

代码详解:

1 、分卷处理:按章节分割原始文本​ 
import os.path
import time

wz = open('红楼梦.txt', 'r', encoding='utf-8')  # 打开原始文本
file = open('.\红楼梦卷\开头.txt', 'w', encoding='utf-8')  # 临时文件,后续被覆盖
i = 10  # 初始跳过行数计数器

for line in wz:
    if '卷 第' in line:  # 检测章节标题(如"卷 第一回")
        file.close()  # 关闭当前章节文件
        name = line.strip() + '.txt'  # 用章节标题命名新文件(如"卷 第一回.txt")
        path = os.path.join('.\红楼梦卷', name)  # 构建文件路径
        file = open(path, 'w', encoding='utf-8')  # 创建新章节文件
        i = 0  # 重置行计数器,准备跳过卷头
    if i <= 3:  # 跳过卷头的前4行(标题行+3行冗余内容)
        i = i + 1
        continue
    file.write(line)  # 将有效内容写入当前章节文件
file.close()  # 关闭最后一个章节文件

关键逻辑​:

  1. 章节检测​:通过关键词 卷 第 识别新章节起始位置。
  2. 文件管理​:
    • 每检测到新章节,关闭旧文件并创建以章节标题命名的新文件(如 卷 第一回.txt)。
    • 跳过章节头部的冗余行(通过 i<=3 控制跳过4行)。
  3. 目录结构​:所有分卷文件保存在 红楼梦卷 文件夹中。

​2、数据整合:合并分卷内容为单行格式​ 
import os.path

jg = open("结果.txt", "w", encoding="utf-8")
a = os.walk("红楼梦卷")  # 遍历分卷文件目录

for root, dirs, files in a:
    for filename in files:
        jg.write(filename)  # 写入文件名(如"卷 第一回.txt")
        path = os.path.join(root, filename)
        file = open(path, encoding="utf-8")
        for line in file.readlines():
            line = line.strip()  # 去除每行首尾空白符
            jg.write(line)  # 将每卷内容压缩为单行
        jg.write("\n")  # 卷间用换行分隔
jg.close()

关键逻辑​:

  1. 文件遍历​:os.walk 获取 红楼梦卷 下所有分卷文件。
  2. 单行压缩​:
    • 每卷内容去除换行符和首尾空格,合并为单行字符串。
    • 各卷以文件名 + 压缩内容的形式写入 结果.txt,卷间用换行符分隔。
  3. 输出格式示例​:
    卷 第一回.txt 甄士隐梦幻识通灵 贾雨村风尘怀闺秀...
    卷 第二回.txt 贾夫人仙逝扬州城 冷子兴演说荣国府...

​3、分词与停用词清洗​ 
import pandas as pd
import jieba

# 加载停用词表(每行一个词)
stopwords = pd.read_table('StopwordsCN.txt', encoding='utf-8')  # 格式:["的", "了", "是"]

# 加载自定义词库(如"林黛玉"、"荣国府"等专有名词)
ck = open('红楼梦词库.txt', encoding='utf-8')
jieba.load_userdict(ck)  # 提升专有名词分词准确性

# 读取压缩后的文本并分词
file = open('结果.txt', encoding='utf-8')
a = jieba.lcut(file.read())  # 精确模式分词

# 清洗停用词和空格
file1 = open('结果1.txt', 'w', encoding='utf-8')
for i in a:
    if i in stopwords.values or i == ' ':  # 过滤停用词和空格
        continue
    content = i + ' '  # 用空格分隔有效词
    file1.write(content)
file1.close()

关键逻辑​:

  1. 停用词过滤​:使用中文停用词表(如"的"、"了")移除无意义词。
  2. 自定义词典​:通过 红楼梦词库.txt 添加专有名词,避免错误拆分(如"林黛玉"不被拆为"林"和"黛玉")。
  3. 分词策略​:jieba.lcut 采用精确模式,适合后续TF-IDF分析。
  4. 输出格式​:清洗后的文本以空格分隔词语(如甄士隐 通灵 贾雨村...)。

​4、TF-IDF关键词提取​ 
from sklearn.feature_extraction.text import TfidfVectorizer

# 初始化TF-IDF模型
model = TfidfVectorizer()
data = open('结果1.txt', encoding='utf-8')  # 注:此处需按行读取文档列表
#这里data已经转化为标准形式了,直接训练就行!
# 训练模型并转换数据
jg = model.fit_transform(data)  # 生成稀疏矩阵(文档数×词汇数)
wordlist = model.get_feature_names_out()  # 获取词汇表(如['甄士隐', '通灵', ...])

# 转换为DataFrame便于分析
import pandas as pd
df = pd.DataFrame(jg.T.todense(), index=wordlist)  # 转置后:行=词汇,列=文档

# 提取每卷(文档)的Top10关键词
for i in range(120):  # 假设共120卷
    series = df.iloc[:, i]  # 取第i卷的TF-IDF向量
    sorted_series = series.sort_values(ascending=False)  # 按权重降序排序
    gjc = sorted_series.head(10)  # 取权重最高的前10个词
    print(f'第{i+1}回的核心关键词是:', list(gjc.items()))  # 输出(词,权重)列表
  1. DataFrame设计​:
    • 常规用法:行=文档,列=词汇 → 直接对每行取Top10关键词。
    • 修正​:
      df = pd.DataFrame(jg.todense(), columns=wordlist)  # 行=文档,列=词汇
      for i in range(df.shape[0]):
          series = df.iloc[i]  # 取第i个文档
          sorted_series = series.sort_values(ascending=False)
          gjc = sorted_series.head(10)
  2. TF-IDF参数优化​:
    • 可添加 stop_words 参数二次过滤停用词,或设置 ngram_range=(1,2) 捕获词组(如"荣国府")。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值