u++の備忘録

CatBoostのテキストカラム指定機能を試す

CatBoostの(カテゴリカラム指定ならぬ)テキストカラム指定機能を試してみました。本記事の内容は、discussion*1に投稿済です。

Kaggle「Real or Not? NLP with Disaster Tweets」*2コンペのデータセットを利用しました。

f:id:upura:20200303195115p:plain

target_col = 'target'
text_cols = ['text']
categorical_cols = ['keyword', 'location']

train_pool = Pool(
    X_tr, 
    y_tr, 
    cat_features=categorical_cols,
    text_features=text_cols,
    feature_names=list(X_tr)
)

生の文章が入ったカラムを指定できるので、サクッとベンチマークを作るには便利だと感じました。

5 foldでの性能をテキストカラムの有無で比較すると、次の表の通りとなりました。正答率(ACC)は、閾値を0.5として算出しています。

with text feature without text feature
Public LB 0.79141 0.73006
Local AUC 0.8590 0.7909
Local ACC 0.7985 0.7358

実装したNotebookも公開済です。

株式会社はてな東京オフィスを訪問してみた

ご縁があり、株式会社はてな東京オフィス*1を訪問しました。はてなブログは2016年9月から足掛け3年半、総計350記事以上書いてきた思い入れあるサービスです。

お土産も頂戴しました。はてなブックマークの15周年*2記念グッズは、結構珍しい気がします。

f:id:upura:20200302220651p:plain

短文の「記念カキコ」*3でした(死語)。

「Linear Quiz Blending」の概説

"Linear Quiz Blending" や "Netflix Blending" と呼ばれる技法について、少し前にまとめたスライドを公開しました。

少し前からKaggleをやっている方だと「Kaggle Tokyo Meetup #5」*1での、Kaggle Grandmasterのsmlyさんの発表が印象的かもしれません。

実装はたとえば次のライブラリのものがあるそうです。

【書籍メモ】『機械学習・深層学習による自然言語処理入門 scikit-learnとTensorFlowを使った実践プログラミング』

2月26日に刊行された『機械学習・深層学習による自然言語処理入門 scikit-learnとTensorFlowを使った実践プログラミング』を読みました。

「日本語」のデータで、「今の自然言語処理」をイチから学ぶ!

公式サイトの宣言文句が、本書の特徴を言い得ています。日本語のデータセットを前提として前処理を含めた概念やコードが丁寧に解説されている点、伝統的な手法と近年発展するニューラルネットワークによる手法の両者が掲載されている点が、現時点で独自性があり優れている書籍だと感じました。

書籍情報

公式サイト

book.mynavi.jp

サポートページ

サポートページには、サンプルコードと訂正情報が記載されています。サンプルコードは、ローカル環境で実行するためのファイル群を圧縮したzipファイル形式と、Google Colaboratory形式の2パターン提供されています。

book.mynavi.jp

著者紹介

本書の著者は、(著者名だけ見ると分かりづらいかもしれませんが)定期的にQiitaはてなブログで特に日本語の自然言語処理に関する有益な情報を発信している方です。私も日本語の分散表現の事前学習モデルなど、有り難く活用しています。

普段は企業のR&D部門で自然言語処理/機械学習の研究開発をしている方らしく、本書でも2章でシステム化におけるパイプラインを明示している点など、実応用の視点が随所にうかがえます。

章別の所感

本書の章別に、私の雑感を記します。

Chapter 1 自然言語処理の基礎

自然言語」とは何か、具体的にどのようなタスクが存在するかを説明している章です。応用技術として機械翻訳・質問応答・対話システムなども紹介しており、本書全体の導入の立ち位置です。

Chapter 2 機械学習

近年の自然言語処理の急速な発展を下支えしている「機械学習」を概説する章です。規則性に基づく手法とは異なりルール自体を学ぶ機械学習について「教師あり学習」「教師なし学習」「強化学習」の枠組みに分けて紹介しています。本章は自然言語処理に限らない話を取り扱っていますが、具体例や図が豊富で汎用的に分かりやすいと感じました。

次章以降でコードが登場する前準備として、ローカルの開発環境の構築方法もスクリーンショット付きで初学者向けに説明しています。

Chapter 3 コーパス

