大量のデータがある場合:Vowpal Wabbit

こんにちは、Habr!







前の2つの投稿( onetwo )では、 Kaggleの競合他社が使用している基本的なアルゴリズムとテクニックを調べました。 今日はさらに進んで、大量のデータがあり、メモリに収まらないサンプルから学習する必要がある場合に、アルゴリズムを開発する際に研究者が直面する困難についてお話したいと思います。 これはKaggle自体さえ非常に頻繁に発生することに注意してください (このタスクでは、トレーニングサンプルの容量は数ギガバイトであり、初心者にはこれをどうするかが明確ではないかもしれません)。 以下では、この問題に対処する機械学習アルゴリズムとツールについて説明します。



機械学習に精通している多くの人は、属性が適切に選択および生成されていれば、単純な線形モデルのおかげでかなり良い品質が得られることを知っています( 以前に説明しました )。 これらのモデルは、シンプルでありながら視認性が高いこともあります(たとえば、分割ストリップの幅を最大化するSVM)。 ただし、線形法には別の非常に重要な利点があります-トレーニング中に、新しいオブジェクトが追加されるたびにアルゴリズムパラメータの調整(つまり、重みを更新する段階)が実行されるようになります。 文献にあるこれらの機械学習方法は、 オンライン機械学習とも呼ばれます。



詳細を説明しない場合、一言で言えば次のようになります。特定の線形手法のパラメーター(ロジスティック回帰の重みなど)を選択するために、これらのパラメーターの初期値が初期化され、その後トレーニングセットの別のオブジェクトが入力されます、重みが更新されます。 そのため、線形法ではこの種のトレーニングが可能です。 同時に、すべてのオブジェクトを同時にメモリに保存する必要がなくなったことは明らかです。



今日、このようなメソッドの最も有名な実装の1つはVowpal Wabbitパッケージです。これはいくつかの点で簡単に説明できます。





したがって、このツールを実際に使用する方法と、このツールを使用して得られる結果について詳しく説明します。 例として、有名なタスクTitanic:Machine Learning from Disasterを検討してください。 このタスクにはデータがあまりないため、これはおそらく最も成功した例ではありません。 ただし、 この記事は、主に機械学習の初心者を対象としています。この投稿は、 公式チュートリアルの優れた続きです。 さらに、この投稿で使用されているコードを実際の(投稿の作成時に関連する) クリックスルーレート予測タスクに簡単に書き換えることができます。このタスクでは、トレーニングサンプルのサイズが5GBを超えています。



特定の手順の説明を開始する前に、以下で説明するコードはかなり前に(Vawpal Wabbitが普及する前でさえ)起動され、プロジェクト自体が最近積極的に更新されているため、以下に示すすべてのソースコードはある程度正確であることに注意してください。読者に。



検討中の問題では、特定の人(タイタニック号の乗客)がheれるかどうかを予測する分類器を構築することが提案されていることを思い出してください。 問題の状態と私たちに与えられた兆候については詳しく説明しません。 ご希望の方は、コンテストのページでこの情報に慣れてください。



したがって、まず、Vowpal Wabbitは入力として特定の形式のデータを受け入れます。



ラベル| A feature1:value1 | B feature2:value2



全体として、通常の「オブジェクト記号」マトリックスと違いはありません。ただし、記号はカテゴリに分割できるため、後でトレーニング中に記号の一部を「オフ」にできます。 したがって、トレーニングサンプルとテストサンプルをダウンロードした後、最初に行うことは、データをVowpal Wabbitが読み取る形式に変換することです。



トレーニングおよびテストサンプルの準備



これを行うには、 train.csvファイルを1行ずつ読み取り、トレーニングセットの各オブジェクトを目的の形式に変換する単純なスクリプトを使用できます(または、優れたphraug2ライブラリを使用できます)。 2クラス分類の場合、 ラベルは+1または-1の値を取ることに注意してください



