祝大家新年快樂
0
機器學習中的分類
這是機器學習發揮作用的地方。我們將建立一個機器學習分類器來判斷一只股票是買入、賣出還是持有。為了確定一個股票或公司是否屬于這三種類型之一,我們將看一下每個公司的季度報告。這些季度報告包含了必要的財務信息,我們需要用基本面分析的方法來訓練我們的機器學習分類器。
獲取全部代碼,見文末
1、基礎數據——季度數據
為了訓練分類器模型,我們需要收集大量的財務季度報告。國外數據從這里:
http://www.stockpup.com/data/
國內推薦Wind,因為比較全,財務量化因子也是PIT的。如果沒有錢買他們的終端,可以用WindQuant萬礦,這個是免費的,數據和Wind一致:
www.windquant.com
DataFrame顯示如下:
我們可以觀察到所有不同的列和對應于每個列的日期。Stockpup還提供了價格信息(最高、最低等),這對我們判斷股票是買進、持有還是賣出非常重要。
我們有很多種方法來決定股票是否值得投資。如果在過去的三個季度中,資產增加了,負債減少了,我們是否可以將其歸類為買入?或者,如果股價上漲,長期債務下降?無論怎樣,我們有許多選擇來確定股票的類別。簡單地說,這是基本面分析的基礎。
1
基本面分析開始
在不了解基本面分析的情況下,我們如何從根本上分析這些季度報告?既然我們不是巴菲特那樣的基本面專家,就讓我們用自己的基本面分析方法來簡化一下吧:
從本質上講,我們正在檢測上一季度到當前季度的變化是否會影響未來的價格。我們將根據上一份報告來判斷每一份季度報告的表現,然后觀察未來的價格走勢。如下圖所示:
我們將在每個季度報告中應用這種分析方法來創建新的基礎數據。如果一只股票本季度值得投資,這種方法將進行分類。顯然,我們不能在最初的 QR 或最近的 QR 上使用這種方法,因為分析的要求過去和未來的季度報告。
2
清理數據
1、創建類標簽
為了對每一份季度報告進行分類,我們將盡量不把事情復雜化。如果下個季度價格大幅上漲,那就是買入。如果下跌,那就是賣出。如果兩者都不是,那就繼續持有。
以下是我們對每個季度報告的具體類別要求:
買:下一季度,高價和低價的漲幅均在3% 以上
賣:下一季度,高價和低價跌幅達 -3% 或以上
持有:如果兩者都沒有發生
我們還可以考慮其他可能的結果,但為了簡單起見,我們保持這些條件不變。我們不知道下個季度最新季度報告的價格高低,因為這是對未來的預測,而這是不可能的。
2、季度報告中的基本面數據
如前所述,對于我們的基本面數據,我們將觀察兩個QRs來創建新值。以前的QR到當前或當前QR的變化將以百分比變化來度量,而不是它們的實際值。例如:
假設上一季度,股票的價值是1000美元。而在本季度,股價目前為1100美元;增加了10%。現在,我們用當前QR的10%來替換1100的股票價值。
我們對每個QR都這樣做(不包括第一個QR,因為我們無法將它與不存在的東西進行比較)。現在每個QR都有每個基本值的變化百分比。
3、編碼
現在我們已經用百分比變化衡量了QRs,并標記為買入、持有或賣出,下面通過代碼實現:
a. 導入數據集
pickle文件是一個DataFrames字典,其中包含 stockpup 網站上每個股票代碼 / 公司的 QRs。
b. 輔助函數
c. 每個股票代碼來轉換數據
有幾點需要注意:
1、為了在以后訓練我們的分類模型,所有來自DFs字典的 DataFrames 被合并為一個。
2、索引被重置,因為不再需要日期。每一行或每一個 QR 現在都包含了過去和未來 QRs 的信息,所以日期對于模型不再重要
3、刪除與價格相關的特征或列,以防止數據泄漏。在正常的QRs中,這些特征不包括在內。
最后,我們導出最終的DF用于數據探索和訓練分類模型。
3
數據探索
接下來,為了更加熟悉我們的數據,我們必須執行一些簡單的探索性數據分析。我們這樣做是為了更好地理解數據,并確保在轉換數據時沒有遺留。
如大家所見,我們的數據存在一個類不平衡問題。這可能是一個問題,但我們不希望丟棄數據點,以便每個類都等于數量最少的類。盡管這可能是解決不平衡的可行方案,但是我們還有其他的選擇可以探索。另一個選擇是在驗證我們的分類模型時使用不同的評估指標。當進入建模階段時,我們將對此選項進行擴展。
數據相關性:
從我們所看到的,一些特征對確定類標簽有影響。有些與股票/季度報告是否值得買進、賣出或持有幾乎沒有關系。既然我們知道QR中的一些特征在確定類標簽時并不重要,那么我們可以從數據集中刪除這些特征。
4
特征工程
現在我們已經對我們的數據進行了一些研究,我們可以繼續進行更多的研究,或者轉移到特征工程中,或者更具體地說,是特征選擇。特征工程是改變數據集以增強機器學習模型的過程。有許多選項可以用來設計數據集的特征。包括但不限于:
1、特征選擇
在本文中,我們將簡單地刪除不重要的特征。這樣做,我們可以潛在地提高模型的準確性,并減少訓練時間。我們將展示兩種不同的特征選擇方法。這樣,我們可以比較由于我們方法的不同,模型的性能與略有不同的數據集會產生什么樣的結果。
方法1:根據相關值選擇前10個特征
我們選擇與決策類標簽相關的前10個特征:
我們現在有了一個新的分類模型數據集。希望這個新的數據集能增強我們的分類模型,并加快訓練時間。
方法2:基于樹分類器選擇前10個特征
下一種特征選擇方法比我們剛才做的要復雜一些。通過使用sklearn,我們將實現一個基于決策樹的分類器來確定哪些特征是最重要的。通過使用這個分類器,我們將能夠確定哪些特征是最重要的分類QR或股票。
接下來,隨著重要特征的排序,我們將其可視化,以確定哪些特征被確定為最重要的。
根據forest.feature_importances_方法,以下是十個是最重要的特征:
5
機器學習分類器
為了找到性能最佳的機器學習分類模型,我們將通過多個模型運行數據。每種模式都有其獨特的優點和缺點。為了確保我們對數據使用的是最優模型,我們必須嘗試每個分類器。
我們將使用的分類模型:
有很多模型!它們中的每一個都將被訓練和安裝到我們的數據集,以確定最佳性能的模型。
1、DummyClassifier
為了度量每個模型的性能,需要將它們與基線模型進行比較。這就是我們的虛擬分類器的用武之地。虛擬分類器的功能類似于隨機猜測每個QR的類標簽。它通常是基于概率的,類標簽是根據它們的樣本大小來決定的。
以建立的虛擬分類器為基線模型,為每個模型設定一個性能標準。為了被認為是一個可行的模型,每個模型必須能夠超越虛擬分類器。如果他們不能超越基線模型,那么模型也不會比隨機猜測更好。
6
對分類模型進行編程
1、導入庫并加載數據:
在導入數據時,我們可以選擇需要哪個數據集。如果我們希望比較兩個不同數據集的模型性能,這是很重要的。
2、縮放和訓練,測試,分割數據:
使用的縮放方法(歸一化)主要取決于大家,因為每個縮放器都有自己獨特的優勢。然后我們將數據分解為X和Y變量的訓練集和測試集,我們將需要這些數據來擬合和評估我們的模型。
我們通過實例化分類器來創建虛擬分類器,然后將其匹配到我們的訓練集。接下來,我們使用測試集來制作預測標簽,并與實際標簽進行比較。最后,我們打印出一份包含我們需要的評估指標的分類報告:
7
評價指標
由于我們處理的是一個不平衡的數據集,我們不能依賴準確性作為我們的模型的評估指標,這就是為什么它沒有包括在分類報告中。準確性可能是一個重要的衡量標準,但是由于我們問題的本質和類別的不平衡,準確度將被忽略,而有利于準確率和召回率。
精確率是針對我們預測結果而言的:它表示的是預測為正的樣本中有多少是真正的正樣本。
召回率是針對我們原來的樣本而言的:它表示的是樣本中的正例有多少被預測正確了。
精確率>召回率
為什么我們選擇精確率而不是召回率呢?當涉及到投資決策時,我們不希望分類器將賣出錯誤地歸類為買入。在我們保守的投資策略中,我們寧愿錯過投資機會(召回率),也不愿投資錯誤的股票(精確率)。很明顯,兩者之間有一個平衡,這就是F1-Score發揮作用的地方。但是,每個分類模型的總體判斷將基于其相對于基線模型的精度評分的增加。
8
混淆矩陣(誤差矩陣)
對于每個分類器,我們將可視化它們的混淆矩陣以獲得更好的可解釋性。混淆矩陣將顯示被錯誤分類的QRs的數量。
隨著混亂矩陣的可視化,以及基線模型的創建和評估,我們已經正式完成了我們的第一個分類模型。
9
構建更多的分類模型
要創建更多的模型,我們所要做的只是復制基線模型的代碼,然后修改幾行代碼。下面是一個模型的代碼(與DummyClassifier非常相似):
正如我們所看到的,在代碼中只有兩到三行需要修改來構建每個模型。
我們需要改變的兩三行是:
1、with open(“top10_df.pkl”, “rb”) as fp:只有在測試其他不同特征的數據集時才進行修改。
2、from sklearn.ensemble import AdaBoostClassifier:將這些導入更改為適當的庫及其各自的分類器。
3、clf = AdaBoostClassifier():將這個變量更改為適當的分類器。
其他一切都保持不變。
10
網格搜索——參數調整
在調整模型以適應數據集時,我們可以保持模型不變,也可以通過使用網格搜索來提高模型的性能。通過使用這種方法,我們能夠適當地根據我們的數據集調整每個分類模型的參數。
到目前為止,網格搜索將是最耗時的。不是因為我們的代碼很多,而是因為每個參數組合的迭代數量。有些模型需要比其他模型更長的時間來進行網格搜索,但是整個過程仍然需要相當多的時間,因為我們將網格搜索我們擁有的每個模型。
網格搜索的代碼對于每個模型基本上是相同的,我們只需要修改幾行代碼。
正如大家所看到的,需要編寫的代碼并不多,實際上這里有一些我們以前使用過的代碼(分類報告和混淆矩陣)。
需要改變的是:
params變量,它將是一個字典,字典的鍵對應于相應的分類器參數,字典的值是我們希望為每個迭代嘗試的不同值。
當變量最初被更改以適應每個新的分類器時,clf早就應該被更改了。
1、網格搜索的參數
這些參數需要設置為適合我們自己的個人需求。正如我們所看到的,clf 和 params 已在上面處理。但對于其他參數:
2、F1分數宏平均(macro-average)
F1分數優先于精確率的原因僅僅是分類的數量。當精確率被優先化時,精確率分數可能會顯著增加,但被歸類為某些類別的QRs的數量會大大減少。 在我們的示例中,分類器很少對 Buy 或 Sell 進行分類,但是許多分類都在 Hold 類中。 這是因為 Hold 類是大多數類。 我們不希望我們的分類器很少告訴我們什么時候投資,我們希望至少有一定數量的機會屬于召回率得分。
為了在精確率和召回率之間取得平衡,我們會優先考慮F1的分數。我們之所以選擇宏觀平均而不是微觀平均,是因為宏觀忽視了階級不平衡。持有類,作為占主導地位的類,當涉及到投資活動時,我們幾乎什么都不知道,因為我們更想知道股票是買還是賣。總的來說,使用F1分數宏平均值將允許網格搜索在我們喜歡的條件下找到最佳參數。
11
每個分類模型運行和評估
現在我們有了數據、分類器代碼、評估報告和網格搜索代碼,我們可以將它們應用到每個分類模型中。
1、保存分類模型
一旦我們決定了哪個模型最適合我們的數據,我們就可以用正確調優的參數保存擬合的模型。看看下面的代碼,看看如何保存一個模型(只有兩行代碼):
這段代碼將導出我們的模型以供其他文件使用。
2、表現最佳的模型
在我們的例子中,性能最好的模型來自XGBoost分類器,它使用了來自樹分類數據集的前10個重要特征。該分類器的分類報告如下:
正如我們在這里看到的,與基線模型相比,在XGBoost模型中,Buy類增加了10%,Sell類增加了20%。這是對DummyClassifier模型的重大改進。在很多方面,我們基本上是在預測未來。如果我們的分類器能夠以47%的準確率來決定一個股票是否值得投資,那么我們應該認為這是一個重大的突破!
12
分類新數據
假設我們想用分類器來預測一個新的QR。我們怎么才能做到呢?最好的選擇是找到最近的QR和以前的QR的值。然后,觀察它們之間的百分比變化,以便它們與我們自己的數據集的格式匹配。
新的數據可以從許多報告QRs的網站獲得,我們可以通過網絡搜集這些值,也可以手工輸入。Stockpup也有最新的QRs,對于本文來說,我們將利用該網站的最新值。在前面的部分中,我們從每個庫存中刪除了最新的QR,因為沒有未來的最高和最低價格用于我們的類標簽。所以這些QRs仍然沒有被標記,但是現在我們可以用分類器的預測來標記它們。
1、最新的QR和可視化輔助函數:
在處理新數據時,為了與配合分類器,我們必須對數據進行擴展,因為我們最初就是這樣訓練分類器的。必須對數據進行處理,以包含百分比修正、正確的特征列和與其他相關數據的縮放值。一旦我們有了所有這些,我們就可以對最新的QR進行分類。
2、分類最新的QR
在這個例子中,我們將使用來自AMD的最新QR:
根據我們的分類器,AMD有42.5%的機會持有。最主要的概率將決定分類器如何確定股票的名稱。
13
結論
根據季度報告來決定股票價值并不是什么新成就。對于大多數基礎分析人員來說,我們使用的策略可能被認為過于簡單或過時,但是對于學習機器學習分類來說,這已經足夠了。我們可以添加更多的特征來改進模型,或者根據新的策略改變現有的特征。
我們甚至可以用神經網絡做實驗,看看它們是否能比我們現有的模型表現得更好。我們將在未來的文章中給大家講解!
14
獲取全部代碼(手慢無!)
2020年第22篇文章