4、文本预处理:中文分词(Jieba)、去停用词、词性标注、命名实体识别
好,咱们进入实战环节的第四步。
前面我们拿到了央行官员的讲话原文,但机器看不懂中文。它只认数字和向量。所以,我们要把一段段中文,拆成机器能理解的最小单元。这个过程,就是文本预处理。
我个人习惯把这一步叫做“洗菜切菜”。菜不洗干净,炒出来一嘴沙子;菜不切好,大厨也没法下锅。咱们做量化分析的,如果文本预处理没做好,后面跑出来的模型结果,你敢信吗?
核心逻辑:原始文本 → 分词 → 去停用词 → 词性标注 → 命名实体识别 → 结构化数据
下面这张图,是我自己画的一个流程。你看一眼,心里就有谱了。
4.1 中文分词:Jieba 实战
分词是第一步。英文有空格,中文没有。所以我们必须用算法把句子切开。
我为什么推荐 Jieba?因为它快,而且准确率在金融文本上表现不错。我试过其他几个库,有的在“降准降息”这种词上会切错,Jieba 基本不会。
Jieba 有三种模式:
- 精确模式:最常用。把句子最精确地切开,适合文本分析。
- 全模式:把所有可能的词都扫出来。速度快,但有冗余。
- 搜索引擎模式:在精确模式基础上,对长词再切分。适合搜索引擎用。
咱们做量化分析,用精确模式就够了。看代码:
import jieba
text = "中国人民银行决定下调金融机构存款准备金率"
words = jieba.lcut(text) # 精确模式
print(words)
# 输出:['中国人民银行', '决定', '下调', '金融机构', '存款准备金率']
你看,“中国人民银行”和“存款准备金率”这种专业术语,Jieba 直接识别为一个词。这就是它厉害的地方。
我的小技巧:如果你发现 Jieba 切错了某个金融术语,可以手动添加自定义词典。比如 jieba.add_word("逆周期因子")。我在处理 2019 年央行货币政策报告时,就加了一堆自定义词,效果立竿见影。
4.2 去停用词:扔掉垃圾
分词之后,你会发现一堆“的”、“了”、“是”、“在”这类词。它们对分析没有帮助,反而增加噪声。
去停用词,就是把这些词过滤掉。
我一般会准备两份停用词表:
- 通用停用词表:包含常见的标点符号、语气词、介词等。
- 金融专用停用词表:比如“先生”、“女士”、“尊敬的”这类在央行讲话中频繁出现但无意义的词。
stopwords = set()
with open('stopwords.txt', 'r', encoding='utf-8') as f:
for line in f:
stopwords.add(line.strip())
filtered_words = [w for w in words if w not in stopwords and len(w) > 1]
print(filtered_words)
# 输出:['中国人民银行', '决定', '下调', '金融机构', '存款准备金率']
嗯,这里要注意。我习惯把单字词也过滤掉。因为中文里单字词大多是虚词,比如“将”、“以”、“为”。当然,像“稳”、“好”这种有实际意义的,需要保留。这个得根据你的具体场景调整。
4.3 词性标注:给每个词贴标签
词性标注,就是给每个词标上它是名词、动词还是形容词。
为什么要做这个?因为央行讲话里,动词往往代表政策动作,名词代表政策工具。比如“下调”是动词,“存款准备金率”是名词。你想想看,如果我们能自动识别出“动词+名词”的组合,是不是就能快速定位政策信号?
import jieba.posseg as pseg
words_with_pos = pseg.lcut(text)
for word, flag in words_with_pos:
print(f'{word} -> {flag}')
# 输出:
# 中国人民银行 -> nt
# 决定 -> v
# 下调 -> v
# 金融机构 -> n
# 存款准备金率 -> n
你看,“决定”和“下调”都是动词(v),“存款准备金率”是名词(n)。这个信息在后面做事件抽取时非常有用。
避坑指南:我曾经在分析“稳健的货币政策”时,Jieba 把“稳健”标成了形容词(a),但央行语境下“稳健”其实是一个政策定调,应该作为专有名词处理。所以,词性标注结果不能全信,需要结合业务知识做后处理。
4.4 命名实体识别:抓关键角色
命名实体识别,简称 NER。它的任务是找出文本中的专有名词,比如人名、地名、机构名、时间、数字等。
在央行口头干预分析中,我们最关心三类实体:
- 机构名:中国人民银行、银保监会、证监会
- 人名:易纲、郭树清、刘鹤
- 政策术语:LPR、MLF、SLF、逆回购
我一般用 HanLP 或者 LAC 来做 NER。Jieba 本身不直接支持 NER,但可以结合自定义词典实现类似效果。
# 使用 HanLP 进行命名实体识别
import hanlp
recognizer = hanlp.load(hanlp.pretrained.ner.MSRA_NER_BERT_BASE_ZH)
text = "易纲行长表示,将保持流动性合理充裕"
entities = recognizer(text)
print(entities)
# 输出:[('易纲', 'PERSON', 0, 2), ('流动性', 'MISC', 7, 10)]
你看,“易纲”被识别为人名(PERSON),“流动性”被识别为其他专有名词(MISC)。
实战要点:NER 的准确率高度依赖训练数据。通用模型在金融文本上可能表现一般。我建议你收集 500 篇央行讲话,手动标注实体,然后微调一个专用模型。虽然费时间,但效果提升非常明显。
4.5 完整预处理流水线
最后,我把这四个步骤串成一个函数。以后处理任何央行讲话,直接调用就行。
def preprocess_text(text):
# 1. 分词
words = jieba.lcut(text)
# 2. 去停用词
stopwords = set()
with open('stopwords.txt', 'r', encoding='utf-8') as f:
for line in f:
stopwords.add(line.strip())
words = [w for w in words if w not in stopwords and len(w) > 1]
# 3. 词性标注
words_with_pos = [(w, flag) for w, flag in pseg.lcut(' '.join(words))]
# 4. 命名实体识别(这里用 HanLP 示例)
entities = recognizer(text)
return {
'words': words,
'pos_tags': words_with_pos,
'entities': entities
}
# 测试
result = preprocess_text("中国人民银行决定下调金融机构存款准备金率")
print(result)
这个流水线,我用了三年。从 2018 年贸易战期间的央行表态分析,到 2020 年疫情后的货币政策跟踪,再到 2022 年汇率波动的口头干预识别,它一直是我的主力工具。
说白了,文本预处理没有太多花哨的东西。就是四个步骤,反复打磨。你做得越细致,后面的模型就越省心。
最后提醒一句:预处理的结果一定要人工抽检。我每处理 1000 篇文本,会随机抽 50 篇看一遍。发现问题,马上调整词典或停用词表。这个习惯,帮我避免了好几次重大失误。
公众号:蓝海资料掘金营,微信deep3321