基于LDA主题模型对新闻报道聚类与Apple公司股票预测

一、主题

基于LDA主题模型对新闻报道聚类与Apple公司股票预测

二、简述

文本聚类的基本步骤:
(1)文本预处理。对获得的文本数据进行清洗,过滤掉无用的文本。然后对文本进行分词。分词后需要去除像“的”、“啊”等无用的词。
(2)构造文本特征。将预处理好的文本转化成能让学习模型处理的数据类型。首先可以生成词袋,即不考虑词语的原本在句子中的顺序,直接将每一个词按照计数的方式进行统计。然后进行词干提取。
(3)构造模型训练。将获得的数据进行划分训练集和测试集,用合适的模型进行训练,最后计算准确率等来评估模型。

TF-IDF算法:
该算法包含两个部分,分别是TF(词频)和IDF(逆文档频率),两者相乘得到TF-IDF算法。

在这里插入图片描述
TF-IDF = TF*IDF

其中,TF算法用来统计训练文本中,某个词的出现次数;IDF 算法用于调整词频的权重系数。

LDA主题模型:
LDA(Latent Dirichlet Allocation,隐含狄利克雷分布)主题模型在机器学习领域有着重要的作用,常用来处理文本数据。其原理是假设文本主题是多项分布,多项分布的参数(先验分布)是服从Dirichlet分布,其实LDA是一种三层的贝叶斯模型。它可以将文本中每篇文档的主题以概率分布的形式给出,从而通过分析一些文本抽取出它们的主题分布后,便可以根据主题分布进行主题聚类或文本分类。
LDA 采用词袋模型。所谓词袋模型,是将一篇文档,我们仅考虑一个词汇是否出现,而不考虑其出现的顺序。与词袋模型相反的一个模型是N-gram,N-gram考虑了词汇出现的先后顺序。
LDA步骤简述:
1.对每一篇文档,从主题分布中抽取一个主题;
2.从上述被抽到的主题所对应的单词分布中抽取一个单词;
3.重复上述过程直至遍历文档中的每一个单词。

SVM算法:
SVM算法(Support Vector Machine,支持向量机)是机器学习领域经典的算法。主要用于解决模式识别领域中的数据分类问题,属于有监督学习算法的一种。SVM本质模型是特征空间中最大化间隔的线性分类器,可以认为是一种二分类模型。目前,SVM 在文本分类、人脸识别、手写字符识别、金融等领域已有非常成功的应用。
在这里插入图片描述
对于不同维度空间,SVM的形式特点也不同。
在这里插入图片描述
优点:
(1)使用核函数可以向高维空间进行映射,可以解决非线性分类。
(2)分类效果较好。
缺点:
(1)SVM算法对大规模训练样本难以实施。
(2)用SVM解决多分类问题存在困难。
(3)对缺失数据敏感,对参数和核函数的选择敏感。

逻辑回归算法:
逻辑回归(Logistic Regression),虽然名字中带有回归两个字,但它却不是回归算法,它是一种用于解决二分类问题的机器学习方法,用于估计某种事物的可能性,其分类边界不一定都是线性的,也可以是非线性的。

优点:
(1)分类时计算量非常小,速度很快,存储资源低。
(2)方便观测样本概率分数。
(3)计算代价不高,易于理解和实现。
缺点:
(1)容易欠拟合,准确度不太高。
(2)不能很好地处理大量多类特征。
(3)当特征空间很大时,性能不是很好。

三、方案设计及实现过程

首先从取汤森路透(TCR)提供的数据库中获取新闻报道数据,观察数据的时间跨度。根据该时间跨度在雅虎金融网站下载Apple公司(股票代码:AAPL)的股票信息。完成数据集准备后进行实现。
导入数据,并观察数据的基本信息。
在这里插入图片描述
Open和Close分别代表该股票在当天的开盘价和收盘价。简单起见,将收盘价减去开盘价,若大于等于0,则认为股价涨了,将其置为1,反之股价跌了,将其置为0。
在这里插入图片描述
提取label列将其添加到新闻报道数据集中。该新闻数据集包含每日点击率最高的25条新闻报道的标题,将每天的数据合并起来放到最后一列。查看数据的相关情况。取”Date”,”combined_news”,”label”三列合成一个新的数据集,至此数据集转化成为初始数据集,之后便可以对该数据集进行一系列的操作。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
随意查看其中的几条数据,可以看出数据比较杂乱,而且里面有很多不需要的数据。因此需要进行预处理来对一些无用的标点符号、换行符等进行删除。对于英文文字集,额外需要去除“’s”、“’re”等简写。
在这里插入图片描述
预处理过程包括替换一些英文标点符号、去掉数字等。同时通过调用nltk模块的中的英语停用词将数据中的无用词删除。再根据文本数据中的一些特殊符号,例如”\\”,将其从文本中去除。
在这里插入图片描述
在预处理的过程中需要将文本分词。在文本聚类中,无论是中文还是英文,都需要将一大段文字进行分词处理。处理过后的数据与之前的数据相比整洁里许多,之后便可以进行接下来的操作。
在这里插入图片描述
接着开始利用gensim模块来构建LDA模型。首先将刚刚整理出来的文本数据转化成为gensim认可的语料库形式。这里用了词袋的方法,把每个单词用一个数字index指代,并把原来的文本数据转化为数组。在LDA主题模型中,将所有文本数据聚成20个类,主题词数量设置为10,并输出查看。
通过结果可以看到各个主题的编号以及各个主题中词出现的概率。例如主题5,应该是关于英美两国对以色列冲突的相关态度;主题7,应该是关于中国、美国、俄罗斯三国政府以及世界形势的相关主题。这里只能知道主题编号,通过提取高频词,人为判定它的主题内容。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过调用sklearn库中的TfidfVectorizer()函数来计算TF-IDF。输出IDF的值进行查看,同时也输出特征向量进行观察。
在这里插入图片描述
在这里插入图片描述

