Kaggleをちょっとやってみた
おはようございます。LiKafです。
今回は、前々から興味があったけどやっていなかったKaggleをちょっとだけやってみたので、備忘録ついでにそれについて書こうかなと思います。
Kaggleの名前は聞いたことあるけどどういうやつか分かってない人とか、そういう人におすすめだと思います。(多分)(適当)
はじめに
Kaggleとは
そもそもKaggleとはなんでしょうか。
公式ホームページによると、以下のようになっています。
DeepL様に翻訳してもらったのが以下です。
『Kaggleは、データサイエンスの目標を達成するための強力なツールとリソースを提供する世界最大のデータサイエンス・コミュニティです。』
コミュニティなので、モデルを公開することができるし、議論をすることもできます(コンテスト中でも)
コンペの成績だけでなく、議論の成績や、公開したコードの成績に対してもランク付けされます。(AtCoderは純粋にコンテストの結果のみでレートが決まるけど)
「昔の成績の影響は減っていくので、ちゃんと今強い人が評価される」とか、色々ランクを決定づけるための要素があって難しそうでした。
この辺のルールが複雑でよくわからなかったのもあって、Kaggleから距離を置いていました。
きっかけ
なんでKaggleを始めたのかというと、先日モデルを実装する機会があり、そこでモデルを改良する楽しさに気づけたからです。
ドメイン知識をもとに特徴量を抽出・選択してみたり、欠損値をどうするかなどを考えて実際にスコアとしてその結果が出るのは、AtCoder(Algorithm)とはまた違う面白さがありました。結果はアレだったけど()
他にも、これまで主に書籍等によって機械学習の勉強をしていたのですが、講義も落ち着き、そろそろ研究に本腰を入れるための助走として、実践的に学びたいと考えたのもあります。
1日目 (6月10日)
Kaggleのチュートリアル的な立ち位置のコンペであるTitanicをやりました。
タイタニックに搭乗していた人の名前や、性別や階級や居た場所などの情報から、その人が生存したかどうかを予測するコンペです。
実は数ヶ月前にKaggleに登録した際に、強い人が公開しているコードをコピペして結果を提出するだけして放置していました。
そこで、とりあえず再度これを読み返して、基本的なKaggleのやり方や、モデルの選定から特徴量抽出・学習・出力の流れを確認しました。
ついでに、 "Thank you. It makes my first step of Kaggle so easy." ってコメントしておきました。
わかりきったことだと思いますが、コードの全体の流れとしては以下のようになっています。
学習データとテストデータをロードする
学習データとテストデータをいじる
モデルを作る
学習データによってモデルを学習する
学習済みのモデルによって、テストデータのターゲットを予測する
予測された出力をcsvファイルなどに変換する
手順2, 3, 4 を工夫することで、いい予測をできるようにしよう!というのがコンペの目的です。
このコードで、Random Forestという手法(モデル)が提示されていました。
なんのこっちゃわからなかったので、
これとかを読みました。
Random Forest以外の手法も知りたかったので、
これを読んでみました。標準化のコード書かれてて、実際に使う時にも参考になりそうでした。
簡単そうだし、とりあえず試す時はRandom Forestが正義かなと思いました。
他にも、この記事を読みました。
どういう考えのもと、モデルを作ったかについて書かれていて、実際のコンペの時の思考の流れが勉強になりました。
軽く調べれば調べるほど、「こういう優秀な手法を使えば、あとハイパーパラメータを調整するぐらいしか出来ることなくない?」という気持ちになりました。
2日目 (6月11日)
他の面白そうなコンペを探しました。
ツイートからいいねを予測するコンペがあったので、それに参加してみることにしました。(ドメイン知識もありそうだし)
とりあえず全てのツイートに対して、いいねを0と予測しているサンプル結果を提出してみました。
その後、研究室に行く用事あったので、Kaggleやったことある先輩に定番手法とか聞いてみました。
そこで仕入れた情報は、
特徴量抽出を頑張る
one-hot-encodingだけじゃなくて、target_encodingってのもある
勾配ブースティング木をテーブルコンペの時最初に試しがち
データの損失について、平均値で埋めたり、消し飛ばすだけじゃなくて、データの損失の有無の列作ったりするのもあり
Twitterでそういう情報流れてくるから強い人をフォローした方がいい
とかでした。(忘れてることあったらすいません。)
色々話してみて、モデルの選択よりも、データをどう使うかが大事ってことかなと思いました。
院試のあれこれで、2日目はTwitterのいいねを予測するコンペをやる時間を全く取れませんでした。
3日目 (6月12日)
Twitterのいいねのコンペをやってみました。
特徴量抽出
one-hot-encoding
target-encoding
random-forest
勾配ブースティング木
線形回帰モデル
ハイパーパラメータの調整
を軸にやってみました。
やっていく中で、疑問点がいくつか生じたので、それについて書いておきます。
生じた疑問点
疑問点①
Q. get_dummiesしたら、trainデータとtestデータで出てくる列名違くて使い物にならなくない?
A. 以下の記事を参考にしたらOK。
このサイトめっちゃお世話になってます。Pythonのループすら知らない時から、ありがとうございます。
疑問点②
Q. GradientBoostingClassifier(勾配ブースティング木)の学習が終わらない。なぜ?
A. よくわからず。致命的。おわり。どうしたらいいんや。パラメータが収束してないのかな。エラーとか出してくれ。研究室の先輩に聞いてみます。
疑問点③
Q. ランダムサーチでハイパラを見つける時に警告出まくるのは仕方ない?組み合わせ的に。この場合ちゃんと警告が出てるのは除外されてるのかな。されてるか。
A. 多分されてる。
特徴量を抽出する
とりあえず、特徴量の抽出をしようということで、どの情報が「いいねの数」に直結するかを考えました。
入力は、「Tweet」と、「そのカテゴリ」の二つだったので、以下のような仮説を考えました。
Tweetのカテゴリでいいねが決まる
AtCoderのコンテストの結果のツイートはいいねされがちとか
社会風刺のツイートがバズりがちとか
Tweetの長さでいいねが決まる
「おはよう」とか「ねるわ」とか短すぎるTweetにはいいねあんまりつかなそう
長すぎても読むのが辛くていいね少なかったりしそうとか。
Tweetの感情でいいねが決まる
ポジティブなツイートの方がいいねしやすいとか
あんまり感情がない「ごはんたべたー」みたいな中立的なツイートはいいね少なそう
これらの仮説をもとに、特徴量抽出を行ってみました。
カテゴリは文字列だったので、get_dummiesで0, 1の列に書き換える。
Tweetの感情はTextBlobを用いて感情を数値化する。
のような実装で実現しました。
感情だけとか、カテゴリ+感情、ツイート長+カテゴリとか、色々試してみたのですが、ほとんどの場合ゴミみたいなスコアになりました。
(カテゴリのみから予測するモデルはサンプルのスコアよりも微かに上だったので、最終的にはカテゴリのみを特徴量としました。)
おそらく分類木において、入力を細分化しすぎると、その極端な値で学習されてしまうことがあるのかなと感じました。データが少ない時は区分を大雑把にして均すようにした方が安全なのかなと思いました。
決定木の知識をもう少しつけようと思って以下の記事を読みました。
「そもそも今回のタスクは分類じゃないじゃん。値を決める系のモデル使わないと上手くいかないんじゃない?」と今更ながら気づいたのですが、回帰にも分類にも使えるらしいです。ありがたい。凄い。
モデルの構築
上記の特徴量抽出をしながら、モデルの選択とハイパーパラメータの調整を行いました。
なぜか勾配ブースティング木は学習が進まなかったので諦めて、Random Forestでやってみました。
ハイパーパラメータは自動で調整するようにしました。
ハイパーパラメータの最適化手法として、グリッドサーチと、ランダムサーチという二つの方法があります。
グリッドサーチは、ハイパラとしてとりうる値を自分で決めて、それぞれについての損失から最も適したハイパラを求めるもので、ランダムサーチはランダムにやります。
今回は、どのハイパラがいいか想像もつかなかったので、ランダムサーチでやってみることにしました。
(ランダムサーチの方が効率がいいって意見もあったし)
でも、引数のparam_distributionsで範囲は自分で決めないといけないので、どっちにしても経験が少ないと上手いハイパラを見つけれないと思います。
ランダムサーチで求めたハイパラでのRandom Forestは予測されたいいねが全部0になってまいました。
色々試行錯誤してみたら、必要そうにない引数を未指定にして、初期値を使用するようにしたら、いいねが0以外になる時も予測してくれるようになりました。結果スコアがサンプルの提出よりも僅かに向上しました。
今の何も分かってない状態だと、無理にハイパラを指定せずに、初期値を使うのもありかもしれないです。
勉強のために、強そうな人が公開しているNotebookを読んでみました。
色々複雑なことをやってモデルを作っていて、凄いなぁと思っていたのですが、実際のスコアはサンプルの提出よりも悪くて、どうしたもんだろう…と思いました。こだわればいいってもんでもないのかなぁ。
もっと多くのコードが公開され、議論されている大きいコンペにも出て、手法を学びたいと思いました。
結果
色々試してみて、サンプルの提出よりはスコアが向上しました。
2023/06/13(17:30)現在で11チーム中4位になりました。
おわりに
短時間しか取り組めませんでしたが、機械学習モデルを作り、改善していく過程を実際に味わうことができました。
手法や特徴量・ハイパーパラメータについて考えたり、学んだことは、今後研究で自然言語処理・機械学習をやっていく上でベースとなる経験になると感じました。
また、最初は競技的にマイナスだと感じていた「コンテスト中にコードが公開されたり、議論が行われる」点についても、世界中の機械学習やデータサイエンスに携わっているエンジニアの知見を吸収しつつ実践できるという点で非常に有用な仕組みだと思いました。
今後も時々はKaggleに参加してみようと思います。
『Kaggleで勝つデータ分析の技術』って本を積読してるのでそれも読みたいし。
ブワァァアア!って勢いで書いたので、読みにくかったと思いますが、最後まで読んでいただいてありがとうございました!
この記事が気に入ったらサポートをしてみませんか?