u++の備忘録

ProbSpace給与推定コンペまとめ

「ProbSpace」というプラットフォームで開催された「給与推定」コンペが23日に終了しました。私は途中で まぐちさん とチームを組み、最終順位は7位でした。

prob.space

PublicとPrivateが分かれていないのは残念でしたが、恐らく独自に作成したデータセットを用いた、初学者でも取り組みやすい程よい難易度に設定されたコンペだったと思います。discussionシステムも存在していました。

本記事では、上位陣が公開した解法をまとめます。

一覧

Rank Link
1 https://prob.space/competitions/salary-prediction/discussions/senkin13-Post46bdfde9468e3d01f4e7
2 https://twitter.com/atushiTAKEDA/status/1208773041682956288?s=20
https://prob.space/competitions/salary-prediction/discussions/takedarts-Post6725a11b22813a3997d7
4 https://prob.space/competitions/salary-prediction/discussions/Yuhei0320-Post4766b7be57ac41cd505b
6 https://twitter.com/rntrnaru/status/1208901691518533637?s=20
https://prob.space/competitions/salary-prediction/discussions/maruyama-Post521eef51a86df217de38
7 https://prob.space/competitions/salary-prediction/discussions/upura-Post29db854982f9d802bb7b
10 https://prob.space/competitions/salary-prediction/discussions/physyuki-Post5fc459a996222908d0bd

1位

f:id:upura:20191223163329p:plain https://prob.space/competitions/salary-prediction/discussions/senkin13-Post46bdfde9468e3d01f4e7

1位の方は、5段階の処理を経て最終的な予測値を算出していました。

  1. LightGBMで152の特徴量を用いて予測
  2. LightGBMの残差が120未満のデータのみをダウンサンプリングして、Neural Networkで予測
  3. Neural Networkの残差が129未満のデータのみをダウンサンプリングして、Neural Networkの残差を新しいtargetにして、LightGBMで予測
  4. LightGBMの残差が129未満のデータのみをダウンサンプリングして、LightGBMで予測
  5. trainのtargetの値でtestを埋める後処理(trainとtestが似ている2件のみ)

残差を取りながらの多段推論がここまで効果を発揮するとは驚きでした。このアイディアはKaggle「Predicting Molecular Properties」コンペのCPMPさんの7位解法*1を参考にしたそうです*2

githubでコードも公開してくださっています*3

2位

2位の方は、480個のNeural Networkのアンサンブルでした。「Feature Encoding」と呼んでいる手法で特徴量自体を480通りに変換しているそうで、とてもユニークな取組だと感じました。

4位

4位の方は、Neural NetworkのSeed値を変えながらのアンサンブルのようです。活性化関数の利用回数を意図的に減らすなどで、過学習への対策をしていました。

6位

6位の方もNeural Networkのアンサンブルで、10個を混ぜたそうです。

7位

最終的なベストスコアは、Neural NetworkとLightGBMの重み付き和でした。チームマージ時点で、まぐちさんがNeural Network、私がLightGBMを進めていました。私の具体的な取り組みについては、discussionに投稿済です。

10位

特徴量エンジニアリング+LightGBMという、テーブルデータコンペの王道の取り組みでした。個人的に興味深かったのは次のデータ水増しです。今回は恐らく独自に作成したデータセットなので、特に効果を発揮する可能性があったと思います。

EDAからsexとtargetだけに注目すると2変数間に関係がなさそうだったので、試しにtrainのsexだけを反転させたデータを元のtrainにくっつけてデータ量を2倍にして学習しました。

おわりに

本記事では、ProbSpaceで開催された給与推定コンペの上位陣解法をまとめました。

*1:www.kaggle.com

*2:

*3:github.com

広島旅行記2019冬

2019年12月13〜16日の3泊4日で広島旅行に行ってきました。11月〜12月上旬に執筆やらイベントやらが重なっていたこともあり、しばしの休息です。

個人的な備忘録として、写真を並べておきます。


「銀の尻」

正式名称は知りません。

f:id:upura:20191216101704p:plain

三瀧寺

広島駅からバスで30分程度と遠からぬ立地でありながら、自然あふれる素晴らしい場所でした。


厳島神社

残念ながら改修中でしたが、これはこれで珍しい光景でした。

f:id:upura:20191216102221p:plain

宮島水族館

牡蠣は当然のように美味しかったです。その流れで水族館にも行きました(?)。

f:id:upura:20191216102808j:plain

f:id:upura:20191216102755j:plain

大和ミュージアム


広島城

護国神社のすぐ近くにありました。

f:id:upura:20191216102426p:plain

広島市現代美術館

