使用GradientBoostingClassifier對於特徵選取結果問題
首先是關於【GradientBoostingClassifier】,我建議在教材重點中,都應該至少提到一次每次跑的結果都會不一樣,這樣可以少掉許多學員的疑問。
但接著真正的疑問是,以下是我跑了10次的結果,也與多名學員貼上來的數據雷同:
應該非常清楚,不管有什麼「每次跑都會不一樣」的這種問題,透過上圖,應能很清楚看出重要程度依序是:Sex、Pclass、Fare、Ticket,而往後的分數差異不大,名次也常替換,但Name無論如何都不會是一個很重要的特徵。(相信老師如果多跑幾次,也會發現這件事。)
而這是答案的結果:
1. 所以這是第一個問題,為什麼我們跑了十多次的結果,很明顯不會出現答案這樣的數據與排名,答案是否用了與我們不同的資料,或是不小心已經處理過了(只是忘記了順序),才導致這麼大的差異。這並不是【每次跑結果都會不一樣】就能解釋的。
2. 雖然我們應該會去懷疑答案中的Name不應該出現這麼高的分數才對,因為以【常識理解】(這是Day13老師教的),都會知道Name和Survived理應無關,也沒有後續分析的意義,這也是前些天某學員有提問到的。但其實我能理解,如果答案跑出來是長那樣,那後面拿了Ticket和Name這兩個object去跑,就還算情有可原啦~
3. 順便彙整一下Day29其他人的疑問,還包括了拿Name和Ticket【相加除以二】以及【相乘】的意義。我確實也不甚理解,根據老師的回覆,相加除以二是【一共有幾個1】、相乘是【or運算】,資質駑鈍,我真的看不懂,不好意思,能否稍加說明?
接著因為Ans用了這相加和加乘之後,分數提升到0.83,看起來好像有效。
但從我的提問1就能得知【背後資料可能是不同的】,所以Ans會有提升,但我們自己做卻不會。
所以我想這Day29整天所有延伸出來的問題,都和我本篇的提問1有關,還有勞個老師解惑,非常感謝!
回答列表
-
2019/05/22 下午 00:40陳明佑 (Ming You Chen)贊同數:0不贊同數:0留言數:3
張同學你好,如果教材尚有不足的地方我們都會繼續優化,但是在你提問的時候是否不應質疑出題專家沒有重複執行過內容,畢竟每個人使用的設備與環境不同,你所遇見的情況,有可能是我無法重現的。
1.針對張同學你跑的結果,你跑10次 我先跑6次給你看
其中執行序號會差3, 是因為我是前面三個Block重新執行
是不是我這邊的結果都如我所說的 : 每次都不一樣, 而且重要性都與你不同
如同你無法重現我這邊的狀況, 希望你也能了解我也無法重現你的狀況
2.的確不該有這麼高的分數, 這點我在寫解答時也覺得很詭異
照理來說以大家的常識來說, 不該出現這樣的結果
老實說我也不太理解, 為什麼同樣的程式, 會有兩大派的結果出現
3.這個問題我已經回在那位同學的問題之下了, 這邊再回一次
相加除以二, 這應該沒什麼問題吧? 就是兩邊總共加起來有幾個1
後面這半部是我打錯了, 應該是And運算,
也就是令1為True, 0為False, 此時只有兩者同時為1/True時, 運算結果才會為1/True
有關同學的提議 : 將執行結果不同的警語, 加入教材之中
這點我們會近期修正於教材之上, 謝謝同學的提問與指教
-
2019/05/22 下午 01:45張小馬贊同數:0不贊同數:0留言數:2
老師我有看你在另外一道題的回覆,【相加的話, 兩邊都是0就是0, 只有其中一邊為1就是1/2, 兩邊都是1就是1, 這應該沒問題吧】、【如果把1當True/0當False, 則只有當兩邊都是True時會輸出True】。我有問題,真的。
如上圖所示,相加除以2要符合0,1/2,1的前提,是Name和Ticket只有0或1兩種選擇,但上圖經處理後卻不符合這樣的前提,Name和Ticket是落在0~1之間的任意小數,這也會造成【Add_char】不會只有0,1/2,1三種其中一種。相乘同理,不會有True或False可以看。
我覺得我們說不定快要找出兩大派的癥結點了,是否我們的資料處理,必須把Name和Ticket處理成只剩下0或1兩種選擇,才會跑出和老師您一樣的結果? (但以目前教材的語法並不是這樣,或是我根本就寫錯語法了?)
-
2019/05/23 上午 00:13劉珍銘贊同數:0不贊同數:0留言數:3
我跑出來的結果也是 Ticket, Age, Name 佔據前三位,跑了幾十次 Name 都不會超出三位外。跑出這兩種差異甚大的結果會不會我們下載下來的 data 本身就不同?又或是套件 sklearn 版本不同導致?
因為 Name 太不合理,所以我最後是取 'Ticket', 'Age' 這兩個欄位做後面的題目。
不過如果我們內心早就認定 Name 對於最後的 Survived 完全沒有影響性的話,我們一開始就應該把 Name 欄位整個拿掉,不要再做 LabelEncoder 了,也許做完類別轉成數字之後才產生某種微妙的關聯也說不定。
反之沒有拿掉的話,也許這搞不好是隱藏在其中的影響參數之一,只是我們用一般人理性的頭腦還沒察覺到的規則。譬如以姓名學來說,就會有好名字跟壞名字之分,也許好名字會帶來好運氣,像是 MJ 可能就是個好名字... XD
附上我的 sklearn 版本 0.19.1
(目前官方最新 stable 版本是 0.21.1 Scikit-learn 0.21.1 (stable) documentation (PDF 46.6 MB))
-
2019/05/29 下午 10:46Jimmy贊同數:4不贊同數:0留言數:0
Hi!
我想這個問題在大家後續接觸到 Gradient Boosting Machine 後應該就可以比較清楚原因為何啦。其演算法的架構,在遇到兩個特徵有高度重疊時,會把特徵重要性全部分給其中一個特徵,至於選哪一個特徵則是會一開始對特徵做排序,先選到的優先使用。改用隨機森林演算法後,就不會看到這樣的情形囉 (若是隨機森林,兩個高度重疊的特徵,其重要性會被均分)。
那回到另一個問題,姓名這個特徵在資料裡面真的合理嗎? 有看過電影的同學應該知道,最後船上的共識是先讓婦女、幼童優先上救生船,再來才是商務旅客,所以理論上婦幼的生存率應該會比較高一點,但問題是透過姓名能夠知道性別嗎?答案是...好像可以耶?! 這邊分享一篇只使用姓名當作特徵就能達到超過 0.8 準確率的文章,證明其實姓名是真的是個有用的特徵,只是他與性別高度重疊,但又沒有性別來得明確,才會發生這種同樣的程式碼與資料,但跑出來的結果不太一樣。
我想遇到這樣的問題對要接觸資料科學的同學其實是個非常棒的經驗,試著去了解演算法的缺失,也了解資料中可能隱藏的問題與巧合,正是資料科學有趣的地方 :)