Python 與金融科技10|使用機器學習演算法預測交易策略
技術標籤:Python金融資料演算法python機器學習人工智慧深度學習
這一期,我們將使用上一期處理好的資料特徵和標籤訓練機器,然後預測交易策略。我們將分別使用 K近鄰演算法和整合學習兩種方法分別完成模型的訓練和預測。
前言
在這個系列中,我們將共同學習如何藉助Python這個強大的工具處理金融資料。在正式開始這個系列的學習之前,需要您具有Python程式設計的基礎知識,至少需要將Python安裝好。如果暫時還不滿足這一要求的,建議先關注公眾號 IT資訊教室,學習 Python入門教程。
內容首發於微信公眾號IT資訊教室,如果您想學習更多AI相關的技能,歡迎搜尋關注或微信掃描下方二維碼關注~~
K近鄰演算法
在 Python 中有很多種免費的機器學習庫,其中之一是 sklearn,是針對 Python 的免費軟體機器學習庫。
sklearn 具有各種分類,迴歸和聚類演算法,包括支援向量機,隨機森林,梯度提升,k均值和DBSCAN等內建方法。
K近鄰演算法是機器學習中比較簡單的演算法之一,在 sklearn 工具包中提供可以直接呼叫的方法。
K近鄰演算法是一個分類演算法,可以把待分類的資料看作空間或者平面的一些點,如果一個樣本點附近的K個最近的樣本點大多數都是屬於同一個類別,那麼,這個樣本點就也是屬於這個類別。
與之前一樣,使用一個特定的函式 doML() 來實現本期的內容,因為要使用上一期處理好的特徵資料和標籤來完成機器學習方法的訓練,所以執行上一期的函式獲取處理完成後的資料:
def doML(ticker):
X, y, dataFrame = extractFeaturesets(ticker)
接下來我們從所有的資料中劃分出一部分來訓練模型,另一部分的資料用來測試我們模型的準確性。
可以使用 train_test_split 這個方法來劃分資料,這個方法來自於 sklearn 庫,所以使用之前需要先匯入這個方法:
from sklearn.model_selection import train_test_split
train_test_split 方法一般有三個引數,第一個引數為待劃分的特徵資料,第二個引數為待劃分的標籤資料,第三個引數為測試資料所佔的比例,第三個引數的值是介於 0 和 1 之間:
XTrain, XTest, yTrain, yTest = train_test_split(X, y, test_size=0.25)
這裡使用 X 作為特徵資料,y 作為標籤資料,隨機取資料總量的 25% 作為測試資料。
接下來我們設定分類模型,這裡選擇 K近鄰分類演算法,前面說過,這是 sklearn 內建的一個方法,使用之前需要先匯入一下:
from sklearn import neighbors
然後使用內建的 K近鄰演算法生成一個分類器 clf:
clf = neighbors.KNeighborsClassifier()
下一步要做的就是訓練模型,藉助於 sklearn 這個機器學習庫,訓練模型也變得很簡單:
clf.fit(XTrain, yTrain)
使用 fit 這個方法來訓練模型,一般會有兩個引數,第一個引數為訓練用的特徵資料,第二個引數為訓練用的標籤資料。
執行這行程式碼後,我們生成的分類器會自動用給定的資料按照既定的模型完成訓練。
還記得前面我們除了生成訓練資料,還生成了測試資料嗎?這時就可以使用測試資料來測試訓練好的模型的準確度,使用 score 這個方法可以返回測試測準確率。
這個方法一般有兩個引數,分別為測試用的特徵資料和測試用的標籤資料:
confidence = clf.score(XTest, yTest)
這個方法會首先將特徵資料作為輸入,使用訓練好的模型去給這些特徵資料分類,也就是獲取每組資料對應的標籤。然後會將預測出來的結果與測試資料中的標籤資料比對,得到並返回一個準確率。
獲取了測試的準確率後,為了讓結果更直觀,我們把準確率輸出:
print('Accuracy:', confidence)
完成了模型的訓練,就可以對資料進行分類預測了。例如我們給定測試用的特徵資料 XTest,使用 predict 方法就可以完成對特徵資料的分類:
predictions = clf.predict(XTest)
根據我們的訓練資料,這裡得到的結果實際上是由 0、1 和 -1 這三個數構成的列表,根據前面的分析,0表示繼續持有,1 表示買入,-1表示賣出。
為了更直觀的展示結果,我們使用 統計每個數出現的次數並將其輸出:
print('Predicted Spread:', Counter(predictions))
這樣就完成了是用 K近鄰演算法預測交易策略。接下來呼叫 doML 這個函式,使用 ‘600036.SS’ 這支股票來驗證一下:
doML('600036.SS')
觀察到的參考輸出為:
dataSpread: Counter({1: 1104, -1: 1082, 0: 463})
Accuracy: 0.41389728096676737
Predicted Spread: Counter({-1: 340, 1: 200, 0: 122})
因為每次使用的訓練資料都是隨機選取的,所以每次得到的準確率可能都不太一樣。
這裡我們得到的準確率是 41% 左右。對於隨機生成的測試資料,預測則結果是由 340 天是建議賣出,200天建議買入,122天建議繼續持有。
如果實際中,我們想要去預測當日的策略,只需要用之前的交易資料去訓練模型,然後得到當日的特徵資料,將特徵資料輸入訓練好的模型,就可以看到使用 K近鄰分類演算法輸出的建議交易策略了。
如果在某次的訓練過程中,獲取到的準確率比較高,還可以將這一次訓練的模型儲存為 pickle 格式,以後需要使用的時候只需要直接獲取這個模型即可。
整合學習
整合學習實際上就是分類器的整合,就是構建多個機器學習模型來完成學習任務。機器學習有很多種模型,對於同一個問題,每一種模型都會產生不同的預測結果。對於多種模型預測結果如何選擇最合適的一個結果呢?這就是整合學習要解決的問題之一:
把多種演算法集中起來,每種演算法都會有一個自己的預測結果,然後對每種演算法的結果進行評估投票,綜合選擇出最好的結果。
在 sklearn 中提供一個封裝好的整合學習方法 VotingClassifier,按照慣例,使用之前先匯入相關的庫檔案:
from sklearn.ensemble import VotingClassifier
在構建整合學習的分類器之前,首先按照第一部分的方法匯入處理好的資料並獲取訓練集和測試集:
def doML(ticker):
X, y, dataFrame = extractFeaturesets(ticker)
XTrain, XTest, yTrain, yTest = train_test_split(X, y, test_size=0.25)
然後開始構建整合學習分類器,這裡我們整合使用三種分類方法:
線性支援向量機、K近鄰演算法和隨機森林分類演算法。
支援向量機是一種二類分類模型。它的基本思想是在特徵空間中尋找間隔最大的分離超平面使資料得到高效的二分類。
隨機森林分類演算法指的是利用多個決策樹對樣本進行訓練並預測的一種分類器。
這是三種比較常見的分類演算法,在 sklearn 中都提供了可以直接呼叫的方法。如果使用線性支援向量機需要匯入以下工具包:
from sklearn import svm
使用 K近鄰演算法 需要匯入以下工具包:
from sklearn import neighbors
使用 隨機森林演算法 需要匯入以下工具包:
from sklearn.ensemble import RandomForestClassifier
想要使用整合學習,只需要新增以下程式碼:
clf = VotingClassifier([('lsvc', svm.LinearSVC()),
('knn', neighbors.KNeighborsClassifier()),
('rfor', RandomForestClassifier())]
)
這樣就完成了整合學習分類器的構建,接下里只需要按照與上一部分相同的方法用處理好的資料訓練並驗證模型:
clf.fit(XTrain, yTrain)
confidence = clf.score(XTest, yTest)
print('Accuracy:', confidence)
最後完成模型的預測並輸出結果:
predictions = clf.predict(XTest)
print('Predicted Spread:', Counter(predictions))
最後我們同樣用 ‘600036.SS’ 這支股票來驗證整合學習的預測結果,輸出內容如下:
dataSpread: Counter({1: 1104, -1: 1082, 0: 463})
Accuracy: 0.4501510574018127
Predicted Spread: Counter({-1: 390, 1: 270, 0: 2})
這裡預測的準確性可以達到 45%。對於這支股票,在測試集合中,整合學習方法預測的結果是有 390天 建議賣出,有 270天 建議買入,有 2 天建議繼續持有。
一般來說,使用整合學習預測的結果會比使用單一模型的預測結果好一些。
同樣的,如果希望預測其他時間點的交易策略,只需要更新測試資料樣本就可以了。
參考程式碼
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author: IT資訊教室(微信公眾號)
訂閱/關注,在看、分享三連吧~
"""
from collections import Counter
from sklearn import svm, neighbors
from sklearn.model_selection import train_test_split
from sklearn.ensemble import VotingClassifier, RandomForestClassifier
def doML(ticker):
X, y, dataFrame = extractFeaturesets(ticker)
XTrain, XTest, yTrain, yTest = train_test_split(X, y, test_size=0.25)
# print(len(XTrain[0]), len(XTest[0]))
# print(yTrain, yTest)
# 構建整合學習分類器,使用的分類演算法有 線性支援向量機、K近鄰演算法和隨機森林演算法。
clf = VotingClassifier([('lsvc', svm.LinearSVC()),
('knn', neighbors.KNeighborsClassifier()),
('rfor', RandomForestClassifier())]
)
# 構建 K近鄰演算法的分類器
# clf = neighbors.KNeighborsClassifier()
clf.fit(XTrain, yTrain)
confidence = clf.score(XTest, yTest)
print('Accuracy:', confidence)
predictions = clf.predict(XTest)
print('Predicted Spread:', Counter(predictions))
print()
print()
doML('600036.SS')
doML('601328.SS')
doML('600340.SS')