広島中心地から少し外れた比治山の山頂付近に位置する趣きある建物です。建築設計を私の高校OBである黒川紀章さんが担当されたこともあり、以前から気になっていました。

f:id:upura:20191216101641j:plain

広島東照宮


おわりに

久々に丸3日くらいパソコンに触らない日々を過ごしました。また明日から、ボチボチやっていきたいと思います。

「Kaggle Days Tokyo」参加録

※ 「Kaggle Advent Calendar 2019」*1の12日目の記事です。

2019年12月11、12日に開催された「Kaggle Days Tokyo」*2に参加しました。1日目はワークショップとプレゼンテーション、2日目はオフラインコンペティションが開催されました。

資料や動画は恐らく公式から公開されると思うので、本記事では私の聴講した内容を基に、個人的な所感を述べます。なお1日目の内容はGunosyブログの記事*3Wantedlyブログの記事*4twitterまとめ*5に詳しく記載されています。

f:id:upura:20191212161627p:plain

1日目

Leveling-up Kaggle Competitions

Ben Hamner, Kaggle CTO

  • KaggleのCTOを務めるBenさんから、Kaggleの遍歴や今後の展望についてのお話でした
  • 深層学習の大躍進以前からKaggleを開催している歴史や、強化学習などの新たなコンペ形式を模索している話など、一人のKagglerとして興味深くお聞きしました
  • 「code competitionは実用性を意識している」といった、自分がおぼろげに感じていたことや疑問についてCTOの言葉を直接聞くことができる貴重な機会でした

Essential techniques for tabular competition

Kazuki Onodera

  • 特徴量エンジニアリングなどテーブルコンペに秀でたKaggle GrandmasterのOnoderaさんにから、テーブルデータの眺め方に関するお話でした
  • 強い方がどのようにデータを分析しているのか、単に手法やコードを示すのではなく「お気持ち」のような部分を感じ取れた素晴らしい発表でした

Hosting Kuzushiji the Competition

Tarin Clanuwat

  • Kaggleのくずし字認識コンペ*6の開催に携わったTarinさんによる熱意のこもった発表でした
  • 評価指標の選定理由やKaggle開催で得られたことなど、あまり世に出づらいお話がお聞きできました

Practical tips for handling noisy data and annotation

Ryuichi Kanoh

  • Kaggle MasterのKanohさんによる、主に画像コンペを対象としたノイズの多いデータの処理方法に関するワークショップでした
  • 資料*7やコード*8からもにじみ出ている圧倒的な実験回数や経験に裏付けされた、有益な知見が豊富なお話でした
  • こういった類いのワークショップは対象聴衆を見定めづらく難しいと思うのですが、随所に落ち着いた質疑応答を挟みながらの素晴らしいご講演でした

How to encode categorical features for GBDT

Ryuji Sakata (Jack)

  • Kaggle GrandmasterのJackさんによる、主にLightGBMにおけるカテゴリ変数の処理方法に関するお話でした
  • one-hot encoding, label encoding, LightGBMにおけるカテゴリ変数指定, target encodingの4つの手法に対して、何通りにも分かる比較実験を実施していました*9
  • あくまで今回の実験設定における話ではありますが数値に基づく議論が展開されており、今後のテーブルデータに取り組む上での道標となるようなお話でした

専業Kagglerの一年半 & LANL Earthquake Prediction 3rd Place Solution

Hideki Murata

  • 財務省を辞め「専業Kaggler」になったMurataさんによるお話でした
  • 前半では専業Kagglerになった経緯や経験談をユーモアを交えて展開し、後半では3位入賞した「地震コンペ」*10での取り組みをご紹介くださいました
  • 随所にてKaggleへの熱量や愛が伝わってくる発表でした

ML Modeling with AutoML Tables

Tin-Yun Ho & Da Huang

  • 「AutoML Tables」*11の開発者による、特徴や最近のリリースに関する紹介でした
  • デモも確認しましたが、思いのほか手軽に利用できそうで、面白いなと感じました

My Journey to Grandmaster: Success & Failure

Jin Zhan

  • Kaggle GrandmasterのJinさんによる、知見が詰まった非常に勉強になるお話でした
  • コンペ遍歴を振り返りつつ、過去のコンペから学んだKaggleの技法や考え方を網羅的に紹介してくださいました
  • 公開された資料*12は今後何度も読み返すことになると思います

How to succeed in code (kernel) competition

Dimitry Gordeev

  • 近年テーブルコンペ、特にKaggleのNotebooks環境にコードを記述する形式のコンペで圧倒的な成績を収めているKaggle GrandmasterのDimitryさんによる発表でした
  • メモリや時間制約のもとでどのように戦うか、考え方や具体的なTipsも交えてご解説くださいました
  • 懇親の場などで個人的により詳細な話も聞くことができ、とても勉強になりました

