做者:chen_h
微信號 & QQ:862251340
微信公衆號:coderpai
簡書地址:http://www.jianshu.com/p/af7e...git
上個星期,我花了一些時間參加了 Numerai 的機器學習金融比賽。這篇文章就是我對於比賽的一些筆記:我嘗試過得一些方法,我作了什麼工做以及什麼工做我直接放棄不作。首先,讓咱們來介紹一下這個比賽和平臺:github
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 。dom
在開始使用特徵工程以前,我快速的瀏覽了一下神經網絡算法。在理想的狀況下,神經網絡能夠從足夠多的原始數據中學習到特徵,但不幸的是,我嘗試過目前全部的神經網絡架構,可是他們取得的效果都不能比簡單的邏輯迴歸有很大的改進。此外,深度神經網絡須要比邏輯迴歸更多的參數,全部咱們須要去使用 L2 正則和批量歸一化來規範參數,給模型加上 Dropout 也能夠給架構帶來性能的改進。機器學習
一個有效可是很是有意思的架構是使用一個很是寬的隱藏層(2048個神經元),擁有很高的 Dropout 值(達到 0.9),而且在開始訓練的時候咱們須要對初始化參數作一個固定設置。由於擁有很高的 Dropout ,因此這就形成了不少的集成模型。雖然這個模型能很好地工做,大約能夠達到 0.689 的正確率,可是該模型太有個性,最終仍是不打算採用這個模型。最後,神經網絡沒有在這個問題中獲得比較好的結果,因此咱們沒有在神經網絡的改進上花費更多的精力,並且本文咱們主要分析咱們的特徵工程。ide
如今咱們須要去挖掘咱們的數據價值,先從一個簡單的特徵分佈圖開始吧。具體以下:性能
每一個特徵的分佈都是很是類似的,那麼特徵之間的相關性如何呢?咱們也畫了一個圖,以下:
][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)