自然语言学习——使用FastText用每日新闻预测金融市场变化

本文主要讲述了通过FastText的分类方法,根据每日新闻来预测金融市场。

数据集:Combined_News_DJIA.csv

读入数据集:

数据集主要分为三个部分:Date(日期),Label(0:股票下跌;1:股票上涨),Top0-25(新闻内容)

一、拆分出训练集和测试集

由于只有这一个数据集,需要对上面这个数据集拆分出训练集和测试集。代码如下:

将2015-01-01(不包含)之前的数据作为训练集,将2015-01-01(包含)之后的数据作为测试集

二、对数据集预处理

1.将每日新闻存放在数组内

在拆分好数据集后,需要对这些数据集预处理成方便训练模型的数据集,代码如下:

其中每条语句都有注释方便理解。上述代码主要获得五个东西:

X_train:一维数组,[a,b,c...,d,e,f],a表示训练集中第一天中所有25条新闻合并一起,用空格隔开。

X_test:一维数组,[a,b,c...,d,e,f],a表示测试集中第一天中所有25条新闻合并一起,用空格隔开。

y_train:一维数组,[0,1,0...,1,0,0],由0,1组成,对应训练集中每一条股票的涨跌。

y_test:一维数组,[0,1,0...,1,0,0],由0,1组成,对应测试集中每一条股票的涨跌。

corpus:一维数组,存储所有的新闻,每一项表示一条新闻(不是X_train中的25条合一起了)。

2.将每日新闻拆分为单词

得到上述五个变量后,因为存储的每一条新闻都是一句或几句话,计算机处理起来不方便,需要把每一句话拆分成单词才好处理,代码如下:

导入了一个word_tokenize函数,其功能为将一句话拆分成单词然后存储在一个列表当中,执行这几条语句后,本来为存储每一句话的一维数组将变为存储单词的二维数组。

3.去除停止词

拆分好每一个单词后,需要去除停止词,停止词就是对全文分析毫无意义的词汇,比如一些语气助词之类的,可参考这篇文章:

https://blog.csdn.net/Da_wan/article/details/104640649

去除停止词函数代码:

# 停止词
from nltk.corpus import stopwords
stop = stopwords.words('english')

# 数字
import re
def hasNumbers(inputString):
    return bool(re.search(r'\d', inputString))

# 特殊符号
def isSymbol(inputString):
    return bool(re.match(r'[^\w]', inputString))

# lemma
from nltk.stem import WordNetLemmatizer
wordnet_lemmatizer = WordNetLemmatizer()

def check(word):
    """
    如果需要这个单词,则True
    如果应该去除,则False
    """
    word= word.lower()
    if word in stop:
        return False
    elif hasNumbers(word) or isSymbol(word):
        return False
    else:
        return True

# 把上面的方法综合起来
def preprocessing(sen):
    res = []
    for word in sen:
        if check(word):
            # 这一段的用处仅仅是去除python里面byte存str时候留下的标识。。之前数据没处理好,其他case里不会有这个情况
            word = word.lower().replace("b'", '').replace('b"', '').replace('"', '').replace("'", '')
            res.append(wordnet_lemmatizer.lemmatize(word))
    return res

preprocessing()为上述粘贴代码的函数,功能就是去除停止词,以及一些特殊符号。

执行完上述操作后,便得到干净所需的单词数据,可以用这些数据去训练数据集了。

4.重新组接成新句子

在去除完生成词后,我们需要重新拼接为新的句子,这些句子都是没有语法的,因为上述操作已经将部分单词去除,看起来会非常违和,但是计算机看这些句子就不用在意,因为之前的这些预处理操作只是让数据显得更加干净,准确率更高。先上代码:

这部分代码当中在每一天的新闻信息后面多加了一个__label__1或者__label__0这样一个标签,是因为fasttext约定俗成的东西,方便其训练模型,0,1表示股票涨跌。加好标签后,然后每个单词用空格分隔开存储,这时每一天都有25条新闻合并成一个句子后面还加了一个label,这就是我们最终要训练的数据。

而测试集是用来测试label是0,还是1的所以不用加label直接拼接成句子就行。

5.将数据集保存为文本

代码十分简单,有三个txt文件,一个是训练集的文本,一个是测试集的文本,最后一个是检验测试集准确率的文本

三、调用Fastext模块,训练模型

import fasttext

clf = fasttext.train_supervised('./input/train_ft.txt', dim=256, ws=5, neg=5, epoch=100, min_count=10, lr=0.1, lr_update_rate=1000, bucket=200000)

将训练集的txt文件导入到模型中训练。最后通过简单的clf.predict(X_test)就可以简单的得出测试集中的label是0还是1,

import re
y_temp = []
y_preds =[]
# 我们用predict来给出判断
labels = clf.predict(X_test)

for x in np.array(labels[0]).flatten():
    y_temp = np.array(re.findall('\d+',x)).astype("int")
    y_preds.append(y_temp)

y_preds = np.array(y_preds).flatten()

# 我们来看看
print(len(y_test))
print(y_test)
print(len(y_preds))
print(y_preds)

from sklearn import metrics

# 算个AUC准确率
fpr, tpr, thresholds = metrics.roc_curve(y_test, y_preds, pos_label=1)
print(metrics.auc(fpr, tpr))

有一段与我课程上的不一样,因为预测的结果是__label__0,不是单纯的数字,所以用re来匹配出其中的数字来存储,最后得到的y_preds就是我们预测的结果,每一项就表示当天股票是涨还是跌了。

四、总结

本文通过Fasttext预测结果并不是很好(只有40%的准确率),只是单纯的记录一下fasttext这样一种方法。

在小量数据上,fasttext是跑不出很理想的结论的,还不如我们自己带上一个SVM的效果。但是面对大量数据和大量label,它的效果就体现出来了。

本文需要的数据集,以及源代码也已经上传(已经设置为0积分下载)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值