Kaggle Night Tokyo


2日目

2日目は、オフラインコンペティションが開催されたそうです。

おわりに

本記事では、2019年12月11、12日に開催された「Kaggle Days Tokyo」の個人的な所感を述べました。多くの知見が得られた刺激的な2日間でした。多くの方々と交流でき、研鑽のモチベーションが高まったイベントでした。

TF-IDFを用いた「Kaggle流行語大賞2019」

「kaggle その2 Advent Calendar」の10日目の記事です*1

2018年に引き続き、2019年もTF-IDFを用いた「Kaggle流行語大賞」を算出します。具体的には、2019年に公開されたNotebookのタイトル情報から、頻繁に登場した単語をランキング形式でまとめました。

なお昨年は「探索的データ分析(Explanatory Data Analysis, EDA)」が1位に輝きました*2

upura.hatenablog.com

集計方法

概ねと同様の方法を採用しています。一連の処理はKaggleのNotebook*3にて公開しています。

データセット

「Meta Kaggle」*4のデータセット「Kernels.csv」を利用しました。公開されているNotebookの公開日・URLなどの情報が格納されています。

NotebookのURLは、ユーザが付けたタイトルに基づいて決まります。下図のように「Simple lightGBM KFold」というタイトルの場合は「simple-lightgbm-kfold」です。

f:id:upura:20191209110128p:plain

Notebookの絞り込み

一定の評価を受けたNotebookに絞り込むため、次の処理を実施して「Voteを1以上得たNotebook」に集計対象を限定します。

kernels = kernels.query('TotalVotes > 0')

年ごとに分割

「公開年」別に集計すると、次のようになりました。公開されたNotebookは年々増加しています。

kernels['Date'] = pd.to_datetime(kernels['MadePublicDate'])
kernels['Date'].dt.year.value_counts().plot.bar()

f:id:upura:20191209114546p:plain

TF-IDFを計算

最後に、年を文書、タイトルを文の単位として捉えて「TF-IDF」を計算します。詳細は割愛しますが、多くの年で出現する語(一般的な語)は重要度が下がり、特定の年にしか出現しない単語の重要度は上がるような計算を施すことになります。あらかじめnltk.corpus内の英語のstopwordsを指定して、a, the, ofなどの一般的すぎる単語は取り除いています。また筆者の判断で、Kaggle特有の一般的な単語やコンペのタイトル名に含まれる単語などを除外しました。

from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer


stopWords = stopwords.words("english")
stopWordsAdd = ['data', 'analysis', 'model', 'simple', '2019', 'ashrae', 'ieee',
                'using', 'prediction', 'ml', 'classification', 'regression',
                'machine', 'learning', 'exercise', 'detection', 'kernel', 'dataset']

for sw in stopWordsAdd:
    stopWords.append(sw)

vectorizer = TfidfVectorizer(stop_words=stopWords)

結果発表

2019年のTF-IDFの値で降順にソートした上位8件を以下に示します。2019年も昨年に引き続き「eda」が首位の座を守りました。

f:id:upura:20191209114830p:plain

年次の推移を下図に示します。

f:id:upura:20191209114759p:plain

近年のKaggleの特にテーブルデータを扱うコンペでは、trainとtestの分布が異なるなど、データを丁寧に眺める必要性が高まっていると感じます。AutoMLなどの発展に伴い、単にデータを機械学習アルゴリズムに突っ込むだけでは差別化が図りづらくなっている面もありそうです。そういった背景もあり、edaはKaggleに取り組んでいると頻繁に見聞きする単語となっています。

2位の「titanic」、6位の「house」は、それぞれKaggleの初学者向けコンペの名前に起因していると推定されます*5*6

3位の「keras」、5位の「pytorch」、8位の「fastai」はいずれもニューラルネットワークを実装できるライブラリ名です。4位の「cnn」は畳み込み構造を持つニューラルネットワーク「Convolutional Neural Network」の略で、7位の「mnist」はcnnでよく扱われる手書き文字データセットです。近年のニューラルネットワークの飛躍的に発展している影響がうかがえます。

なお筆者の判断でstopwordを追加しなかった場合は下図の通りとなりました。どこまでを「一般的」として取り除くかは正直判断が難しいところです。

f:id:upura:20191209121211p:plain

おわりに

本記事では昨年に引き続き、TF-IDFを用いた「Kaggle流行語大賞」を算出しました。昨年に引き続き探索的データ分析(eda)が1位を守り、初学者向けコンペ名やニューラルネットワーク関連語も上位に食い込みました。

今年1年も存分に楽しませてもらったKaggleに感謝しつつ、来年もKaggleを楽しんでいきたいです。

