3、文本预处理实战:中文分词(Jieba)、去停用词、词干提取与词形还原

好,咱们直接进入正题。文本预处理,说白了就是把那些乱七八糟的新闻文本,变成机器能理解的干净数据。这一步做不好,后面再牛的模型也是白搭。我刚开始做量化因子的时候,就吃过这个亏——数据没洗干净,回测曲线漂亮得不行,实盘一跑直接崩了。

今天咱们要搞定的,是中文文本预处理的四个核心步骤:分词、去停用词、词干提取、词形还原。其中分词和去停用词是中文特有的,词干提取和词形还原更多用在英文场景,但咱们做新闻情绪因子,偶尔也会碰到中英文混杂的情况,所以一并讲了。

3.1 中文分词:Jieba 实战

中文不像英文,词与词之间没有空格。所以第一步,就是把连续的汉字序列切分成有意义的词语。这个活儿,业内最常用的就是 Jieba 分词库。

我个人习惯用 Jieba 的精确模式,它最适合做文本分析。全模式虽然快,但会输出所有可能的词,冗余太多。搜索引擎模式更不用说了,那是给搜索引擎用的。

核心要点: Jieba 有三种模式——精确模式、全模式、搜索引擎模式。做新闻情绪因子,只用精确模式。

3.1.1 安装与基本使用

# 安装
pip install jieba

# 基本使用
import jieba

text = "今日A股市场迎来大幅上涨,北向资金净流入超过百亿元。"
seg_list = jieba.cut(text, cut_all=False)  # 精确模式
print(" / ".join(seg_list))
# 输出:今日 / A股 / 市场 / 迎来 / 大幅 / 上涨 / , / 北向 / 资金 / 净流入 / 超过 / 百亿元 / 。

你看,Jieba 把「北向资金」切成了一个词,把「百亿元」也正确识别了。这背后是它的词典在起作用。但有些专业术语,比如「量化宽松」,默认词典可能没有,这时候就需要自定义词典。

我的经验: 做新闻情绪因子,一定要加金融领域的自定义词典。我曾经因为没加「降准」「逆回购」这些词,导致情绪打分完全偏离。你想想看,一篇说「央行降准」的新闻,如果被切成了「央行」「降」「准」,情绪就变成中性了,多离谱。

3.1.2 自定义词典

# 加载自定义词典
jieba.load_userdict("finance_dict.txt")

# finance_dict.txt 内容示例:
# 量化宽松 5
# 逆回购 3
# 北向资金 5
# 降准 3

text = "央行宣布实施量化宽松政策,同时进行逆回购操作。"
seg_list = jieba.cut(text)
print(" / ".join(seg_list))
# 输出:央行 / 宣布 / 实施 / 量化宽松 / 政策 / , / 同时 / 进行 / 逆回购 / 操作 / 。

嗯,这里要注意:自定义词典的格式是「词语 词频 词性」。词频越高,Jieba 越倾向于把它当作一个词。我一般给金融术语设 3-5 的词频,够用了。

3.2 去停用词:把噪音扔掉

分词之后,你会发现有很多「的」「了」「是」「在」这类词。它们对情绪分析毫无贡献,反而会干扰模型。去停用词,就是把这些无意义的词过滤掉。

我建议准备两份停用词表:一份是通用的中文停用词表(网上很多),另一份是金融领域专用的。比如「报告」「公告」「显示」这类词,在新闻里频繁出现,但对情绪没有指示作用。

避坑指南: 我曾经把「不」「没有」这类否定词也加进了停用词表,结果情绪分析完全失效。你想想,「业绩不达预期」去掉「不」之后,就变成了「业绩达预期」,情绪从负面变成了正面。所以,否定词绝对不能去!
# 加载停用词表
stopwords = set()
with open("stopwords.txt", "r", encoding="utf-8") as f:
    for line in f:
        stopwords.add(line.strip())

# 去停用词
def remove_stopwords(words):
    return [w for w in words if w not in stopwords and len(w) > 1]

text = "今日A股市场迎来大幅上涨,北向资金净流入超过百亿元。"
seg_list = jieba.cut(text)
filtered_words = remove_stopwords(seg_list)
print(filtered_words)
# 输出:['A股', '市场', '迎来', '大幅', '上涨', '北向', '资金', '净流入', '超过', '百亿元']

你看,「今日」「,」「。」都被去掉了。剩下的词,基本就是情绪分析的核心素材了。

3.3 词干提取与词形还原

这两个概念,主要针对英文。中文没有词形变化,所以一般用不到。但咱们做量化,新闻里经常夹杂英文术语,比如「earnings」「earned」「earning」,它们其实都是同一个词根「earn」。这时候就需要做词干提取或词形还原。

词干提取:简单粗暴,直接砍掉词缀。比如「running」变成「run」,「flies」变成「fli」。速度快,但结果可能不是合法单词。

词形还原:更智能,会考虑词性,还原成词典里的原形。比如「better」还原成「good」,「ran」还原成「run」。准确率高,但速度慢。

我个人建议:做新闻情绪因子,用 词形还原。因为情绪词典里都是原形词,比如「good」「bad」「increase」。如果你用词干提取,把「increased」变成「increas」,情绪词典就匹配不上了。

# 使用 NLTK 进行词形还原
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet

lemmatizer = WordNetLemmatizer()

# 需要指定词性,否则默认是名词
words = ["earnings", "earned", "earning", "increased", "increasing"]
for w in words:
    # 先判断词性,这里简化处理
    lemma = lemmatizer.lemmatize(w, pos='v')  # 假设都是动词
    print(f"{w} -> {lemma}")
# 输出:
# earnings -> earnings  (名词,没变)
# earned -> earn
# earning -> earn
# increased -> increase
# increasing -> increase
我的习惯: 我会先判断单词的词性,再决定是否做词形还原。比如「earnings」是名词,表示「收益」,不需要还原。而「earned」是动词过去式,需要还原成「earn」。这一步虽然麻烦,但能提升情绪匹配的准确率。

3.4 完整预处理流程

好了,咱们把上面三步串起来,形成一个完整的预处理流水线。我画了一张流程图,方便你理解整个逻辑。

新闻文本预处理流程 原始新闻文本 中文分词(Jieba) 去停用词 词形还原(英文) 干净文本 → 情绪分析 关键说明 • 中文分词:精确模式 • 自定义金融词典 • 保留否定词 • 英文词形还原 • 过滤单字词 输出结果示例: ['A股','市场','迎来', '大幅','上涨','北向', '资金','净流入', '超过','百亿元']

这个流程看起来简单,但实际项目中坑不少。我总结了一个表格,把常见问题和解决方案列出来,你直接拿去用。

步骤 常见问题 解决方案
中文分词 金融术语被错误切分 加载自定义金融词典,词频设为3-5
去停用词 误删否定词,导致情绪反转 停用词表中排除「不」「没」「无」等否定词
词形还原 英文术语匹配不上情绪词典 先判断词性,再选择是否还原
整体流程 处理速度慢,影响实盘 使用多进程并行处理,或预加载词典
核心总结: 文本预处理是新闻情绪因子的地基。分词用 Jieba 精确模式 + 自定义金融词典;去停用词要保留否定词;英文部分做词形还原。这三步做好,你的情绪因子就成功了一半。

好了,这一章的内容就到这里。下一章咱们会讲如何构建情绪词典,以及如何给新闻文本打情绪分。到时候我会分享一个我自己踩过的坑——情绪词典的权重设置,差点让我回测数据全废了。


蓝海数据掘金营,专注资料整理