この記事は別室に移転しました。3秒後に転送します。
最近、なんとなく機械学習をちょっとかじるか…と思い、教師あり2項分類問題のコンペに参加してみています(Kaggleと同じような枠組みのやつ)。
まったくの初心者かつ文系おじさんなので、基本的にはchatGPTくんに教えを乞うてコードを書いているのですが、まあchatGPTがあっても結構躓くところは躓くので、初心者が躓いたポイントを簡単に記録しておきます。コードはchatgptにきいてください。
(環境はGoogle上ではなく、ジュピターノートブックでやっています。環境構築は割愛します。よくわかってないし。あと、以下の記載について、誤っている記載がある可能性がありますので、その前提で読んでください。)
モデル作成の流れ
大まかなコードの組み方
だいたい、コードのおおまかな流れは以下の通りです。
- 必要なツールのインポート
- トレーニングデータとテストデータのcsvファイルをデータフレーム化
- 特徴量エンジニアリング(データ整備)
- トレーニングデータをモデルの学習用にトレーニングデータとバリデーションデータに分離
- トレーニングデータでモデルを訓練
- バリデーションデータでモデルの精度を検証
- テストデータを検証
- 検証結果をcsvに出力
おそらく、途中途中でCSVファイルを打ち出して、別のブックで作業したほうが効率がいいような気がしますが、面倒なので、特徴量の分析以外は単一のブックで作業してしまっています。
意外と簡単なので、とりあえず組んでみるのが吉
上記の通り、そこそこのプロセスを経る必要はあるのですが、基本的には特徴量エンジニアリング部分以外はほぼ固定コードで行けます。
よって、ただモデルを一回作ってみるだけであれば、そこまで苦労はしないです。
モデルの訓練についても、データの整備さえいったん行えてしまえば、あとはツールをインポートして、適切にトレーニングデータとバリデーションデータを割り当てて、回していくだけです。
モデルには簡単に回せるモデル、回すまでのデータ加工に色々と留意が必要なモデルがありますが、一旦は色々な要件を無視してそこそこの精度が出るLightGBMがおすすめです。めちゃくちゃ動作が軽いですしね。
(ハイパーパラメータを調整しないと精度でないけど…)
LightGBMであれば、後述の特徴量エンジニアリング部分で最低限必要な加工だけ注意すれば回せるはずです。
特徴量エンジニアリングでやらないといけないこと
特徴量エンジニアリング部分で最低限やらないといけないことは、以下の2つです。
LightGBM使うなら前者は不要ですが、RandomForestやXGBoostなどを使用する場合は前者の加工が必要です。
- 欠損値の確認と加工
- 文字列型(object型)の数値化or削除
それぞれ、欠損値数の確認を行うコードと、データ型を一覧で確認するコードがあるので、chatGPTくんに出してもらって確認しましょう。
欠損値の確認と加工(放置可)
欠損値がある場合、LightGBMなど特定のモデル以外の場合、モデルの学習ができないため、欠損値を0や平均値、最頻値などに変更する必要があることがあります。
lightGBMなど、特に欠損値を気にする必要がない場合は放置しても問題ありません。(lightGBMの場合、欠損値の加工をしないほうが精度を保てたりします)
また、精度を度外視するのであれば欠損値ありの対象を全量削除しても問題ありません
感覚的には全体の5割以上欠損値みたいなデータは削除しちゃったほうがよさそうな感じです。
文字列型(object型)特徴量の加工・削除
次に、文字列型のカラムがデータに存在する場合ですが、文字列型のままではモデルで処理できないため、数値に変更するか、削除をする必要があります。
基本的に削除すると精度が下がるばかりなので、エンコーディングして、数値に置き換えたいところです。
なお、とりあえず動かしてみることを目的として、精度を度外視するのでれば、いったん削除してしまっても問題ありません。
文字列型特徴量のエンコーディングの方法
エンコーディングの代表的な方法としては、「ラベルエンコーディング」と「ワンホットエンコーディング」があります。
前者は1つのカラムの中でカテゴリ種類ごとに数値を割り当てる方法、後者はカテゴリ種類の数だけ0or1のカラムを作成する方法です。
「ラベルエンコーディング」の方がすっきりとしたデータフレームを維持できますし、モデルの学習でも軽く動作できるのですが、1つのカラムで連続的な数値を並べる関係もあり、数値の大小関係など、不要な関係性を捉えてしまう可能性があります。
一方で、「ワンホットエンコーディング」の場合はカラムが無尽蔵に増えてしまう反面、各カラムで該当有無を0or1で判定するため、数値の大小関係が生じず、間違った解釈をモデルが行ってしまう可能性がありません。
「ワンホットエンコーディング」のほうが汎用性が高いのですが、LightGBMやRandomForestであれば「ラベルエンコーディング」でも特段問題ありません。
(自動的に判別し、大小関係のないカテゴリカル変数としてとらえてくれるため。厳密に適用させるにはハイパーパラメータを調整する必要がある?)
コンペ特有の注意点(テストデータと推察結果の提出周り)
トレーニングデータとテストデータを同じように加工しよう
削除や加工をする場合に注意しなければならない点として、Kaggle系のトレーニングデータのcsvとテストデータのcsvがそれぞれ渡されているケースの場合、トレーニングデータだけではなく、テストデータも同じように削除・加工する必要があります。(たぶん)
特徴量のカラム数と名称が同一でないと、モデルで推察ができないためです。
この点は、特にchatGPTにコードを作成させている場合に留意が必要です。
chatGPTは必ずしもKaggle系コンペを前提とした回答を返してくれるわけではないため、chatGPTに頼って作業していると、モデル作成はできるものの、テストデータの推察実行時にエラーが発生してしまいます。
質問の仕方によりますが、chatGPTの「テストデータ」は上記でいう「バリデーションデータ」を指しているため、会話が噛み合わず、エラーの要因を適切に解釈できないまま詰まる可能性があります。
そのため、上記の留意点は人間側で認識した上で、chatGPTにコードを提案させる必要があります。
(とはいえ、トレーニングデータのデータ加工に関する提案は正しいはずなので、基本的にはそのコードをコピーしてデータフレームの名称を書き換えるだけで済む話ではあるのですが)
エンコーディングの際はトレーニングデータとテストデータを結合したほうが無難
尚、削除の場合はトレーニングデータとテストデータのそれぞれのカラムを削除すればよいですが、エンコーディングを行う際には少し留意が必要です。
トレーニングデータとテストデータのカラムに含まれるカテゴリ種類は同一とは限らないため、ワンホットエンコーディングを別々に実施すると、トレーニングデータとテストデータのカラム数に差分が生じ、テストデータの推察が不能になります。
回避する方法としては、以下の2点があります。
- 「ワンホットエンコーディング後にトレーニングデータに含まれないテストデータカラムを削除する」方法
- 「トレーニングデータとテストデータを結合してからワンホットエンコーディングを行ってから再度トレーニングデータとテストデータに分割する」方法
chatGPTが安易に前者のコードを教えてくることがありますが、前者だと情報が失われてしまうので、後者の方法で対応しましょう。
プログラムの順序としては以下のような形です。
- トレーニングデータとテストデータを結合させた新しいデータフレームを作成する
- ワンホットエンコーディングを行う
- トレーニングデータとテストデータを加工したデータフレームの対応箇所のデータで上書きする
特定カラムを削除して学習させたいが、提出時に対象のカラムが必要な場合の処理について
テストデータの推察後の最終提出データに行IDと推察結果が必要な場合などにおいて、モデルの学習対象から除く場合、単純にトレーニングデータとテストデータから対象カラムを削除すると問題が生じる為、少し工夫が必要です。
プログラムの時系列としては、モデル訓練時と推察時には対象のカラム情報が不要、提出時データを生成するタイミングで対象のカラム情報が必要になります。
よって、以下のようなフローで対象カラムを削除する前にテストデータの対象カラム情報を別に記録しておき、推察後の提出用データ作成時に対象カラムの情報を付与してあげることで問題を解消できます。
- テストデータの対象カラムの情報を新しいdfに記録しておく
- 対象カラムの情報をトレーニングデータとテストデータから削除する
- モデルを訓練し、テストデータを推察する
- テストデータの推察結果と保存しておいたテストデータの対象カラムの情報を組み合わせたCSVデータを生成する
全体
というわけで、つまづいたところを記載しておきました。いや、絶賛つまづき中ではあるのですが。
なんかこう、やっぱり慣れないことをやると難しいですね…。
とりあえず以下の書籍が手元にあるとつぎはぎの情報に一本芯が通るらしいので、読もうと思っております。→読んだらすごく良かったです。おすすめ!
Pythonカタカタしているだけだと「あれ…?この一週間なにやっとったんじゃろ…」となるので、また気が向いたら気づき事項とかは記録しておこうと思います。
正直、ノートPCでやると計算力足りないので、つよいPCが欲しいです…。グリッドサーチが終わらねぇー!!!