藏语自然语言处理入门 - 2 分词
本课目标:分词 + 词频统计 + 停用词候选
本课要做的三件小事
- 用 Botok 把句子切成“词”。
- 统计每个词出现了几次,导出表格。
- 粗筛一批“停用词”(像“的、了、在”这种功能词)。
做完你会得到三个文件:
tokens.csv
:一行一个“词”(带句子编号、在句子里的位置)。freq_top50.csv
:出现次数最多的前 50 个词。stopwords_suggest.txt
:停用词。
0. 开始前(1 分钟)
先装三个包(本地或 Colab 都行):
pip install botok pandas regex
botok
负责分词,pandas
负责做表格,regex
备用。
1. 我们需要的输入(1 分钟)
上节我们已经有:
cleaned.txt
(干净文本)sentences.txt
(一行一句)
这一课直接用
sentences.txt
,因为一行一句更好定位每个词属于哪句。
2. 一段“分词+词频”的可直接运行脚本(8–10 分钟)
把下面代码保存为 tokenize_and_freq.py
,和 sentences.txt
放在同一目录下运行即可。
# tokenize_and_freq.py
# 用法:
# python tokenize_and_freq.py
# 产出:
# tokens.csv —— 分词明细(句ID、词在句中的索引、token)
# freq_top50.csv —— 词频Top50
# stopwords_suggest.txt —— 停用词候选(简单启发式)from botok import WordTokenizer
from pathlib import Path
import pandas as pd
import regex as re
from collections import CounterSENTS_FILE = "sentences.txt"# 1) 读取句子
sents = Path(SENTS_FILE).read_text(encoding="utf-8").splitlines()
sents = [s.strip() for s in sents if s.strip()] # 去空行# 2) 初始化分词器(首次会准备资源)
wt = WordTokenizer()def tokenize_sentence(sent: str):# botok.tokenize 返回 token 对象;这里只取 .texttoks = [t.text for t in wt.tokenize(sent) if t.text and t.text.strip()]return toks# 3) 对每句分词,记录(句ID、词序号、token)
rows = []
for sid, sent in enumerate(sents, start=1):toks = tokenize_sentence(sent)for idx, tok in enumerate(toks, start=1):rows.append({"sent_id": sid, "tok_idx": idx, "token": tok})df_tokens = pd.DataFrame(rows)
df_tokens.to_csv("tokens.csv", index=False, encoding="utf-8")
print("✅ 已输出 tokens.csv,大小:", df_tokens.shape)# 4) 词频统计(不区分大小写;藏文一般不涉及大小写)
# 这里简单排除纯句末符号(།/༎)和全空白
def is_noise(tok: str) -> bool:# 只包含句末符或空白 → 认为是噪声return bool(re.fullmatch(r"[།༎]+", tok)) or (tok.strip() == "")freq = Counter(tok for tok in df_tokens["token"] if not is_noise(tok))
top50 = pd.DataFrame(freq.most_common(50), columns=["token", "count"])
top50.to_csv("freq_top50.csv", index=False, encoding="utf-8")
print("✅ 已输出 freq_top50.csv")# 5) 停用词候选(非常粗的启发式版本)
# 思路:高频 & 很短(<=2字符) & 非标点;你也可以手动加一些已知功能词
stop_candidates = [t for t, c in freq.items() if len(t) <= 2 and not is_noise(t)]
# 也可以补充一批常见功能词(按实际语料再调整)
manual_add = ["ནས་", "ན་", "ལ་", "དང་", "ཡི་", "གི་", "ཀྱི་", "ལས་", "མི་", "ཚོ་"]
stop_set = sorted(set(stop_candidates + manual_add))Path("stopwords_suggest.txt").write_text("\n".join(stop_set), encoding="utf-8")
print("✅ 已输出 stopwords_suggest.txt(候选数量:", len(stop_set), ")")
读者版讲解(一句话就够):
WordTokenizer()
:就是“切词刀”。tokens.csv
:把每个词都落成一行,后面随时能查“第几句第几个词”。freq_top50.csv
:最常出现的 50 个词,帮你摸清文本“口味”。stopwords_suggest.txt
:一份“可能无关紧要”的词清单,下一课提取关键词时会用得到。
3. 跑一下!(2–3 分钟)
执行:
python tokenize_and_freq.py
看终端提示,会生成三个文件:tokens.csv
、freq_top50.csv
、stopwords_suggest.txt
。
用表格工具或随便打印几行看看,确认分词结果合你的直觉。
4. 快速自检(1 分钟)
tokens.csv
里是否出现了单独的།
/༎
?(作为“词”出现没问题,但我们在词频里剔除了它)freq_top50.csv
的前几名是否大多是功能词?这很正常。stopwords_suggest.txt
有没有明显“不该进”的词?可以删掉。
5. 小任务(10 分钟)
任务A(必做):
把 stopwords_suggest.txt
里你不认同的词删掉,再加上你觉得多余的词,得到你的自定义停用词表 stopwords.txt
。
任务B(可选):
做一个小查询:输入一个词,打印它出现的所有句子(句ID + 句子内容),方便课堂展示“例句”。
提示代码:
from pathlib import Path
import pandas as pddf_tok = pd.read_csv("tokens.csv")
sents = Path("sentences.txt").read_text(encoding="utf-8").splitlines()def concordance(term, top=10):rows = df_tok[df_tok["token"] == term]["sent_id"].unique().tolist()for sid in rows[:top]:print(f"[句{sid}] {sents[sid-1]}")concordance("བོད་ཡིག") # 示例
6. 常见小坑(快速排雷)
- 分词“看着怪”? 多半是原文没清干净。回到第1课,把
cleaned.txt
和sentences.txt
再确认一遍。 - 功能词太多,盖住主题词? 就是要这样先看“原貌”。下一课我们会引入停用词表 + TF-IDF,把主题词“捞”出来。
- Botok 太慢? 首次用会准备资源,后续就快了;文本很大时可以分批处理。
7. 本课产出
- ✅
tokens.csv
(句ID、词序号、词) - ✅
freq_top50.csv
(高频词) - ✅
stopwords_suggest.txt
(候选停用词,等人工修订)