藏语自然语言处理入门 - 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 关键词差异。


相关推荐
Highcharts.js10 分钟前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
apple_6926588516 分钟前
基于 Qwen-Image-2.1 的人物替换 LoRA 模型及部署工作流 人物替换的效果 吊打闭源
人工智能·计算机视觉
甲维斯21 分钟前
绝了!Codex找苹果客服解决Claude订阅问题!
人工智能
斗象科技24 分钟前
斗象入选上海市“AI+制造“服务商能力图谱·AI安全服务商
人工智能·安全·制造
明志数科30 分钟前
工业采集数据的计量口径分层与可复算质检设计
人工智能·机器人
qq_252941316839 分钟前
日本道路病害检测数据集 | 道路病害 裂缝检测 坑洼识别 市政巡检9287期
人工智能·深度学习·yolo·目标检测·计算机视觉·道路检测
yumengxt40 分钟前
「屿梦星途GEO」系列 · 每日AI资讯解读
人工智能
Qianxueban1 小时前
如果卷积核大小固定,步长固定,那经过i次卷积,它一个像素的感受野是多大?
人工智能·深度学习·计算机视觉
拆房老料1 小时前
DeepSeek Super-agent 架构解析:从单任务 Agent 到持续运行的任务系统
人工智能·设计模式·系统架构
民乐团扒谱机1 小时前
【一文吃透】机器学习 Embedding 降维打击:从底层空间几何原理到 RAG 向量检索工程实战避坑
人工智能·机器学习·embedding