自然言語で記述されたデータ集合「コーパス」について、1章分を割いてまとめています。csv, tsv, jsonというファイル形式の解説など基礎的な部分から網羅していました。実際に自分でデータセットを準備する際に必要になる「スクレイピング」や「アノテーション」にも触れられています。

Chapter 4 テキストの前処理

個人的に、本書が最も価値を持つと感じた章の一つです。自然言語処理に関する優れた文献は数多くありますが、日本語のデータセットを前提としてテキストの前処理についてコード付きで丁寧に解説している書籍は多くありません。HTMLタグの削除・単語分割・正規化・「ストップワード」の除去に加え、本書の後半で登場するニューラルネットワークを扱う上での全体と成る、単語のID化や系列長を揃える「パディング」も扱っています。

Chapter 5 特徴エンジニアリング

N-gram」「Bag of Words」「TF-IDF」などの伝統的な特徴ベクトル作成手法を解説している章です。近年でも十分に有用性がある手法を紹介しつつ、単語の順序情報を失っている問題点にも触れています。ここでは「おまけ」として掲載していますが、本書の後半部分で扱う要素にも関わるので、もう少し強調して記載しても良かったのではと個人的に感じた面もあります。スケーリングや特徴選択など、必ずしも自然言語処理の文脈に限らない話にも言及がありました。

Chapter 6 機械学習アルゴリズム

前章で獲得した特徴ベクトルを「ロジスティック回帰」に投入します。単なるパッケージの使い方にとどまらず、数式を交えて損失関数やオプティマイザといった内部構造にも言及があります。機械学習アルゴリズムを評価する文脈の中で「交差検証」「過学習」「正則化」といった要素も丁寧に紹介しており、その流れで実際にハイパーパラメータ調整も実行しています。決して自然言語処理特有の話題ではないにもかかわらず、機械学習を実運用する上で欠かせないこれらの概念が盛り込まれている点は、とても素晴らしいと感じました。

Chapter 7 ニューラルネットワーク

本章から、近年発展するニューラルネットワークによる手法を取り扱っていきます。シンプルな多層パーセプトロンを題材にニューラルネットワークの概念を紹介し、実際にkerasを用いて実装も進めます。モデルの保存・読込や、過学習を防ぐための「Early Stopping」、実行ログを可視化できる「TensorBoard」の紹介もあります。実用面が強く意識された書籍という印象を受けました。

Chapter 8 単語分散表現

自然言語処理の手法として著名な「Word2Vec」を解説している章です。単に単語をベクトル化するツールとして活用するのではなく、前章で解説したニューラルネットワークを用いて「分散表現」を獲得する過程を説明しています。分量は多くありませんが、単語の分散表現の評価手法に関する言及がある書籍は珍しいと感じました。

Chapter 9 テキスト分類

Chapter 6ではロジスティック回帰を用いて実装したテキスト分類タスクに対して、ニューラルネットワークの「RNN」「LSTM」「CNN」を適用します。前章で扱った単語分散表現についても、ニューラルネットワークのEmbedding層の初期値にする文脈で登場します。

Chapter 10 系列ラベリング

文ではなく単語などの系列単位でラベル付けする「系列ラベリング」について、特に「固有表現抽出」の話題を取り上げる章です。前章のLSTMを拡張した「双方向LSTM」、そして近年の自然言語処理に飛躍的な進歩を生み出した「BERT」が登場します。個人的に「BERT」の実装はPyTorchのtransformersを利用することが多いため、改めてkerasのコードを読むのは勉強になりました。予測ラベル間の制約を考慮できる「条件付き確率場」も紹介しています。

Chapter 11 系列変換

機械翻訳に代表される「系列変換」を扱う章です。Google翻訳など、多くの方に馴染みの深い話題だと思います。基礎となる「エンコーダ・デコーダ」について数式を交えて解説しつつ、実装の評価の中で「GLUE」も紹介しています。エンコーダ・デコーダの課題に応える形で「アテンション」が登場するので、コードの書き換えの過程も含めて理解が進む構成になっていると感じました。

Chapter 12 機械学習クラウド

最終章の題材は、Google Colaboratory、AutoML、自然言語処理用のAPIです。クラウドについて具体的に触れている点は、近年のデータサイエンスを取り巻く環境の変化を実感させられます。

おわりに

本記事では、『機械学習・深層学習による自然言語処理入門 scikit-learnとTensorFlowを使った実践プログラミング』を紹介しました。