import csv import re i = 0 def clean(s): return " ".join(re.findall(r'\w+', s,flags = re.UNICODE | re.LOCALE)).lower() with open("train_titanic.csv", "r") as infile, open("train_titanic.vw", "wb") as outfile: reader = csv.reader(infile) for line in reader: i += 1 if i > 1: vw_line = "" if str(line[1]) == "1": vw_line += "1 '" else: vw_line += "-1 '" vw_line += str(line[0]) + " |f " vw_line += "passenger_class_"+str(line[2])+" " vw_line += "last_name_" + clean(line[3].split(",")[0]).replace(" ", "_") + " " vw_line += "title_" + clean(line[3].split(",")[1]).split()[0] + " " vw_line += "sex_" + clean(line[4]) + " " if len(str(line[5])) > 0: vw_line += "age:" + str(line[5]) + " " vw_line += "siblings_onboard:" + str(line[6]) + " " vw_line += "family_members_onboard:" + str(line[7]) + " " vw_line += "embarked_" + str(line[11]) + " " outfile.write(vw_line[:-1] + "\n")
      
      





テストサンプルでも同じことを行います。



 i = 0 with open("test_titanic.csv", "r") as infile, open("test_titanic.vw", "wb") as outfile: reader = csv.reader(infile) for line in reader: i += 1 if i > 1: vw_line = "" vw_line += "1 '" vw_line += str(line[0]) + " |f " vw_line += "passenger_class_"+str(line[1])+" " vw_line += "last_name_" + clean(line[2].split(",")[0]).replace(" ", "_") + " " vw_line += "title_" + clean(line[2].split(",")[1]).split()[0] + " " vw_line += "sex_" + clean(line[3]) + " " if len(str(line[4])) > 0: vw_line += "age:" + str(line[4]) + " " vw_line += "siblings_onboard:" + str(line[5]) + " " vw_line += "family_members_onboard:" + str(line[6]) + " " vw_line += "embarked_" + str(line[10]) + " " outfile.write(vw_line[:-1] + "\n")
      
      





出力はそれぞれtrain_titanic.vwtest_titanic.vwの 2つのファイルです。 これは多くの場合、最も困難で長い段階であることに注意してください-サンプルの準備。 実際、さらにこのサンプルで機械学習メソッドを数回実行し、すぐに結果を取得します



Vowpal Wabbitでの線形モデルトレーニング



作業は、渡されたパラメーターを使用してvwユーティリティを実行することにより、コマンドラインから実行されます。 実行する。 すべてのパラメーターの詳細な説明には焦点を当てませんが、例の1つだけを実行します。



vw train_titanic.vw -f model.vw --binary --passes 20 -c -q ff --adaptive --normalized --l1 0.00000001 --l2 0.0000001 -b 24



ここでは、バイナリ分類問題( --binary )を解き、トレーニングサンプルで20パス( --passes 20 )、L1およびL2正則化( --l1 0.00000001 --l2 0.0000001 )、正規化、モデル自体をmodel.vwに保存します-b 24オプションは 、ハッシュ関数を指定するために使用されます(冒頭で述べたように、すべての属性がハッシュされ、ハッシュ自体は0から2 ^ b-1の値を取ります)。 また、ペアの機能をモデルに追加することを示す-q ffパラメーターに注意することが重要です(これはVWの非常に便利な機能であり、アルゴリズムの品質を大幅に向上できる場合があります)。



しばらくして、訓練されたモデルを取得します。 テストサンプルでアルゴリズムを実行するだけです。



vw -d test_titanic.vw -t -i model.vw -p preds_titanic.txt



そして、結果を変換してkaggle.comに送信します



 import csv with open("preds_titanic.txt", "r") as infile, open("kaggle_preds.csv", "wb") as outfile: outfile.write("PassengerId,Survived\n") for line in infile.readlines(): kaggle_line = str(line.split(" ")[1]).replace("\n","") if str(int(float(line.split(" ")[0]))) == "1": kaggle_line += ",1\n" else: kaggle_line += ",0\n" outfile.write(kaggle_line)
      
      





このシンプルなソリューションは、 0.79 AUC以上のかなり良い品質を示しています。 かなり些細なモデルを適用しました。 パラメータを最適化し、兆候を「再生」することで、結果をわずかに改善できます(読者は演習としてこれを行うことができます)。 この紹介が、初心者が機械学習コンテストのデータ量に対処するのに役立つことを願っています!



All Articles