Japan.R 2019にて「KaggleとRコンペの紹介」の題目で発表しました

「kaggle その2 Advent Calendar」の7日目の記事です*1

本日開催された「Japan.R 2019」*2にて「KaggleとRコンペの紹介」の題目で発表しました。

TokyoRでは2度発表したことがあるのですが*3*4、JapanRは初参加でした。幅広い世代の方が多様なジャンルの発表をしているのが印象的でした。あまりKaggleをやっている人は多くなさそうな空間で、普段と違った刺激が多く得られたイベントでした。

f:id:upura:20191207130831p:plain

Glideで手軽にJapan.R 2019 の非公式アプリを作ってみた

「R Advent Calendar 2019」の6日目の記事です。

qiita.com

概要

明日12月7日に開催される「Japan.R 2019」*1*2の非公式アプリを作ってみました。

ea1gv.glideapp.io

f:id:upura:20191109171916p:plain

作り方

11月6日に公開されて少しバズっていた記事*3を読んで、30分くらいで作成できました*4。「Glide」*5という、Google Spreadsheet からスマホ向けの Web アプリを作成できるサービスです。

Google Spreadsheet にデータをまとめておき、あとはGUIで手軽にアプリのUIを設計できます。connpassから発表タイトルや発表者名をコピペして加工するのが一番面倒でした。

Google Spreadsheet

f:id:upura:20191109172725p:plain

設計画面

f:id:upura:20191109172433p:plain

アプリ構成

学会用のテンプレートを基に、いくつか修正を加えて、次のような4つのタブを持つアプリ構成になりました。

  • Schedule
  • Talks
  • Speakers
  • Venue

住所を指定するだけで地図を埋め込む機能も提供されています。

f:id:upura:20191109173533p:plain

おわりに

本記事では、Glideを用いて作成した、明日開催のJapan.R 2019の非公式アプリについて紹介しました。かなり手軽に作成できるので、プロトタイプ作成の選択肢として持っておこうと思います。

Japan.R 2019 では「KaggleとRStudioコンペの紹介」という題目でLTをする予定です。参加される方は、よろしくお願いします。

*1:japanr.net

*2:japanr.connpass.com

*3:itnews.org

*4:

*5:go.glideapps.com

小数点以下を取り出す特徴量エンジニアリングの解釈と実装

Couseraの「How to Win a Data Science Competition: Learn from Top Kagglers」*1などで紹介されている特徴量エンジニアリングのアイディアの一つとして「数値データの小数点以下を取り出す」という技法があります。

本記事では簡単な解釈を述べ、Pythonによる実装も紹介します。「kaggle その2 Advent Calendar 2019」の8日目の記事です*2

数値データの小数点以下を取り出す

小数点以下を含む数値系のカラムに適用できる特徴量エンジニアリングです。次の図の「TransactionAmt」から「TransactionAmtDecimalPoint」を取り出すような処理を意図しています。

f:id:upura:20191204170200p:plain

解釈

Couseraの動画*3では「人間の認知やコンピュータとの違いを表現できる」といった説明がなされています。

例えば、価格の場合「$3.00」と「$2.98」だと、後者の方がお買い得だと感じる人も多いでしょう。人間とコンピュータとの違いで言うと、動画ではオークションやSNSの事例が出ています。オークションでは人間は切りの良い数字を使いやすいがコンピュータはそうではない、SNSでは厳密に1秒ごとに記事を読むのは人間ではなくbotである、などという解釈です。

動画で登場しなかった例で言うと、KaggleのTitanicコンペでも小数点以下を含む数値が登場します*4。年齢が推定値の場合など、「Age」は小数点以下を含むようです。このようなデータの仕様を表現する目的で、小数点以下を取り出す特徴量エンジニアリングが使える場合もあると思います。

age: Age is fractional if less than 1. If the age is estimated, is it in the form of xx.5

その他に「Statoil/C-CORE Iceberg Classifier Challenge」コンペ*5でも類似の事例がありました*6*7

主催者側が自動生成によってデータを水増し(data augmentation)をしていたのですが、各画像が水増しされて生み出されたデータかどうか、入射角の数値の小数点以下の桁数を確認すれば判別できるという情報でした。

実装

Pythonでの実装は、標準ライブラリのmathに含まれるmodf()*8*9を利用するのが手軽だと思います。

train_transaction['TransactionAmtDecimalPoint'] = [math.modf(v)[0] for v in train_transaction['TransactionAmt']]

一連の処理の流れは、KaggleのNotebook*10で公開しています。

おわりに

本記事では「数値データの小数点以下を取り出す」という特徴量エンジニアリングの簡単な解釈を述べ、Pythonによる実装も紹介しました。