数据简介
本案例用到的原始数据是一个简单的数据集,其中包括从国外某网站捞取的每日新闻排序(25条),然后以当日的股票市场涨跌作为Label。从而根据对新闻的挖掘,来判断当日股票涨跌。
数据集大致长这样(部分截图):
Date:日期数据,本案例文本分析就不用这个数据了。
Label:当日股票市场情况,1代表上涨,0代表下跌。
Top*:共25列,表示当日的相关新闻。
下面利用Word2Vec简单的进行文本的向量化处理,代码也都比较简单,重点是关注处理流程。
导入数据:
import numpy as np
import pandas as pd
from sklearn.metrics import roc_auc_score
from datetime import date
#读入数据
data=pd.read_csv(r'E:\python\news stock\input\Combined_News_DJIA.csv')
#观察数据
data.head()
分割测试/训练集:
#分割测试/训练集,保留部分数据测试用
train=data[data['Date']<'2015-01-01']
test=data[data['Date']>'2014-12-31']
#把每条新闻做成一个单独的句子,集合在一起
X_train=train[train.columns[2:]]
corpus=X_train.values.flatten().astype(str)
X_train=X_train.values.astype(str)
X_train=np.array([' '.join(x) for x in X_train])
X_test=test[test.columns[2:]]
X_test=X_test.values.astype(str)
X_test=np.array([' '.join(x) for x in X_test])
y_train=train['Label'].values
y_test=test['Label'].values
#corpus是全部我们『可见』的文本资料。我们假设每条新闻就是一句话,把他们全部flatten()了,我们就会得到list of sentences。
#再进行分词
from nltk.tokenize import word_tokenize
corpus=[word_tokenize(x) for x in corpus]
X_train=[word_tokenize(x) for x in X_train]
X_test=[word_tokenize(x) for x in X_test]
#tokenize完毕后,corpus和x都是一个二维数组。corpus里,第二维数据是一个个句子。x里,第二维数据是一个个数据点(对应每个label)
数据预处理:
#停止词
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):
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):
word=word.lower().replace("b'",'').replace('b"','').replace('"','').replace("'",'')
res.append(wordnet_lemmatizer.lemmatize(word))
return res
#把三个数据组都来处理一下
corpus=[preprocessing(x) for x in corpus]
X_train=[preprocessing(x) for x in X_train]
X_test=[preprocessing(x) for x in X_test]
训练NLP模型:
#Word2Vec的简单运用
from gensim.models.word2vec import Word2Vec
model=Word2Vec(corpus,size=128,window=5,min_count=5,workers=4)
#这个文本本身量很小,我们可以把所有的单词的vector拿过来取个平均值
#拿到全部的vocabulary
vocab=model.wv.vocab
#得到任意text的vector
def get_vector(word_list):
res=np.zeros([128])
count=0
for word in word_list:
if word in vocab:
res+=model[word]
count+=1
return res/count
#此时,我们得到了一个取得任意word list平均vector值的方法
#我们可以同步把我们的X都给转化成128维的一个vector list
wordlist_train=X_train
wordlist_test=X_test
X_train=[get_vector(x) for x in X_train]
X_test=[get_vector(x) for x in X_test]
模型训练:
#SVM
from sklearn.svm import SVR
from sklearn.model_selection import cross_val_score
params=[0.1,0.5,1,3,5,7,10,12,16,20,25,30,35,40]
test_scores=[]
for param in params:
clf=SVR(gamma=param)
test_score=cross_val_score(clf,X_train,y_train,cv=3,scoring='roc_auc')
test_scores.append(np.mean(test_score))
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(params,test_scores)
plt.title('Param vs CV AUC Score')
上面模型训练好之后,就可以把test丢进去,获取结果了。本文对Word2Vec进行简单的平均化处理,其实在大数据集上这样处理是不严谨的,上面只是示范下简单的过程。而本身Word2Vec构建特征也要根据实际案例进行处理,具体更多使用方法可以搜索相关资料进行学习。