4、文本预处理:中文分词(Jieba)、去停用词、词性标注、命名实体识别

好,咱们进入实战环节的第四步。

前面我们拿到了央行官员的讲话原文,但机器看不懂中文。它只认数字和向量。所以,我们要把一段段中文,拆成机器能理解的最小单元。这个过程,就是文本预处理。

我个人习惯把这一步叫做“洗菜切菜”。菜不洗干净,炒出来一嘴沙子;菜不切好,大厨也没法下锅。咱们做量化分析的,如果文本预处理没做好,后面跑出来的模型结果,你敢信吗?

核心逻辑:原始文本 → 分词 → 去停用词 → 词性标注 → 命名实体识别 → 结构化数据

下面这张图,是我自己画的一个流程。你看一眼,心里就有谱了。

文本预处理核心流程 原始文本 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