作者:chen_h
微訊號 & QQ:862251340
微信公眾號:coderpai
簡書地址:http://www.jianshu.com/p/af7e…
上個星期,我花了一些時間參加了 Numerai 的機器學習金融比賽。這篇文章就是我對於比賽的一些筆記:我嘗試過得一些方法,我做了什麼工作以及什麼工作我直接放棄不做。首先,讓我們來介紹一下這個比賽和平臺:
Numerai 是一家對衝基金,它利用比賽的形式來收集使用者的策略,然後在內部對這些策略進行組合整合來交易。這個平臺還有一個獨一無二的地方是它對所有資料都會進行加密。每個星期,Numerai 都會重置比賽,然後公佈一個新的資料集。然後經過一週短短的比賽,來評出第一名和第二名。這些名詞不是單單利用比賽的分數來評定,還會有策略的原創性來考核。截止到這週末,我的策略的 log loss 在 0.68714。這個分數大約可以獲得價值 $ 8.17 的比特幣價值。
下面是訓練資料的一個示例:
feature1 feature2 feature3 feature4 feature5 feature6 feature7 feature8 feature9 feature10 feature11 feature12 feature13 feature14 feature15 feature16 feature17 feature18 feature19 feature20 feature21 target
0.801620682063483 0.954026655642816 0.5705311667363 0.144232717229754 0.0500492688121434 0.0786789084265974 0.929508009336688 0.171077685785306 0.883034072289284 0.179369932130713 0.943269363053669 0.0288614434941082 0.1991065940751 0.968784322087461 0.064581284883459 0.916191480500131 0.238189399122635 0.0936556660484072 0.206537285119826 0.160288788368154 0.659444719296122 1
0.54007050183969 0.459006729530628 0.933131512414551 0.499801268888154 0.437992709228964 0.267235986043502 0.49719463349721 0.456020915709475 0.609753221442359 0.187454050581248 0.469354733168323 0.118559329564251 0.129507550533594 0.479953630810717 0.416888497364001 0.634561462124642 0.710520556134985 0.324297337296292 0.339857563207418 0.349509997045832 0.432920679407234 1
0.518214112985959 0.383788083593395 0.424871302717305 0.792762973770667 0.7742857173559 0.451385276234671 0.791400908677086 0.845301217143346 0.11862555750929 0.419257487945476 0.376741188540958 0.625610979113513 0.266524021808175 0.648017340815601 0.420797663214614 0.00431873269449817 0.992130143506543 0.718080611565518 0.992093533667718 0.134067138702938 0.0743077276110433 0
0.806453569351584 0.161343358248138 0.636975566410459 0.20171554254616 0.420537856699983 0.151818600989567 0.305146784581374 0.117884737420495 0.6108915265627 0.249714474623046 0.819308099139668 0.250770579717342 0.205248270449002 0.0862103305974124 0.532109927231077 0.790242340397417 0.198781520011354 0.274051362170583 0.192056729456156 0.0975874452607068 0.669890711788048 0
0.415003336362225 0.170186235034517 0.418823297694966 0.471830387551152 0.570765150255677 0.213788507104613 0.158155235117551 0.0117300575807448 0.418275738366933 0.558753991377777 0.179990534571358 0.436470111914978 0.506977165129181 0.300005858796116 0.742479443088257 0.206816619126046 0.814364270840413 0.331907239807323 0.0654237310678893 0.406143623934384 0.746499721419085 0
0.704449319534233 0.850338911254686 0.455998303770994 0.224563394324338 0.6995439084974 0.834721324063086 0.74728784556282 0.901345710496236 0.497415817686694 0.903353074258274 0.571234586425579 0.700451571955351 0.834000656317827 0.729095524732872 0.81078297616965 0.609452318787617 0.192694538456569 0.621665212601283 0.737860261408827 0.194185986803504 0.364996083433718 1
0.788055769180724 0.0545958246530098 0.200827379203853 0.0673784077815309 0.941077448055137 0.778947613783854 0.116750357635139 0.22800316108405 0.136388118235054 0.964284570466578 0.504061018335779 0.990569143158103 0.784283053374759 0.0393941086088943 0.933946479526913 0.669042714854619 0.138144590100865 0.918439009896414 0.880195626011122 0.0703418399004744 0.479384331357069 1
0.188297550227483 0.604074503040718 0.0183412656148252 0.81576618771192 0.518477669691875 0.803097540388692 0.711386433623059 0.652814191221587 0.0526464320116979 0.817774122488179 0.237459905042212 0.602959633090017 0.730338364463652 0.586008172371978 0.416888497364001 0.223150580662151 0.626276488264701 0.963008567409791 0.689730272299441 0.689253363243162 0.132085515045565 0
0.820315384108692 0.637408836538877 0.907437156607062 0.243122252397027 0.378765978591899 0.25798160900915 0.983337691578471 0.355088818872554 0.88329260758454 0.12352921389316 0.71346744394059 0.369877122677724 0.221232749108118 0.812421645851051 0.112857777466973 0.709823231860924 0.598130707018941 0.0413007685381965 0.50006278551784 0.266615825161751 0.735885538367622 1
驗證
我在比賽中的第一步就是設計我們的驗證集,以方便我們在本地測試我們的模型效能,從而可以對模型在排行榜上面的排名可以有一個預估。如果我們只是簡單的對資料進行分割,那麼驗證結果並不能正確的反應在排行榜上面,所以在這裡我採用的是 “對抗驗證”。這個聰明的想法是 @fastml 中的一個想法,具體部落格在這裡。具體思想如下:
- 訓練分類器,並且確定資料的來源,是來自訓練集還是測試集;
- 按照測試資料集中的概率分佈對訓練資料進行排序;
- 選擇與測試資料最相似的訓練資料作為驗證集;
按照這種方法設計的驗證集,我們把相同的模型在公開排行榜上面進行測試的時候,得到的 log loss 誤差大約在 0.001 左右。有趣的是,相對於訓練資料,測試資料是不滿足 IID 的條件。
基準模型
現在我們已經有了一個非常好的驗證集,之後我們需要去設計一個模型,並且對這個模型進行驗證和上傳結果,這個模型就作為我們的基準模型了。作為起點,我就是用最簡單的邏輯迴歸並且沒有用任何的特徵工程。這個模型在驗證集上面得到了 0.69290 的結果,在公開的排行榜上面得到了 0.69162 的結果。這個結果並不好,但是我們的目的達到了,現在我們擁有了一個初始目標。為了進行比較,第一名目前的得分為 0.64669,所以我們最簡單的基準分數與它之間的大約只有 6.5% 的差距。這也就意味著我們對於基準模型的任何改動,對最終的排名結果的影響都是非常小的。我們在對基準模型加上 1e-2 的 L2 正則化之後,這在排行榜上面達到了 0.69286 的正確率,比基準測試提高了 0.006 。
神經網路
在開始使用特徵工程之前,我快速的瀏覽了一下神經網路演算法。在理想的情況下,神經網路可以從足夠多的原始資料中學習到特徵,但不幸的是,我嘗試過目前所有的神經網路架構,但是他們取得的效果都不能比簡單的邏輯迴歸有很大的改進。此外,深度神經網路需要比邏輯迴歸更多的引數,所有我們需要去使用 L2 正則和批量歸一化來規範引數,給模型加上 Dropout 也可以給架構帶來效能的改進。
一個有效但是非常有意思的架構是使用一個非常寬的隱藏層(2048個神經元),擁有很高的 Dropout 值(達到 0.9),並且在開始訓練的時候我們需要對初始化引數做一個固定設定。因為擁有很高的 Dropout ,所以這就造成了很多的整合模型。雖然這個模型能很好地工作,大約可以達到 0.689 的正確率,但是該模型太有個性,最終還是不打算採用這個模型。最後,神經網路沒有在這個問題中得到比較好的結果,所以我們沒有在神經網路的改進上花費更多的精力,而且本文我們主要分析我們的特徵工程。
資料分析與特徵工程
現在我們需要去挖掘我們的資料價值,先從一個簡單的特徵分佈圖開始吧。具體如下:
每個特徵的分佈都是非常相似的,那麼特徵之間的相關性如何呢?我們也畫了一個圖,如下:
][7]
從圖中,我們可以看到很多的特徵之間是強相關的。我們可以通過多項式關係在我們的模型中使用這一個特性。根據這個性質,我們在驗證資料集上面取得了 0.69256 的成績。
接下來,我們來做降維處理。我們採用的是 PCA 來把維度下降到二維,然後進行視覺化操作,如下:
從圖中我們得不到很多有用的資訊,那麼嘗試一下多項式特徵如何?如下圖:
多項式 PCA 通過將很多目標是 “1” 的值拉向邊緣,並且把目標是 “0” 的值拉向中間,從圖中看效果比前面一個好了很多。但是看起來還不是很好,所以我打算放棄使用 PCA,而使用別的方法。
我們將使用一種稱為 t-SNE 的方法,t-SNE 通常用於高維資料的視覺化,但是它擁有一個 PCA 沒有的特性:t-SNE 是非線性的,並且根據兩個點的概率來選擇是否作為中心點的鄰居。
這裡,t-SNE 獲得了很好的的視覺化結果。我將這些 2D 特徵新增到我們的模型中,獲得了目前最好的 log loss 成績:0.68947,。我懷疑這個起作用的原因是區域性特徵,邏輯迴歸不能從資料中得到這些區域性特徵,但是這些區域性特徵對我們的分類是非常有效的。
由於 t-SNE 是隨機的,我們每一次的執行結果都會產生不一樣的結果。為了利用這一個特性,我們需要在不同的困惑度和維度(2D或者3D)上面,執行 t-SNE 五到六次,然後去分析這些額外的特徵。最後,根據這個結果,我們的驗證成績達到了 0.68839 。
附加嵌入資料
由於 t-SNE 可以很好地工作,所以我又採用了集中其他的嵌入方法,包括自動編碼器,去噪編碼器和生成對抗網路。自動編碼器可以對原始資料進行重新建模,而且建模的正確率可以高達 95% 的正確率,即使我們的資料中有噪音,但是這種嵌入表示並沒有造成很大的影響。GAN,包括各種半監督的變體,他們的效能並沒有超過簡單的邏輯迴歸模型。我還是重點關注非線性降維犯法,比如核心PCA和等值線。但是這些方法很花費計算時間,減少了我迭代的次數,所以最終我還是把他們拋棄了。我沒有嘗試過 LargeVis 或者引數 t-SNE,但是他們都是非常值得研究的,因為它們可以保持一定的適應性,而不是將所有的學習樣本一次輸入。
資料互動
其中一個整合模型是資料互動。基本上,從兩個樣本的特徵可以直接看出,兩個樣本中哪個樣本更大的可能性會被歸類為 “1”。由於我們是對樣本之間的互動進行建模,而不是對單個樣本,因此根據這一個特性我們可以得到更多的資料。我們還可以根據我們的分類結果,從而從資料中學習到更有用的特徵。
超引數搜尋
現在我們有一些有用的特徵和一些效能良好的模型,所以我想執行一個超引數模型,看看它是否可以勝過現有的模型。由於 scikit 包只能用 GridSearchCV 和 RandomSearchCV 進行探索超引數,而不是整個架構,所以我選擇使用在兩者之間的 tpot 包。我發現,使用隨機 PCA 的效能由於 PCA,並且 L1 正則化(稀疏性)略由於 L2 正則化(平滑),特別是跟隨機 PCA 進行配合使用。不幸的是,我們所發現的資料之間的關聯性並沒有用在最終的整合模型中:手工工程取得了勝利。
整合
我們已經完成了幾個模型,是時候對這幾個模型進行整合預測了。整合開發有很多的方式,我們這裡採用的是最簡單的基於幾何平均值的簡單平均值。
最後的整合模型我們採用了 4 個整合模型: logistic regression, gradient boosted trees, factorization machines 和 the pairwise model。我對每個模型都是使用相同的特徵,特徵由原始的 21 個特徵組成,並且在 5,10,15,30 和 50 的困惑度下,在 2D 中執行 t-SNE 五次,以及在 3D 中執行 t-SNE 一次(困惑度 30)。這些特徵與多項式特徵相互結合,並且應用到模型中,這個整合模型最終得到的分數是 0.68714 。
結論
總體而言,這是一個非常有趣的比賽,它和 kaggle 最不同的地方是它的資料是加密的,而且它獨特的獎金分配製度也是吸引我的一個地方,但是我更傾向於將獎勵看做是積分,而不是貨幣,因為這使得競爭更加樂觀。另一方面,現在我有了我的第一個比特幣 ?
完整程式碼,可以點選 Github。
作者:chen_h
微訊號 & QQ:862251340
簡書地址:http://www.jianshu.com/p/af7e…
CoderPai 是一個專注於演算法實戰的平臺,從基礎的演算法到人工智慧演算法都有設計。如果你對演算法實戰感興趣,請快快關注我們吧。加入AI實戰微信群,AI實戰QQ群,ACM演算法微信群,ACM演算法QQ群。長按或者掃描如下二維碼,關注 “CoderPai” 微訊號(coderpai)