一
上篇文章我們進行了黃金行情資料爬取,並對黃金資料進行了一波花式分析,這篇文章我們將用我們之前的文章所用過的策略進行黃金價格的分析,並通過分析,優化我們的程式碼,提升預測的正確性。
我們輸出一下這3650天的漲跌情況的柱狀分佈圖
rate_of_return.plot(kind=`hist`,bins=150,alpha=0.3,color=`g`,normed=1)
rate_of_return.plot(kind=`kde`,xlim=[-0.1,0.1],style=`r`,grid=True,figsize=(15,10))
plt.show()
複製程式碼
僅用三行程式碼,我們就輸出了這樣一個優美的柱狀分佈圖,這裡面紅色的曲線叫kde圖,中文名字叫核密度估計圖,是在概率論中用來估計未知的密度函式。
我們可以看到,漲跌幅的分佈是一個比較標準的正態分佈,中間高兩邊小,而且對於XAUUSD來說,因為有高達兩百倍這樣的槓桿比率的存在,我們看來很小的一些漲跌幅波動,對於炒外匯的人來說,那一上一下就是好幾個億啊!
二
OK,現在我們按照機器學習股票價格預測初級實戰這篇文章的方法對黃金價格進行預測,主要思路就是,通過對預測當天前兩天的漲跌情況作為特徵,而標籤為預測當天的漲跌情況。
這樣跑下來,我們的預測正確率為53%,實際上這個結果我認為還是有一定道理的,如果行情連續兩天都在漲,那麼第三天最後是漲的情況可能確實要多一些。
這邊因為程式碼重複,我就直接截圖了
因為我有自己玩過外匯,所以大概會看一些簡單的趨勢,而這些趨勢判斷的時間段經常是以月為單位的,所以我們可以動態的改變一下視窗期,一個月的工作日有21,22天這樣,那麼我們就從看看預測概率在window為1-22情況下的情況吧。
# 視窗期對預測數量的影響
win_ratio = []
window_list = [x for x in range(22) if x != 0]
i = 1
for window in window_list:
X = deque()
y = deque()
clf = tree.DecisionTreeClassifier()
prediction = 0
test_num = 0
win_num = 0
current_index = window
for current_index in range(current_index, len(up_and_down)-1, 1):
fact = up_and_down[current_index+1]
X.append(list(up_and_down[(current_index-window): current_index]))
y.append(up_and_down[current_index])
if len(y) > 100:
test_num += 1
clf.fit(X, y)
prediction = clf.predict([list(up_and_down[(current_index-window+1): current_index+1])])
if prediction[0] == fact:
win_num += 1
ratio = win_num/test_num
print("已完成預測",i,`次`)
i += 1
win_ratio.append(ratio)
fig = plt.figure(figsize=(12,10))
plt.plot(window_list,win_ratio,`ro--`)
plt.show()
複製程式碼
結果非常有趣,我們發現,視窗期從8開始,預測的正確率呈現出一個比較明顯的上揚趨勢,甚至在window為17天的時候,正確率達到驚人的百分之57。
實際上我有在別的品種,比如股票的品種上跑過相同的程式碼,但大多數的正確率只有52-53之間。看,我們好似發現了黃金外匯中的一個比較有趣的影響特徵了。
實際上我這樣的寫法過於粗暴,因為我們window的數量對於這個案例來說直接決定了我們的特徵維度,window越大,你會發現我們整個的預測邏輯執行時間將會越長。這裡會涉及到一個特徵工程,我們可以可以把這樣的特徵轉化為一個對映。這樣,無論window是多少,最後都會轉化為一個特徵。
比如,如果window=4,然後其中一個樣本的前四天的漲跌情況為,漲漲跌跌,通過對映,我們可以用一個向量來表示:[1,1,0,0]。當然啦,特徵工程是一個非常重要的事情,我們今天的重點並不在這。
我們來試試對於預測sample進行動態改變會對預測結果帶來多少影響。
# 樣本數量對預測率的影響
window = 2
win_ratio = []
samples_list = [x*5 for x in range(60) if x != 0]
for samples in samples_list:
X = deque()
y = deque()
clf = tree.DecisionTreeClassifier()
prediction = 0
test_num = 0
win_num = 0
current_index = 2
for current_index in range(current_index, len(up_and_down)-1, 1):
fact = up_and_down[current_index+1]
X.append(list(up_and_down[(current_index-window): current_index]))
y.append(up_and_down[current_index])
if len(y) > samples:
test_num += 1
clf.fit(X, y)
prediction = clf.predict([list(up_and_down[(current_index-window+1): current_index+1])])
if prediction[0] == fact:
win_num += 1
ratio = win_num/test_num
win_ratio.append(ratio)
print("預測完畢")
fig = plt.figure(figsize=(12,10))
plt.plot(samples_list,win_ratio,`ro--`)
plt.show()
複製程式碼
沒錯,看起來確實有些影響,但看看我們的y軸數值,實際上影響並不是很大,這裡主要因為我的迴圈數量還是很低,最高的300對於3000多的完整資料來說,還是不太夠的。
再有,我這套程式碼的訓練泛化性並不高,我在sample訓練之後,雖然劃分了訓練集和測試集,但每次預測完一個測試資料就會把這條資料在下次預測的時候新增到訓練資料集裡,所以結果差距不大,確實在情理之中。
這裡涉及到一個拆分資料的問題,如果可以,儘量將資料拆分成三層 : 訓練集、驗證集和測試集。
三
文章差不多要結束了,我們的價格預測,實際上還差得遠呢,最重要的是,我並不是一個專業的金融分析師,做這樣的量化交易與預測分析,顯然是需要金融專業的人和程式設計師配合才能擦出火花,我一直覺得金融是機器學習目前最適用的領域了,它的資料多,指標全,太適合做歷史資料分析了,任重而道遠,還有很多值得我去學習的。
這是最近兩篇文章 ipy 和 py 原始碼檔案的 Github 連結,有需要的朋友請下載觀看,建議使用 jupyter notebook 觀看,體驗更好一點
參考文章:關於漲跌的思考
推薦閱讀