【Season3-24】Binary Prediction of Smoker Status using Bio-Signals【データコンペ05】
コンペ概要
Your Goal: For this Episode of the Series, your task is to use binary classification to predict a patient's smoking status given information about various other health indicators. Good luck!
コンペ詳細
目標
smoking
is the binary target
喫煙者かどうか
- not smoker:0
- smoker:1
データ
課題種別:分類
学習データサンプル数: 159256
説明変数の数:23
欠損値:なし
Column | Dtype | Explanation |
---|---|---|
id | int64 | ID |
age | int64 | 年齢 |
height(cm) | int64 | 身長 |
weight(kg) | int64 | 体重 |
waist(cm) | float64 | ウエスト |
eyesight(left) | float64 | 視力(左) |
eyesight(right) | float64 | 視力(右) |
hearing(left) | int64 | 聴力(左) |
hearing(right) | int64 | 聴力(右) |
systolic | int64 | 血圧(高) |
relaxation | int64 | 血圧(低) |
fasting blood sugar | int64 | 空腹時血糖 |
Cholesterol | int64 | コレステロール |
triglyceride | int64 | 中性脂肪 |
HDL | int64 | コレステロールの種類 |
LDL | int64 | コレステロールの種類 |
hemoglobin | float64 | ヘモグロビン |
Urine protein | int64 | 尿タンパク |
serum creatinine | float64 | 血清中クレアチニン |
AST | int64 | アスパラギン酸アミノトランスフェラーゼ |
ALT | int64 | アラニンアミノトランスフェラーゼ |
Gtp | int64 | γ-GTP |
dental caries | int64 | 虫歯 |
smoking | int64 | 喫煙(目的変数) |
評価指標
Submissions are evaluated on
area under the ROC curve
between the predicted probability and the observed target.
AUC:0から1までの値をとり、値が1に近いほど判別が高い。
判別がランダムであるとき、AUC = 0.5
情報公開ポリシー
A Data Access and Use.
Competition Use and Commercial: You may access and use the Competition Data for any purpose, whether commercial or non-commercial, including for participating in the Competition and on Kaggle.com forums, and for academic research and education.
A データのアクセスと使用。
コンテストでの使用および商用: お客様は、コンテストや Kaggle.com フォーラムへの参加、学術研究や教育など、商用か非商用かを問わず、あらゆる目的でコンテスト データにアクセスして使用することができます。
学習の目的
選択理由
- SIGNATEでコンペに参加をしたのでKaggleでも参加してコンペの幅を広げるため
- 簡単めであるPlayground Seriesから最新のコンペを選択
目標・目的
- Kaggleに慣れる
- 前回振り返ったデータの確認やそこからの予測
- 順位的なことは気にしない
分析
コンペの流れ
- ベースライン作成
とりあえず全体を粗削りながらも通してやってみる。そこで問題点や注意点に気づくもよし。とりあえず流れを抑える。 - データの確認
データを詳しく確認しながら予測を立てる。(重点的に意識) - 特徴量生成
有効な特徴量を作る。振り返りで特徴の作り方など見ていくのでなんとなくで。(振り返りはここを意識) - 振り返り
一番大事な奴。英語なので読むのは大変かもしれないが公開されるであろうコードを読み解いていきたい。
ベースライン作成
簡易的なデータの確認をしてからベースラインの作成をしていきます。 データが大きいのでメモリを削減するコードを実行しています。
気になる点はinfo()で確認した型の揺れ。おそらくメモリ削減の際に揺れてしまったのでしょう。これはいいことなのか。いまいち判断しかねます。
今回の場合describe()で確認した際にmeanがnan表記になっていたことを考えるとよくなかったかもしれません。おそらく桁数が大きすぎた結果?
欠損値は前もってあった情報通りなし。
目標値であるsmoking
のばらつきはそこまで大きくないといえるでしょう。
ベースラインの説明変数には血圧や肥満度に関係がある特徴量を3つ‘["systolic","triglyceride","HDL",]`選択し進めていきます。
問題なくベースラインができたので重要度も確認します。中性脂肪の値がかなり大きい重要性ということがわかったのでこれも踏まえてデータの確認をしていきます。
データの確認
smoking
目的変数。喫煙しているかどうか。
2値のカテゴリ。
先述した通り少しだけ偏りがあり、43%ほどが喫煙していることが確認できます。無難に等しい割合で訓練データ、テストデータに分けておくのが無難だと思われます。
ちなみに日本人の喫煙率は16.7%だそう。
id
ID。インデックスとして使用。
age
年齢。int属性。
ヒストグラムを確認すると40代だけ突出しています。これは集計方法に問題を抱えていそうな予感。
目的変数別にみてみると40代以下では50%を超え、年齢が上がっていくにつれて下がる傾向に見えます。
年代別で確認してみると右肩下がりなことが確認できます。
height(cm)
身長。
170cmあたりを中心にわりかし左右に等しい山。身長は正規分布に従いやすいそうなので当然っちゃ当然なのかもしれません。
目的変数別のヒストグラムでは大きく違いがあります。中央値が160,170なので男女での喫煙率の違いとみても良さそうです。日本人の場合、男女別の喫煙率は男性 27.1%、女性 7.6%。有用な説明変数ぽそう。
weight(kg)
体重。int。
こちらも男女混合のヒストグラムなのだろう。
体重もが慎重と同様に重いほうが喫煙率は高い傾向にあることがわかります。ただ身長と体重は相関が高い可能性があるので注意が必要かもしれません。
waist(cm)
ウエスト。float64。
こちらも正規分布に近い。
わずかではあるがずれがある。身長ほどは男女でみてもそこまで大きな差はないのかもしれない。
わずかなずれがあるデータは二乗などのデータ変換を使えば顕著に表れるのかもしれない。
eyesight(left),eyesight(right)
視力(左)、視力(右)。float64。どちらも似たようなデータだったのでまとめ。
0~2に収まりそうだがヒストグラムでは左に寄っている。
確認してみると9.9という値がある。視力9.9はどこかの部族であれば可能性としては有り得るが現実的ではないので欠損値であると判断。
中央値を代入し、9.9であったところはフラグを立てて情報が失われないように対処しました。
hearing(left),hearing(right)
聴力(左)、聴力(右)。int64。どちらも似たようなデータだったのでまとめ。
intだが数値ではなくカテゴリととらえるほうがよさそうです。聞こえた聞こえないの2値分類であると思われます。
割合で比べると1のほうが10ポイント程高くなっています。
この2つの間には年齢の違いがあります。喫煙による聴力の低下かもしれませんが、年齢による聴力の低下ととらえるほうがいいかもしれません。
年齢でうまく効かない場合、こちらを特徴として採用してもいいかもしれないということ。
systolic
int64。血圧(高)。喫煙による血管が固くなることで血圧が上がりやすくなるのだそう。しかし喫煙後15分があがりやすかったりといろいろな情報がある。
高血圧と呼ばれる状態が上が140以上らしいです。そこあたりに注目してもそこまで大きな変化はなく似たような分布。
relaxation
int64。血圧(低)。こちらも血圧(高)と同様。
高血圧は下の場合、90以上。こちらもいまいちな気がします。血圧の数値は他と組み合わせて使うほうが有効な気がします。
fasting blood sugar
int64。空腹時血糖。
喫煙の空腹時血糖に及ぼす影響は肥満度により異なるそうです。BMIを作って掛け算して使うと効果的かもしれません。
Cholesterol
int64。コレステロール。
あまり参考になる情報は見つけられず。調べても調べてもHDLとLDLしか出てきません。
おそらく肥満度に関係あるので有用...か?
triglyceride
int64。中性脂肪。基本的に中性脂肪の増加は暴飲暴食。そこからさらに喫煙によって中性脂肪の増加を促されるそうです。
基準値は30~149。グラフでは100を超えたあたりから割合的にはかなり高くなっています。
よりわかりやすく50ずつに区切って集計してみたところ右肩上がりなのがよくわかります。400以上は母数の少なさによって100%をたたき出しています。
HDL
int64。コレステロールの種類。喫煙によって低下する値。
たしかに山が左にずれています。基準値は40。それ以下で異常値なのでそこのフラグを立ててもいいかもしれません。
LDL
int64。コレステロールの種類。HDLとセットで語られがち。こちらは喫煙によって上昇する値。
あまりにヒストグラム上で左に寄っていたので箱ひげ図です。外れ値が多くほどんどが250以内に収まっている中で1700を超えています。
500以上の値を500にクリップしました。もう少し小さい値でクリップしたほうがいいのかはわかりません。120以上で注意、150以上で危険というあたいなのでそこらへんでフラグを立ててみてもいいかもしれません。
hemoglobin
float64。ヘモグロビン。喫煙によってヘモグロビンが一酸化炭素と結合するため全身への酸素の供給量が減少し、その結果、ヘモグロビンが増加する代償現象が起こるそうです。
かなり右側に喫煙者が寄っているので有用な説明変数のひとつととらえていいでしょう。
右肩上がりなことがよくわかります。さらには13以下であれば喫煙の割合はかなり低いので有用な変数といえるでしょう。
Urine protein
int64。尿タンパク。喫煙は血管を収縮させて腎臓の血流量を落としますし、血管そのものの障害も起こします。その結果、タンパク尿を増やす、そうです。
数値というよりはカテゴリ属性にみえます。割合に大きく差があるので別のグラフで見てみます。
喫煙割合をカテゴリ別にみてみると40%前後を推移しています。6では0となっていますが母数が少ない(6)のであまり気にしなくてもよさそうです。あまり有用そうには見えない。
serum creatinine
float64。血清中クレアチニン。主に腎機能に関係している。
ほぼほぼ0~2に収まっています。カテゴリではなく数値データ。扱いに困るデータ。どうすればいいのでしょうか。
AST
int64。アスパラギン酸アミノトランスフェラーゼ。肝細胞のひとつ。肝臓に障害が起こって肝細胞が壊れると、増加する。
こちらも値が大きすぎたので最大値100でクリップしました。ぱっとみそこまでわかりやすさがある変数ではないです。
大きく見ると上がっているように見えるが50%あたりを推移しながら分散が大きいのを確認。単体では使いにくそうです。基準値は40以内。
ALT
int64。アラニンアミノトランスフェラーゼ。肝細胞のひとつ。肝臓に障害が起こって肝細胞が壊れると、増加する。 ASTとセット。
こちらも最大値150でクリップしたグラフ。
こちらも分散がおおきいです。単体では使いにくいのでセットであるASTと使うとよさそうです。比率とかで。肝障害の場合、ALT > ASTだそうです。基準値は40以内。
Gtp
int64。γ-GTP。肝臓に中性脂肪がたまりそれが原因で起こった肝炎でも、γ-GTP値が上昇することがわかってきました。
あまりに外れ値が大きかったのでこちらも最大値200にクリップしたグラフ。男性の場合基準値は80以内ですが25以上ですでに大きい割合の変化が確認できます。
右肩上がりで割合が上がっています。かなり有用な変数であると思われます。
男性:80 IU/L以下、女性:30 IU/L以下が基準値。25を超えたあたりから上がっていることを考えると女性の喫煙者が割合を挙げている要因かと考えられます。
dental caries
int64。虫歯。喫煙は虫歯が発生しやすい口腔環境を作りやすい傾向にあるそうです。
0/1のカテゴリデータ。おそらく1が虫歯がある状態であると考えられます。
dental caries 0 0.410934 1 0.545284
割合でみると少しではありますが偏りがあります。
ヒートマップ
対になっている関係(視力や血圧)、身長と体重などの相関があることがわかります。多重共線性を気を付けるラインが相関係数0.8以上なので注意して進めていきます。
仮説
男女での違いが大きく喫煙率に違いが出てきそうです。なので身体的特徴である
height
,weight
,waist
を特徴量にするとよさそうです。ただこれらは相関関係が高いので様子を見ながら採用していきたいところ。大きく違いが出ていた
triglyceride
,hemoglobin
,Gtp
の血液で違いが出るものは男女に大きな違いがないと思われるので差が表れそうです。視力や聴力は微妙な可能性。年齢の低下によるものがあるから扱いは慎重に。
肥満度が喫煙に関係していそう。というよりかは喫煙することによって運動量の低下、食事量の増加などによって結果的に肥満になるというほうが正しい気がする。
特徴量生成
BMI
ボディマス指数と呼ばれ、体重と身長から算出される肥満度を表します。聞き馴染みのある指数です。
BMI = weight(kg) / (height(m) ** 2)
LH_ratio
LDLとHDLの比率。この比率が2倍あると動脈硬化が疑われる水準なのだそう。
LH_ratio = LDL / HDL
blood_pressure
血圧の割合。
blood_pressure = systolic / relaxation
height_weight_ratio
身長と体重の割合
height_weight_ratio = height / weight
AST_ALT_flag
ASTがALTより多いと注意が必要だそう。フラグ。
各項目の異常値
危険の水準で血液の各項目をフラグ。
クラスタリング
テストデータを含めてオリジナルデータで3つにクラスタリング。
サブミット
モデル:LightGBM, RogisticRegression
スコア: Private Score:0.86749 → Public Score:0.87082
順位:730 → 849 / 1,908 teams
説明変数
仮説を立てたとおり、
height
,triglyceride
,hemoglobin
,Gtp
の説明変数はLightGBM,LRの両モデルで有用な説明変数でした。目標であったデータを確認して予測を立てるという点はなかなかうまくいったかなと思います。異常値でフラグをたてたりなどデータの確認をしたことで新しい変数を作成することができました。これもまたデータの確認からうまくいったことのひとつ。
Kmeans法でクラスター分けをしてみたが変数の重要度はかなり低く、全然うまくいっていないといっていきませんでした。クラスターの分け方がよくなかったのか、扱いが違うのか、振り返りで確認したいところです。
モデル
コンペ中のDiscussionでは私と同様LightGBMを使っていた人をたくさん見かけました。そこではほとんどの人が元々のすべての説明変数に加えてに新たな変数を加えてモデルを学習していました。
LightGBMでは重要度が0になることもあるのでそこらへんは加えてみるのも手なのかもしれません。アンサンブルで2つのモデルでを合わせてみましたが、いまいちロジスティック回帰のモデルは精度が向上しませんでした。アンサンブルの比率も9:1でいいスコアが出たのでもう少しスコアを向上させてから合わせたかったです。
結果について
順位は大きく下がりましたがスコアは伸びたのでまあよしという感じでとらえています。
今回は慣れることが第一だったので今回のことを生かして次回以降は順位も伸ばせて行けたらと考えています。
振り返り
説明変数
130~140ほどの説明変数を作成。どれもがうまく機能しているわけではないので削除する必要はあったが精査された変数が残る。
変数の作成量がすごい。LightGBMでは加算より乗除が新たな変数を作成するうえでは効きやすいと聞いたのでいろいろ作ったりして試したのでしょう。ここまでいかなくてももっと試すべきでした。有効な説明変数同士の掛け算も説明変数として有効な場合がある。
カテゴリ変数は回帰する場合も考えてOHEしておく。
モデル
モデルのなかでもパラメータを変えていくつかつくっている。今回のケースであれば身体的特徴だけのモデル、血液の特徴のモデル、それを組み合わせたモデル3つは少なくとも作れたはず。ロジスティック回帰が微妙なのであればLightGBMをアンサンブルしてしまえばよかったのかもしれません。
モデルを複雑にしすぎてはいけない。シンプルなモデルにはパワーがある。格言かもしれない。
その他
- 以前に似たようなコンペがあったらそれを参考にする。これは一通り終わったら確認してみてもいいかもしれません。
反省点
データの確認
まだまだ甘いところはあると思いますが、データの確認からの予測、変数の作成は良い感じにできたと思います。初回ながらも。次回以降も続けていけたらと思います。
試行錯誤が足りない
終わってみればあれやればこれやればが出てきます。書き溜めておいて見直していろいろな試行錯誤をしていきたいです。変数130個作るのは厳しいかも。
Discussion/Codeを読む
これは慣れていなかったのでしょうがない部分ではありますが、読み返してみると有用な情報が大いにありました。途中から参加すると英文の量に腰を抜かす可能性もあるので序盤から少しずつ読んでいけばと思います。
最後に
Kaggleに慣れながらコンペをするというものでしたが、なかなか面白く挑戦することができました。なんといっても情報量がすごいです。
読んでも理解できないことがたくさんありますが、少しずつ知識を増やしていければと思います。次回は上位30%を目指して頑張りたいと思います。