藏语自然语言处理入门 - 3 找关键词

主题:用 TF-IDF 找"关键词",顺手挑"关键句"

这一课要做什么?

  1. sentences.txt(一行一句)继续用 Botok 分词;
  2. TF-IDF 给词打"信息量分",捞出关键词Top
  3. 给每句加总一个分数,挑出关键句Top(可当小摘要参考)。

做完你会得到:

  • tfidf_keywords_top50.csv:全局关键词Top50;
  • key_sentences.txt:关键句Top10(句子+分数);
  • tfidf_terms_full.csv:所有词的平均TF-IDF分(备用分析)。

一、什么是"TF-IDF"

  • TF(Term Frequency):这个词在"当前这句/段"里出现几次?出现越多,越重要。
  • IDF(Inverse Document Frequency):这个词在"整份语料"里稀不稀有?越稀有越重要(到处都有就不重要)。
  • TF × IDF = TF-IDF 分数:分数越高,越像"关键词"。

小例子(藏语氛围):

  • ནས་ 这类功能词几乎句句都有 → IDF≈0 → 再高的 TF 也乘成 0 → 不是关键词
  • བོད་ཡིགསློབ་ཚན 这种"内容词"并非处处都有 → IDF>0 → 有机会成关键词。

关键点:先分词靠谱 (用 Botok),再配停用词表(把"粘合词"剔除),TF-IDF 才更准。


二、开箱即用脚本

确保已安装依赖:

bash 复制代码
pip install botok pandas regex scikit-learn

把下面保存为 tfidf_keywords_and_summary.py,跟 sentences.txt 放一起:

python 复制代码
# tfidf_keywords_and_summary.py
# 输入:
#   sentences.txt                ------ 一行一句
#   stopwords.txt(可选)          ------ 你修订后的停用词
#   stopwords_suggest.txt(兜底)  ------ 第二课生成的候选停用词
# 输出:
#   tfidf_keywords_top50.csv     ------ 关键词Top50(term, score)
#   key_sentences.txt            ------ 关键句Top10(含分数)
#   tfidf_terms_full.csv         ------ 全量词平均TF-IDF(备用)

from pathlib import Path
import pandas as pd
import regex as re
from botok import WordTokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np

SENTS_FILE = "sentences.txt"
STOP_FINAL = Path("stopwords.txt")
STOP_SUGG  = Path("stopwords_suggest.txt")

# 1) 读句子
sents = [s.strip() for s in Path(SENTS_FILE).read_text(encoding="utf-8").splitlines() if s.strip()]
if not sents:
    raise SystemExit("❌ sentences.txt 为空,请先完成第1/2课。")

# 2) 停用词(优先用你修订后的)
if STOP_FINAL.exists():
    stopwords = {w.strip() for w in STOP_FINAL.read_text(encoding="utf-8").splitlines() if w.strip()}
elif STOP_SUGG.exists():
    stopwords = {w.strip() for w in STOP_SUGG.read_text(encoding="utf-8").splitlines() if w.strip()}
else:
    stopwords = set()
print(f"🧹 停用词载入:{len(stopwords)} 个")

# 3) 分词:句子 → token 列表(过滤句末符与停用词)→ 用空格连接
wt = WordTokenizer()
def tokenize(sent: str):
    toks = [t.text for t in wt.tokenize(sent) if t.text and t.text.strip()]
    toks = [t for t in toks if not re.fullmatch(r"[།༎]+", t) and t not in stopwords]
    return toks

seg_sents = [" ".join(tokenize(s)) for s in sents]

# 4) TF-IDF:我们已经自己用空格切好词,所以 token_pattern 设"非空格"
vectorizer = TfidfVectorizer(
    token_pattern=r"[^ ]+",
    lowercase=False,         # 藏文无大小写
    use_idf=True,
    smooth_idf=True,         # 防止分母为0
    sublinear_tf=True        # TF取对数,弱化重复词
)
X = vectorizer.fit_transform(seg_sents)   # [句子数 × 词表大小]
terms = vectorizer.get_feature_names_out()

# 5) 全局关键词Top:按"每个词在所有句子的平均TF-IDF"排序
tfidf_mean = np.asarray(X.mean(axis=0)).ravel()
df_terms = pd.DataFrame({"term": terms, "tfidf_mean": tfidf_mean}).sort_values("tfidf_mean", ascending=False)

