第三章 金融文本预处理(上):中文分词技术
做金融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
- 停用词过滤要谨慎,别把金融术语过滤掉
- 自定义词典是提升分词准确率最有效的方法
- 编码问题一定要先处理,不然后面全是乱码
好了,这一章就到这里。下一章我们会讲文本向量化,把分词后的结果变成模型能理解的数字。到时候见。
公众号:蓝海资料掘金营,微信deep3321