Indeed における機械学習とは、we help people get jobsという私たちのミッションの鍵です。機械学習は、一日に掲載される何百万という求人情報を集め、分類し、分析することを可能にします。
この記事では、オープンソース化した Java ラッパーの特に便利な機械学習ライブラリについて説明し、どう皆さんに活用いただけるかを説明していきます。
機械学習における挑戦
機械学習システムを作り上げるのは容易ではありません。良いシステムには、いくつか正しくやらなければいけないことがあります。
- 特徴量設計(Feature engineering) 例えば、テキストを特徴量ベクトルに変換するには、単語についての統計データを事前に計算しなければいけません。この工程には多くの課題が伴うこともあります。
- モデルの品質 アルゴリズムのほとんどがハイパーパラメータのチューニングを必要としており、通常それらはグリッドサーチを通して行われます。この作業は何時間もかかりかねず、アイデアを素早く繰り返し試していく事を難しくします。
- 大きなデータセットに向けたモデルの訓練 ほとんどのアルゴリズムの実装は、全てのデータセットがメモリに入ると想定します。Indeed で使用するような非常に大きなデータセットは、訓練が難しいのです。
うさぎが助けにやってきた
幸運なことに、そんな需要に応えてくれる素晴らしい機械学習システムがすでに存在します。Microsoft 社のコンピュータサイエンス研究者であるジョン・ラングフォード氏は、機械学習の理論とプログラミングの両方に突出した稀有な存在です。そんな彼のコマンドラインツールである Vowpal Wabbit (VW) は、一般化線形モデルのための最先端の技術を実装しており、柔軟なインプットデータフォーマットなど便利な機能を備えています。 VW は、機械学習のコミュニティで、沢山の注目を浴びており、業界内でも成功を収めています。
Vowpal Wabbit を使うメリット
Indeed では新しい求人情報の発見、検索結果の品質向上、そしてプロダクトのパフォーマンスの正確な測定などの作業を行うために、VW を使用してモデルを構築しています。VW が便利な理由は沢山あるのです。
メリットその1:あとで楽な入力フォーマット
VW にデータを投入するためには、まず特別なフォーマットにデータを変換する必要があります。このフォーマットは変な風に見えるかもしれませんが、沢山の利点があります。特徴量に名前空間 (namespace) を与える他には、一つの名前空間全体に重みをつけたり、特徴量に名前を付けたり、カテゴリーデータをそのままの形で渡したり、さらにはテキストさえも特徴量として渡すことができます。 VW を使用することで、下準備がほぼゼロの状態で生のテキストを渡して、それを踏まえきちんとしたモデルを訓練することができるのです!
また、このデータ・フォーマットはエラーが発生しにくくなります。予測の段階では、予測対象の特徴量を数値ベクトルではなく、このフォーマットに変換するだけで良いのです。
メリットその2:そのまま使えるパワフルな特徴量設計手法
Vowpal Wabbit のもう一つの強みは 特徴量設計手法が実装されている点です。これらの手法は、変数間の二次の相互作用(Quadratic interaction)や n-grams などのあまり複雑でないものから、変数間の二次の相互作用の低ランク近似(Low-rank quadratic approximation factorization machines (FM) としても知られています)のように、より複雑なものまであります。これらの特徴量設計手法を全て、プログラムのオプションを変更するだけで使用できるようになるのです。
メリットその3:素晴らしい速さ
Vowpal Wabbit は最適化された C++ で書かれており、複数のプロセッサーコアを活用することができます。 VW は訓練時間だけを見ると R よりも2、3倍速く、また tf-idf の計算などの準備時間を見た場合 R よりも10倍速くなります。
メリットその4:データサイズにボトルネックなし
多くの機械学習アルゴリズムはメモリ内にデータセットを全て読み込まなければいけません。 VW は、オンライン学習という異なるアプローチを使用します。これは訓練集合をその事例ごとに読み込み、モデルを更新していきます。ハッシュトリックを使用しているので、メモリ内に単語から重みベクトルのインデックスへのマッピングを保存する必要はありません。メモリ内には重みベクトルさえあれば良いのです。これは一つのマシンでどんなサイズのデータセットからでもモデルを訓練ができるということです。データが何十GBあろうと問題ではありません。
VW APIを改善
Vowpal Wabbit は find
のような古き良きUNIX コマンドラインツールにインスパイアされています。しかし Indeed では、わたしたちのインフラのほとんどが Java で書かれています。 Java コードから VW を起動したかったのですが、VWで提供されている Java ラッパーを使用した場合二つの問題に直面しました。
- ラッパーが使用される全てのサーバーで、 boost をインストールする必要がある
- API のレベルがとても低いため、より便利である抽象化された操作の代わりに、文字列で操作する必要がある
これらの問題を解決するため、自社で VW 用のオープンソース JNI ラッパーを作りました。
プロジェクトに vw-wrapper を追加
以下に記したように、Maven を使用し vw-wrapper に依存性を追加します。他のソフトウェアは必要ありません。
<dependency> <groupId>com.indeed</groupId> <artifactId>vw-wrapper</artifactId> <version>1.0.0</version> </dependency>
モデルを本番へデプロイ
以下三つの方法でモデルを本番にデプロイすることができます。
- モデルをコマンドライン経由で訓練し、モデルを本番環境にコピーするか、ソースと一緒に Git に入れることで本番へデプロイする。
- まず、あるコンポーネントがモデルを訓練し、ファイルに保存する。そのモデルを本番環境にコピーし、別のコンポーネントが予測を行う。
- 訓練と予測を同一の Java プロセスの中で行う。これは、オンライン学習システム(新しいデータが利用可能になると継続してモデルを更新するシステム)を作りたい場合に有効。
わたしたちは、CentOS、Ubuntu、そして macOS と、自社で使用する三つの主要な環境でライブラリをテストしました。配布している jar ファイル には、共有ライブラリを含めています。
使用例
わたしたちは、 Java API の使用法を示す結合テストの中に、各モデルを再現しました。
- MovieLens データセットのテストはユーザー評価の予測にどう VW を使用できるか示します。このテストは
lrqfa
のオプションを使用し、潜在的な(ユーザー、映画の)の反応からシグナルを取得します。これは factorization machines の論文にも述べられています。 - Twitter のセンチメント分析のテストは 自然言語処理 にどう VW を使用できるか示しています。このテストは、特徴量として生のテキストを使う方法、n-grams を使う方法、そして skip-n-grams の特徴量設計の手法を使う方法の三つの方法と、
featureMask
オプションを使用した特徴選択の行い方を示しています。
Vowpal Wabbit:名前の由来
Vowpal Wabbit という名前は、エルマー・ファッド風に Vorpal Rabbit を呼ぶところから取りました。 Vorpal というのはルイスキャロルのジャバウォックの詩に出てくるでたらめな言葉で、この文脈では“素早い”という意味で使われています。
One, two! One, two! And through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.(訳)
一、二、一、二 ずんずんと
素早い刃がざくざく刺した!
死体は残し 頭を持って
彼は意気揚々と戻っていった。
Vorpal Rabbit は非常に素早いうさぎなのです。
Vowpal Wabbit と Vowpal Wabbit Java を始めよう
VW について、更に詳しく知りたい方はラングフォード氏の VW ドキュメンテーションを読んでください。 VW の機能について書かれている他、チュートリアルや、内部で VW がどう動くか説明した論文へのリンクなども含まれています。
Github で私たちの作った Vowpal Wabbit Java ラッパー も是非チェックしてみてください。このラッパーの使いかたは、結合テストと Java API のドキュメンテーション を参照してください。便利なパラメータ についての情報も記載されています。