最后用机器学习算法预测Apple公司股价的涨跌。这里用了两种算法进行比较,分别是支持向量机和逻辑回归。首先根据时间划分测试集和训练集,在对数据格式进行转化,输出最佳模型的配置参数。最后预测矩阵和准确率进行查看。从结果上看,支持向量机的准确率高于逻辑回归,但还是不足,仅仅只有一半的正确率。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

使用LDA主题模型进行聚类的关键在于主题数量K的选取。若K值太大,则主题内容分得过细,反之,主体内容会分得过粗。最好是根据实际的情况进行多次尝试来确定。而之后用机器学习算法来预测Apple公司股票的涨跌准确率不是很高,原因在于股市的风险难以预料,不能单单凭借新闻报道以及一些算法进行预测。经过查找资料和思考,股市的数据可以认为是一个时间序列,考虑使用LSTM算法进行尝试,再结合更加细化的新闻文本的聚类分析,理论上可以提高正确率。

实现代码

import pandas as pd
import numpy as np

aapl = pd.read_csv('AAPL.csv')
aapl['subtract'] = aapl['Close'] - aapl['Open']
aapl['label'] = aapl['subtract'].apply(lambda x:1 if x>=0 else 0 )
aapl

news = pd.read_csv('News.csv')
news['label'] = aapl['label']
news['combined_news'] = news.filter(regex=("Top.*")).apply(lambda x: ''.join(str(x.values)), axis=1)
news
data = news[['Date','combined_news','label']]
data.head(10)
data['combined_news'].head().values

import re
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

def clean_news_data(text):
    text = text.replace('\n'," ") 
    text = text.replace("b'"," ").replace('b"', " ").replace('b', " ")
    text = text.replace("\\'"," ") 
    text = re.sub(r'\\\\', ' ', text)
    text = re.sub(r"-", " ", text) #把 "-" 的两个单词分开
    text = re.sub(r'\d+', '', text)  #去掉数字
    text = text.lower()
    
    english_punctuations = [',', '.', ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%', '-',
                            '..', '...', '|', '``', '\'','\\' , '\'\'', '<', '>', '~', '+', '/', '//', '"']
    addition_stopwords = ['\'re', '\'s', '\'t', '\'m', '\'ll', '\'ve', '\'d', 'n\'t','een','e']
    
    words = word_tokenize(text)
    stop = stopwords.words('english')
    
    filter_words = [w for w in words if (w not in stop)]
    filter_words = [w for w in filter_words if (w not in english_punctuations)]
    filter_words = [w for w in filter_words if (w not in addition_stopwords)]
    return filter_words

cn = data['combined_news']
xw = cn.apply(lambda s: clean_news_data(s))
xw.head().values

import gensim
from gensim import corpora, models, similarities
from sklearn.feature_extraction.text import TfidfVectorizer

dictionary = corpora.Dictionary(xw)       #为每个出现在语料库中的单词分配了一个独一无二的整数编号
corpus = [dictionary.doc2bow(text) for text in xw]   #对每个不同单词的出现次数进行了计数,并将单词转换为其编号以稀疏向量的形式返回结果

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)
lda.print_topics(num_topics=20, num_words=10)

from sklearn.feature_extraction.text import TfidfVectorizer

tf = TfidfVectorizer(norm=None)
tf_fit=tf.fit_transform(cn)

print(tf.idf_)
#print(tf_fit.toarray())
tf.vocabulary_

from sklearn import svm
from sklearn.linear_model import LogisticRegression

train = data[data['Date'] <= '2015-01-01']
test = data[data['Date'] > '2015-01-01']

x_train = train['combined_news'].apply(lambda s: clean_news_data(s))
x_test = test['combined_news'].apply(lambda s: clean_news_data(s))

x_train = x_train.apply(lambda x: ' '.join(x))
x_test = x_test.apply(lambda x: ' '.join(x))

x_train = tf.fit_transform(x_train.values)
x_test = tf.transform(x_test.values)
y_train = train['label'].values
y_test = test['label'].values

rbf = svm.SVC(kernel='rbf',probability=True)
result1 = rbf.fit(x_train, y_train)
print(result1)

predict1 = rbf.predict_proba(x_test)
print(predict1)

lr = LogisticRegression()
result2 = lr.fit(x_train, y_train)
print(result2)
predict2 = rbf.predict(x_test)
print(predict2)

score1 = rbf.score(x_test, y_test)
print("svm准确率:",score1)
score2 = lr.score(x_test, y_test)
print("逻辑回归准确率:",score2)
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值