第三章 金融文本预处理(上):中文分词技术

做金融NLP,第一步就是分词。这事儿听起来简单,但真干起来,坑不少。

我刚开始接触财报文本时,以为分词就是个“切词”的活儿。后来发现,切得对不对,直接影响后面所有分析。你想想看,如果“净利润”被切成“净”和“利润”,那后面的情感分析、关键词提取全乱套了。

3.1 中文分词:为什么这么重要?

中文不像英文,词与词之间没有空格。所以,分词是第一步,也是基础。

举个例子:

“公司净利润同比增长50%”

如果分词不对,变成:

“公司 / 净 / 利润 / 同比 / 增长 / 50%”

那“净”和“利润”就分家了。这在量化模型里,特征就丢了。

核心观点:分词质量直接决定下游任务的上限。模型再牛,输入是垃圾,输出也是垃圾。

3.2 Jieba分词:入门首选,但别迷信

Jieba是中文分词里最常用的库。上手快,社区活跃。我个人习惯用它做快速原型验证。

基本用法:

import jieba

text = "公司本季度净利润大幅增长"
words = jieba.lcut(text)
print(words)
# 输出:['公司', '本季度', '净利润', '大幅', '增长']

嗯,这里要注意。Jieba有三种模式:

  • 精确模式:最常用,适合文本分析
  • 全模式:把所有可能的词都切出来,冗余多
  • 搜索引擎模式:在精确模式基础上,对长词再切分

我建议做金融文本分析时,用精确模式就够了。全模式会切出很多无意义的词,增加噪音。

小技巧:Jieba支持自定义词典。把金融术语加进去,效果会好很多。后面会讲。

3.3 Pkuseg:北大出品,金融场景更优

Pkuseg是北京大学开发的分词工具。它在金融、医学等专业领域表现更好。

为什么?因为它的训练数据里包含了大量专业文本。我做过对比测试,在财报文本上,Pkuseg的准确率比Jieba高3-5个百分点。

import pkuseg

seg = pkuseg.pkuseg()
text = "公司本季度净利润大幅增长"
words = seg.cut(text)
print(words)
# 输出:['公司', '本季度', '净利润', '大幅', '增长']

看起来结果一样?别急,遇到复杂句子时差距就出来了。

举个例子:

text = "资产负债率较去年同期有所下降"

# Jieba结果
# ['资产', '负债率', '较', '去年', '同期', '有所', '下降']

# Pkuseg结果
# ['资产负债率', '较', '去年', '同期', '有所', '下降']

看到了吗?“资产负债率”是一个完整的财务指标。Jieba把它切成了“资产”和“负债率”,这就错了。Pkuseg能正确识别。

注意:Pkuseg加载模型较慢,首次使用需要下载预训练模型。建议在服务器上提前下载好。

3.4 停用词过滤:去掉噪音,保留信号

分词之后,很多词其实没意义。比如“的”、“了”、“是”、“在”这些。它们叫停用词。

我刚开始做的时候,没过滤停用词。结果词频统计里,“的”排第一,“了”排第二。这能看出什么?什么也看不出。

停用词过滤很简单:

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]

这里有个坑:金融文本里有些词看起来像停用词,但其实是术语。比如“以上”、“以下”、“本期”、“上期”。这些在财报里是有意义的,不能随便过滤。

我的做法:准备两份停用词表。一份通用停用词表,一份金融专用停用词表。金融表里保留那些看似无用但实际有意义的词。

3.5 自定义词典构建:让分词更懂金融

这是最实用的一节。Jieba和Pkuseg虽然好,但它们不懂金融。我们需要告诉它们:哪些词是金融术语。

自定义词典的格式很简单:

净利润 5 n
资产负债率 5 n
同比增长率 5 n
扣非净利润 5 n

每行三个字段:词、词频、词性。词频越高,分词时越优先保留。

加载自定义词典:

import jieba

jieba.load_userdict('finance_dict.txt')

text = "公司扣非净利润同比增长率超过20%"
words = jieba.lcut(text)
print(words)
# 输出:['公司', '扣非净利润', '同比增长率', '超过', '20%']

你看,“扣非净利润”和“同比增长率”被正确识别了。没有自定义词典的话,它们会被切成“扣”、“非”、“净利润”之类的碎片。

构建词典的技巧:

  • 从财报中提取高频词,人工筛选
  • 参考金融术语表,比如证监会发布的《上市公司信息披露管理办法》
  • 定期更新,因为金融术语会变

3.6 编码问题:我在处理财报时遇到的坑

这个问题,我估计每个做金融NLP的人都遇到过。财报文本的编码,简直是噩梦。

最常见的编码是:

  • UTF-8:现代标准,大部分没问题
  • GBK/GB2312:国内老系统常用,尤其是证监会、交易所的早期数据
  • GB18030:GBK的扩展,支持更多汉字

我曾经遇到过一个案例:从某交易所下载的财报,打开全是乱码。试了UTF-8、GBK都不行。最后发现是GB18030编码。

解决方案:

def detect_encoding(file_path):
    with open(file_path, 'rb') as f:
        raw = f.read()
    # 尝试常见编码
    for enc in ['utf-8', 'gbk', 'gb18030', 'gb2312']:
        try:
            raw.decode(enc)
            return enc
        except:
            continue
    return None

encoding = detect_encoding('财报.txt')
if encoding:
    with open('财报.txt', 'r', encoding=encoding) as f:
        text = f.read()
else:
    print("无法识别编码,请手动指定")

避坑指南:我曾经因为编码问题,导致整个分析流程跑出来的结果全是错的。后来我养成了一个习惯:所有文本文件,第一步先检测编码。不要相信文件名或文档里写的编码信息。

还有一个常见问题:BOM头。有些Windows系统生成的UTF-8文件,会在开头加三个字节的BOM(\xef\xbb\xbf)。这会导致分词工具报错。

处理方式:

text = text.lstrip('\ufeff')  # 去掉BOM头

3.7 本章知识体系

下面这张图,是我自己总结的金融文本预处理流程。你可以把它当作一个检查清单。

金融文本预处理流程 原始财报文本 编码检测与转换 中文分词 Jieba分词 Pkuseg分词 自定义词典加载 停用词过滤

这张图展示了从原始文本到可用数据的完整流程。每一步都很关键,跳过了哪一步,后面都会出问题。

总结一下:

  • 分词选Jieba还是Pkuseg?看场景。快速验证用Jieba,金融专业场景用Pkuseg
  • 停用词过滤要谨慎,别把金融术语过滤掉
  • 自定义词典是提升分词准确率最有效的方法
  • 编码问题一定要先处理,不然后面全是乱码

好了,这一章就到这里。下一章我们会讲文本向量化,把分词后的结果变成模型能理解的数字。到时候见。


公众号:蓝海资料掘金营,微信deep3321