私自身も業務の中で機械学習自然言語処理を取り扱っていますが、イマドキの日本語の自然言語処理について基礎から応用までを広く体系立てて書籍という形でまとめるのは、本当に骨の折れる作業だったと想像します。著者への感謝を述べて、本記事の結びとします。

Kaggle「WiDS Datathon 2020」コンペ解法まとめ

先日まで参加していたKaggle「WiDS Datathon 2020」コンペの解法まとめです。「検査データから1週間後の生死を当てる」というシンプルなテーブルコンペでした。本記事では、自分の復習用にザッとまとめたメモを共有します。

Place Link
1 https://www.kaggle.com/c/widsdatathon2020/discussion/133189
2 https://www.kaggle.com/c/widsdatathon2020/discussion/132387
3 https://www.kaggle.com/c/widsdatathon2020/discussion/132292
4 https://www.kaggle.com/c/widsdatathon2020/discussion/132312
5 https://www.kaggle.com/c/widsdatathon2020/discussion/132267
6 https://www.kaggle.com/c/widsdatathon2020/discussion/133509
7 https://www.kaggle.com/c/widsdatathon2020/discussion/132301
14 https://www.kaggle.com/c/widsdatathon2020/discussion/132225
16 https://www.kaggle.com/c/widsdatathon2020/discussion/134391
21 https://www.kaggle.com/c/widsdatathon2020/discussion/132451
22 https://www.kaggle.com/c/widsdatathon2020/discussion/132302
24 https://www.kaggle.com/c/widsdatathon2020/discussion/132262
61 https://www.kaggle.com/c/widsdatathon2020/discussion/133428
132 https://www.kaggle.com/c/widsdatathon2020/discussion/132674

f:id:upura:20200229122426p:plain https://www.kaggle.com/c/widsdatathon2020/leaderboard

1位

探索的データ分析(EDA)、欠損値補完、特徴選択、モデリング、アンサンブルの一連の観点で、多種多様なやり方を試していました。

  • 欠損値をさまざまな形で活用した
    • 欠損値フラグ
    • XGBoostで予測
    • 統計値で補完
  • EDAに基づく特徴量エンジニアリング
  • さまざまな特徴選択を試した
  • モデリング
    • Boosting trees (Catboost, Xgboost, Lightgbm, h2o GBM)
    • Scikit learn (KNN, Logistic Regression, Random Forest, Extremely Randomized Trees, Histogram-Based Gradient Boosting)
    • Deep learning models (Pytorch and Tensorflow)
    • Pystacknet
  • Pseudo Labeling
  • Test Time Augmentation (TTA)
    • 年齢や性別などを変更した結果をアンサンブル

2位

2位チームは、privateで大きく順位を上げていました。

  • 前処理: 検査項目の最大値・最小値に関する特徴量のデータ修正
    • 今回のデータには、最大値よりも最小値が大きいものが少なからず存在していた(discussion)
  • 集約系の特徴量を思考停止で作ると特徴量が増えて過学習につながるので注意深く追加した
  • 欠損値はLightGBMで予測。単純に補完するのではなく、別の特徴量として追加したほうが良かった
  • 単純な KFold を利用。fold数は、CVとLBスコアを見て8に決めた
  • 特徴量数(200〜1500)や前処理方法を変えたLightGBMモデルを複数作った
  • XGBoostやロジスティック回帰も含めて、26モデルをアンサンブル
  • 効かなかったこと: Frequency encoding、Target encoding、相関や検定に基づく特徴選択、Stratified KFold、Pseudo Labeling
  • GitHub: GitHub - oleg-panichev/WiDS-Datathon-2020-Second-place-solution: WiDS Datathon 2020 Second place solution

3位

  • 既存の特徴量の削除
    • 特にfeature importanceが上位に来る apache_4a_hospital_death_probapache_4a_icu_death_prob を削除している点が驚き
    • feature importanceは高いが、過学習を引き起こしているとのこと
  • 前処理: 検査項目の最大値・最小値に関する特徴量のデータ修正
  • Pseudo Labeling
  • 最終モデルは3モデルの重み付き平均
    • 60%: LightGBM + categorical_features
    • 20%: LightGBM + One hot encoding
    • 20%: Neural Network (Notebook)
  • Repeat Stratified KFold

