词嵌入金融文本:用向量空间把公告语义变成可计算因子
情感词典(利好词 +1、利空词 −1)有个致命短板:它只认得你手工列进去的词。市场天天造新词——『超预期』你收录了,明天出现『扩产』『中标』你没收录,词典对它们视而不见,直接算 0。词嵌入用 skip-gram 从公告语料里学出每个词的向量,语义相近的词自动挨在一起,于是词典外的新词也能被『情绪轴』投影出方向。合成实验:4000 条公告、三类语义(利好/利空/中性),纯 numpy 负采样 skip-gram 训练后同类词余弦 0.981 vs 异类 0.896;构造情绪因子做 IC 检验——在含词典内词的公告上嵌入因子 IC 0.607 与词典计数 0.574 基本打平,但在『全是词典外新词』的留出集上,词典计数 IC 直接归零(0.000),嵌入因子仍有 0.602。附向量可视化、维度敏感性与五类真实陷阱(中阶)。
先说结论:情感词典只认得你手工列进去的词,而市场天天造新词——词典外的表达它一律算 0,直接漏掉。词嵌入把每个词学成一个向量,语义相近的词自动挨在一起,于是词典没收录的新词也能被『情绪方向』投影出来。 本文合成实验:4000 条公告、三类语义(利好/利空/中性),纯 numpy 训练 skip-gram 后同类词余弦相似度 0.981 远高于异类 0.896。关键对比在留出集上:面对全部由词典外新词组成的公告,词典计数法 IC 直接归零(0.000),而嵌入因子仍有 0.602——这就是向量空间的泛化能力。

一、问题:词典是死的,语言是活的#
量化里处理文本情绪,最朴素的办法是情感词典:维护一张表,“增长、超预期、回购”记 +1,“亏损、减持、诉讼”记 −1,一篇公告的情绪分就是正词数减负词数。简单、可解释、算得快。
但它有个绕不过去的死穴:它对没收录的词完全失明。 你词典里有”超预期”,某天研报写”业绩大幅扩产、新签订单饱满”——“扩产""订单”你没收录,这篇明明强烈利好的公告,词典给它打 0 分。语言在演化、行业黑话在更新、同一个意思有几十种说法,而手工词典永远追不上。你以为你在做情绪分析,其实只在数几个固定关键词出现了几次。
词嵌入换了个根本思路:不靠人工列词表,而是让模型从海量文本里自己学出『哪些词意思相近』。 学出来的不是标签,是每个词的一个稠密向量。语义相近的词,向量也相近。这样一来,哪怕”扩产”从没被你标注过,只要它在语料里和”增长""超预期”经常出现在相似的上下文,它的向量就会落在利好词一堆里,自然被情绪轴投影成正向。
二、原理:用上下文定义词义#
词嵌入的哲学根基是分布假说(Firth 1957):“一个词的意义,由它周围经常出现的词决定。” “增长”和”扩产”如果总是出现在相似的邻居中间(同样跟着”订单""业绩""超预期”),那它们语义就相近,向量就该接近。
word2vec 的 skip-gram 把这句话变成一个可优化目标:用中心词去预测它窗口内的上下文词。 训练完成后,那个”用来预测”的中心词向量矩阵,就是我们要的词嵌入。
直接对整个词表做 softmax 太贵(每步要归一化几万个词),实践用负采样近似:对每个真实的 (中心词, 上下文词) 正样本,随机抽几个不相关的词当负样本,目标变成”让正样本点积大、负样本点积小”:
其中 是中心词向量, 是真实上下文词, 是负采样词, 是 sigmoid。负样本按词频的 0.75 次方抽样——这个指数是 word2vec 原论文的经验值,作用是既不让高频词(“的""公告”)霸占负样本,也不让极低频词几乎不被抽到。
三、纯 numpy 实现#
三个部件:负采样表、前向的 sigmoid 打分、反向的梯度更新。核心就是对每个训练对,更新中心词向量和它对应的正/负上下文词向量。
import numpy as np
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-np.clip(x, -30, 30)))
# 负采样表:词频^0.75 归一化
neg_p = counts ** 0.75
neg_p /= neg_p.sum()
Win = rng.normal(0, 0.1, (V, D)) # 中心词(输入)向量 —— 最终要的嵌入
Wout = rng.normal(0, 0.1, (V, D)) # 上下文(输出)向量
for c, o in training_pairs: # c=中心词, o=真实上下文词
negs = rng.choice(V, size=n_neg, p=neg_p) # 抽 K 个负样本
vc = Win[c]
# 正样本:希望 sigmoid(vc·v_o) -> 1
s_pos = sigmoid(vc @ Wout[o]); g_pos = s_pos - 1.0
# 负样本:希望 sigmoid(vc·v_neg) -> 0
s_neg = sigmoid(vc @ Wout[negs].T); g_neg = s_neg
# 梯度
grad_c = g_pos * Wout[o] + (g_neg[:, None] * Wout[negs]).sum(0)
Wout[o] -= lr * g_pos * vc
Wout[negs] -= lr * g_neg[:, None] * vc
Win[c] -= lr * grad_cpython训练完对 Win 做行归一化,就得到可以直接算余弦相似度的词嵌入。构造语料时用了三个语义主题,每个主题一套高共现词汇,主题间只有 8% 的词汇泄漏——这模拟了真实公告里”利好用词扎堆、利空用词扎堆”的结构。
四、结果一:语义相近的词自动聚成簇#
训练后把 16 维嵌入做 PCA 投到二维(就是封面图),利好、利空、中性三类词各自聚成一团,泾渭分明——模型从没见过这些标签,纯粹靠”谁和谁在相似上下文里出现”就把它们分了开。
量化上更严格的检验是同类词对 vs 异类词对的余弦相似度分布:

同类词对平均余弦 0.981,异类词对 0.896,两个分布明显分离。这个”同类高、异类低”的间隔,就是后面能把词典外新词投影出方向的物理基础——新词只要落在某类词堆里,它跟这类的余弦就高。
五、结果二:词典外新词,才是嵌入真正的战场#
这是全文最值钱的实验。我把每类词汇拆成两半:
- 词典内词(前 5 个):分析师手工收录进情感词典的;
- 词典外新词(后 5 个):模型学过(在语料里出现过),但从没被写进词典的新表达。
情绪轴只用词典内词构造(),模拟”分析师只能给自己认识的词打标签”。然后分两种公告检验预测力(IC,因子与公告后收益的相关):

- 混合用词公告(含词典内词):嵌入因子 IC 0.607,词典计数 0.574——基本打平。当词典能覆盖到词时,两种方法差不多,词典甚至因为规则硬、无噪声还略稳。
- 纯新词公告(全是词典外新词):词典计数 IC 暴跌到 0.000——它一个词都不认识,全篇打 0,因子成了常数,彻底失去区分度;而嵌入因子 IC 仍有 0.602,几乎没掉。
右图直观展示:即便这些公告用的全是词典没有的新词,嵌入情绪投影值越高,公告后收益的分组均值仍单调上升。原因就是那 0.981 vs 0.896 的间隔——新词”扩产”在向量空间里紧挨着词典内的”增长""超预期”,情绪轴投影自然把它识别成利好。词典法的天花板是它的词表大小,嵌入法的天花板是语料的覆盖广度,后者高一个量级。
六、维度怎么选#
嵌入维度 是要调的超参。用”同类均值余弦 − 异类均值余弦”这个分离间隔来衡量质量:

时间隔只有 0.055——维度太低,向量塞不下三类的区分信息,被迫挤在一起。 升到 816 间隔涨到约 0.10 并趋于平台,再往上(32、64)不再改善甚至略降。结论:维度不是越大越好,够用即止。 真实语料词表几万、语义关系复杂,工业界常用 100300 维;但盲目堆到上千维只会增加过拟合和计算成本,不会带来成比例的语义质量提升。
七、五类真实陷阱#
陷阱一:把余弦相似度当因果或情感强度。 嵌入学的是”共现相似”,不是”情感极性”。“利好”和”利空”这对反义词,因为经常出现在同类公告的相似位置(都在讲业绩),余弦可能不低。要提取情感方向必须像本文那样显式构造情绪轴(正词均值减负词均值),不能直接拿两个词的余弦当情绪。
陷阱二:语义相近不等于会同向变动。 嵌入告诉你”扩产”和”增长”语义近,不告诉你它们对应的股票会同涨同跌。从词向量到收益预测,中间隔着一整套”语义→事件→基本面→价格”的传导,每一步都会衰减和引入噪声。本文 IC 0.6 是合成数据的理想值,真实公告文本的情绪因子 IC 通常在 0.02~0.05 量级。
陷阱三:训练语料的时间泄漏。 这是文本因子最容易翻车的地方:用全样本语料训练嵌入,再回测早期时段,等于让早期的模型偷看了未来的语言分布(新词、新说法)。严谨做法是嵌入训练窗口严格早于回测窗口,滚动更新,绝不能一次训练用到底。
陷阱四:文档向量用简单平均会丢结构。 本文把公告向量取词向量均值——简单但会抹掉词序和否定。“不及预期”里的”预期”是正词,“不及”是负词,平均下来可能互相抵消甚至判成中性。真实系统需要处理否定词、程度副词,或改用能建模词序的模型。
陷阱五:中文分词是隐藏的前置误差源。 英文空格分词,中文得先分词。“超预期”被错分成”超”+“预期”,或”业绩预亏”被分成”业绩”+“预亏”还是”业绩预”+“亏”,直接决定了词表和共现统计。分词错了,后面再好的嵌入都是建在沙子上。本文用的是预定义词表规避了这个问题,实盘里它往往是最大的误差来源。
小结#
词嵌入相对情感词典的核心优势,不是”更准”,而是泛化——它把离散的、封闭的词表,换成了连续的、开放的语义空间。词典法的能力边界是你列了多少词,嵌入法的能力边界是语料覆盖了多少语言现象。当市场用词稳定、词典覆盖充分时,两者差不多;但一旦遇到新词、黑话、同义变体(这在真实公告里是常态),词典法会系统性失明,而嵌入法凭借”新词自动落进语义邻域”继续工作。代价是它需要足够语料、需要防时间泄漏、且从语义相似到收益预测中间还有很长的、会大幅衰减的传导链——它是一个强大的特征工程工具,不是印钞机。