Python 机器学习算法交易实用指南(五)(2)https://developer.aliyun.com/article/1523711
使用 Doc2vec 进行情感分析
文本分类需要组合多个词嵌入。一个常见的方法是对文档中每个词的嵌入向量进行平均。这使用所有嵌入的信息,并有效地使用向量加法来到达嵌入空间中的不同位置。但是,有关单词顺序的相关信息会丢失。
相比之下,用于生成文本片段(如段落或产品评论)的嵌入的最先进模型是使用文档嵌入模型Doc2vec
。这个模型是 Word2vec 作者在发布其原创贡献后不久开发的。
与 Word2vec 类似,Doc2vec
也有两种类型:
- 分布式词袋(DBOW)模型对应于 Word2vec 的 CBOW 模型。文档向量是通过训练网络在预测目标词的合成任务中产生的,该任务基于上下文词向量和文档的文档向量。
- 分布式记忆(DM)模型对应于 Word2vec Skip-Gram 架构。通过训练神经网络来预测目标单词,使用整个文档的文档向量。
Gensim 的 Doc2vec
类实现了这种算法。
在 Yelp 情感数据上训练 Doc2vec
我们使用 500,000 条 Yelp 评论(参见第十三章,处理文本数据)的随机样本,以及它们的相关星级评分(参见 notebook yelp_sentiment
):
df = (pd.read_parquet('yelp_reviews.parquet', engine='fastparquet') .loc[:, ['stars', 'text']]) stars = range(1, 6) sample = pd.concat([df[df.stars==s].sample(n=100000) for s in stars])
我们使用简单的预处理来删除停用词和标点符号,使用 NLTK
的分词器并删除少于 10 个标记的评论:
import nltk nltk.download('stopwords') from nltk import RegexpTokenizer from nltk.corpus import stopwords tokenizer = RegexpTokenizer(r'\w+') stopword_set = set(stopwords.words('english')) def clean(review): tokens = tokenizer.tokenize(review) return ' '.join([t for t in tokens if t not in stopword_set]) sample.text = sample.text.str.lower().apply(clean) sample = sample[sample.text.str.split().str.len()>10]
创建输入数据
gensim.models.doc2vec
类以 TaggedDocument
格式处理文档,其中包含标记化的文档以及允许在训练后访问文档向量的唯一标记:
sentences = [] for i, (_, text) in enumerate(sample.values): sentences.append(TaggedDocument(words=text.split(), tags=[i]))
训练界面与 word2vec
类似,但有额外的参数来指定 Doc2vec 算法:
model = Doc2vec(documents=sentences, dm=1, # algorithm: use distributed memory dm_concat=0, # 1: concat, not sum/avg context vectors dbow_words=0, # 1: train word vectors, 0: only doc vectors alpha=0.025, # initial learning rate size=300, window=5, min_count=10, epochs=5, negative=5) model.save('test.model')
您还可以使用 train()
方法来继续学习过程,并且,例如,逐渐降低学习率:
for _ in range(10): alpha *= .9 model.train(sentences, total_examples=model.corpus_count, epochs=model.epochs, alpha=alpha)
因此,我们可以将文档向量作为特征来访问,以训练情感分类器:
X = np.zeros(shape=(len(sample), size)) y = sample.stars.sub(1) # model needs [0, 5) labels for i in range(len(sample)): X[i] = model[i]
我们将训练一个 lightgbm
梯度提升机,如下所示:
- 从训练集和测试集创建
lightgbm
Dataset
对象:
train_data = lgb.Dataset(data=X_train, label=y_train) test_data = train_data.create_valid(X_test, label=y_test)
- 定义具有五个类别的多类模型的训练参数(否则使用默认值):
params = {'objective' : 'multiclass', 'num_classes': 5}
- 对模型进行 250 次迭代的训练,并监视验证集错误:
lgb_model = lgb.train(params=params, train_set=train_data, num_boost_round=250, valid_sets=[train_data, test_data], verbose_eval=25)
- Lightgbm 对所有五个类别进行概率预测。我们使用
np.argmax()
来获取具有最高预测概率的列索引来获取类别预测:
y_pred = np.argmax(lgb_model.predict(X_test), axis=1)
- 我们计算准确率评分来评估结果,并看到相对于五个平衡类别的基线 20%,准确率提高了 100% 以上:
accuracy_score(y_true=y_test, y_pred=y_pred) 0.44955063467061984
- 最后,我们通过混淆矩阵来更仔细地查看每个类别的预测:
cm = confusion_matrix(y_true=y_test, y_pred=y_pred) cm = pd.DataFrame(cm / np.sum(cm), index=stars, columns=stars)
- 并将结果可视化为
seaborn
热图:
sns.heatmap(cm, annot=True, cmap='Blues', fmt='.1%')
总之,doc2vec
方法使我们能够在不经过太多调整的情况下,比一个简单的基准模型取得了非常大的测试准确率改进。如果我们只选择顶部和底部的评论(分别为五星和一星),并训练一个二元分类器,则使用每个类别的 250,000 个样本时,AUC 分数可以达到 0.86 以上。
附加内容 - 用于翻译的 Word2vec
该 notebook 翻译演示了一个语言中编码的关系通常对应于另一种语言中的类似关系。
它说明了如何使用单词向量通过将单词向量从一个语言的嵌入空间投影到另一个语言的空间使用翻译矩阵来翻译单词和短语。
摘要
本章以词嵌入如何更有效地为个别标记编码语义开始,这比我们在第十三章中使用的词袋模型更为有效。我们还看到了如何通过线性向量算术验证嵌入,以评估是否正确表示了单词之间的语义关系。
学习词嵌入时,我们使用的浅层神经网络曾经在包含数十亿标记的 Web 数据规模上训练速度很慢。word2vec
模型结合了几种算法创新,显著加速了训练,并为文本特征生成确立了新标准。我们看到了如何使用spaCy
和gensim
来使用预训练的词向量,并学会了训练自己的词向量嵌入。然后,我们将word2vec
模型应用于 SEC 提交文件。最后,我们介绍了doc2vec
扩展,它以与单词向量类似的方式学习文档的向量表示,并将其应用于 Yelp 商家评论。
现在,我们将开始第四部分关于深度学习(如前言所述,在线可用),从介绍前馈网络、流行的深度学习框架和大规模高效训练技术开始。
Python 机器学习算法交易实用指南(五)(4)https://developer.aliyun.com/article/1523713