4位

  • 特徴量エンジニアリングはかなり簡素で、最大値と最小値の差の特徴量の追加など
  • 最終モデルは3モデルの重み付き平均
    • 35%: LightGBM
    • 50%: LightGBM + Pseudo Labeling
    • 15%: 4層MLP

5位

  • LightGBMの複数モデルのアンサンブル (Notebook)
    • 'boosting_type': 'goss'
    • train, testの一部のだけで共通していたid系の特徴量の活用

6位

  • XGBoost2+LightGBM1のアンサンブル
  • id系や apache_4a_hospital_death_probapache_4a_icu_death_prob の削除
  • 前処理: 検査項目の最大値・最小値に関する特徴量のデータ修正

7位

  • id系やadversarial validationで上位に来た特徴量の削除
  • Repeating Stratified kfold with k == 5 and 10 repeats
  • trainとtestを結合した後にFrequency encoding
  • 効かなかったこと: Target encoding、「最大値<最小値」フラグ追加

14位

upura.hatenablog.com

21位

  • XGBoost、CatBoost、AdaBoostのアンサンブル

22位

  • BayesianRidgeで7モデルをstacking
    • LightGBM: dart, goss, rfの3種類
    • XGBoost: 片方は「Imbalance-Xgboost
    • Neural Network: カテゴリ変数の処理がembedding層かOne hot encodingか
  • id系カラムへのFrequency encoding、検査項目の最大値・最小値に関する特徴量のデータ修正、ageなどのbinningが効いた

24位

  • 2種類のモデルでアンサンブル
    • h2o.AutoML (15 models and 10 folds)
    • LightGBM tuned by GBRT, with Repeated Stratified KFold (4 splits, 10 repeats)

61位

  • 3時間チャレンジらしい
  • LightGBMの5fold

132位

上位4%から14%までprivateで落ちてしまった方の取り組みで、CVの重要性を教訓として語っています。個人的には、決して上位でなくとも取り組みを共有するのは素晴らしいことだと思っています。

おわりに

本記事では、Kaggle「WiDS Datathon 2020」コンペの解法まとめを掲載しました。

「NLPコンペの知見を実務に活かすために」の題目で発表しました

本日開催された「Kaggle Google Quest Q&A Labeling 反省会」*1にて「NLPコンペの知見を実務に活かすために」の題目で発表しました。自作のPythonライブラリ「Ayniy」について、設計思想や具体例を紹介しました。

詳細な内容については然るべきタイミングで別途記事にする予定ですが「Ayniy」には次のような特徴があります。 これらの内容を、具体例も含めてザッとお話させていただきました。

  • コンペ特化のpipe lineではなく、ちょっとしたサポートツール
  • 設定レベルの変更でdata loaderやベクトルを作成できるような共通インタフェースで、比較実験を回しやすくしている
  • コンペで扱うことが多い英語と、実務で扱うことの多い日本語の切り替えも簡単にしている

その他の発表については、詳しくはブログ枠の方の報告*2を御覧ください。 NLPコンペに関して少人数で濃い議論できた有意義な場でした。

Kaggle「WiDS Datathon 2020」コンペ14位の取り組み

Kaggleで開催されていた「WiDS Datathon 2020」コンペに参加して、public 7位、private 14位でした。shake downしてしまいましたが、ほぼベストの提出を選択できていたので悔いはありません。「検査データから1週間後の生死を当てる」というシンプルなテーブルコンペで、いろんな技術が検証できて面白かったです。

取り組み

既にdiscussionに投稿済の内容を日本語で掲載します。

チームメイトの方と共に、多様なモデルを作りました。それぞれがstackingモデルを作り、最後の2サブとして選択しています。

mtmt モデル

f:id:upura:20200225130710p:plain

u++ モデル

f:id:upura:20200307162246p:plain

LightGBMモデルで試したこと

  • Create {700, 1000, 2000} features
  • Remove {hospitalid, icuid}
  • Do adversarial validation, and remove some features
  • Add residual of other models
  • Parameter tuning by {hand, Optuna}
  • Pseudo labeling by {all data, some data}
  • Impute {apache4ahospitaldeathprob, apache4aicudeathprob}
  • Train with focal loss

Phase 2として、research paperの提出も検討中です。stackingの各モデルのCV, LBをまとめるなど、詳細な情報を盛り込めればと考えています。