topN = min(50, len(df_terms))
df_terms.head(topN).to_csv("tfidf_keywords_top50.csv", index=False, encoding="utf-8")
df_terms.to_csv("tfidf_terms_full.csv", index=False, encoding="utf-8")
print(f"✅ tfidf_keywords_top50.csv(Top {topN})已生成")

# 6) 关键句:把每句的 TF-IDF 向量沿词维度求和 = 句子"信息量分"
sent_scores = X.sum(axis=1).A.ravel()
rank = np.argsort(-sent_scores)
topK = min(10, len(sents))
lines = [f"[Top{i+1}] score={sent_scores[idx]:.4f}\n{sents[idx]}\n" for i, idx in enumerate(rank[:topK])]
Path("key_sentences.txt").write_text("\n".join(lines), encoding="utf-8")
print(f"✅ key_sentences.txt(Top {topK})已生成")

三、跑一下!

bash 复制代码
python tfidf_keywords_and_summary.py

如何读结果?

  • 打开 tfidf_keywords_top50.csv:前10个词大多就是"这组句子的主题词"。
  • 打开 key_sentences.txt:Top 关键句念一遍,像不像摘要?不满意就扩充/清洗语料或完善停用词再跑。

四、分析

  • 为什么TF-IDF能找关键词?

    因为它同时看这句里多不多(TF)全库里稀不稀有(IDF);"处处都有"的词(功能词)IDF≈0,自然会被压下去。

  • 为什么先做停用词?

    把"粘合词"先过滤,关键词就更干净(ན་/ནས་/ལ་/དང་/ཀྱི་/... 这类)。

  • 为什么要先分词?

    不分词,机器只能按字符或固定长度切片,不符合藏语习惯,TF-IDF分会偏。

  • 关键句怎么来的?

    "把这一句里的词分数加起来",谁的总分高,谁更代表主题(简单好用的基线)。


五、30秒自检清单

  • 关键词Top里还有明显的功能词?→ 补到 stopwords.txt 再跑一次。
  • 关键句Top读起来不像摘要?→ 文本太短/主题太杂/停用词不全,逐步改进。
  • 分词怪怪的?→ 回第1课检查清洗是否到位(括注/页码/装饰符未清掉会干扰)。

六、10分钟小任务

任务A(必做) :把 tfidf_keywords_top50.csv 里你不认可的词加入 stopwords.txt;再跑脚本,观察Top是否更"像话"。
任务B(可选) :把 key_sentences.txt Top3 贴到讲义封面,当"本段要点"。
任务C(进阶):把语料按章节切两份,分别跑一遍,比较两个章节的 Top 关键词差异。


相关推荐
Java与Android技术栈2 小时前
AI Coding 让我两天完成图像编辑器 Monica 的国际化与多主题
人工智能
wwwzhouhui2 小时前
85-dify案例分享-不用等 OpenAI 邀请,Dify+Sora2工作流实测:写实动漫视频随手做,插件+教程全送
人工智能·音视频·sora2
Testopia3 小时前
AI与敏捷开发管理系列3:敏捷方法在AI项目中的应用案例
人工智能·ai编程·敏捷流程·#人工智能学习
倔强青铜三3 小时前
苦练Python第61天:logging模块——让Python日志“有迹可循”的瑞士军刀
人工智能·python·面试
Testopia3 小时前
AI与敏捷开发管理1:传统方法失灵?人工智能项目的新法则
人工智能·项目管理·敏捷开发·敏捷流程
倔强青铜三3 小时前
苦练Python第60天:json模块——让Python和JSON“无缝互译”的神兵利器
人工智能·python·面试
Ivanqhz3 小时前
LR算法中反向最右推导(Reverse RightMost Derivation)
人工智能·算法
whltaoin4 小时前
AI 超级智能体全栈项目阶段四:学术分析 AI 项目 RAG 落地指南:基于 Spring AI 的本地与阿里云知识库实践
人工智能·spring·阿里云·向量数据库·rag
sheji34164 小时前
【开题答辩全过程】以 Web数据挖掘在电子商务中的应用研究为例,包含答辩的问题和答案
前端·人工智能·数据挖掘