自然語言學習——使用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積分下載)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章