Mahoutで体感する機械学習の実践

第3回Mahoutの環境構築とFP-Growthによるマーケットバスケット分析

HadoopとMahoutをインストールする

Hadoopのバージョンに注意

前回はマーケットバスケット分析の理論編として、アソシエーション分析とアプリオリアルゴリズムについて解説しました。今回は実践編として、Mahoutが実装しているアプリオリアルゴリズムを改良したFP-Growthを用いて、実際にマーケットバスケット分析を行ってみましょう。

そのための準備として、まずMahoutとHadoopをインストールする必要がありますが、 その際1つ注意する点があります。現在のMahoutの最新バージョンである0.7は、利用するHadoopのバージョンが0.20系である必要があります。しかし、Apacheの公式サイトからはすでにHadoopのバージョン0.20をダウンロードすることはできません。

Hadoopのバージョン0.20をお持ちでない方は、Cloudera社のページからダウンロードすることができます。このバージョンのHadoopのインストール方法はこちらにまとめられています。

Mahoutのインストール方法は、公式サイトに情報がまとめられています。

実際の開発ではIDEなどを用いて、MahoutやHadoop内部の処理もステップデバッグを行うことができれば便利です。特にMahoutはまだ情報が十分でないため、ソースを追う必要がある局面も考えられます。

Eclipseを利用する場合の環境構築方法は、mahout.jpのページに情報がまとめられています。

サンプルデータをダウンロードする

今回は、次のサンプルデータを利用してマーケットバスケット分析を行います。

サンプルデータはCSV形式となっています。各行がマーケットバスケット分析における各トランザクションデータに該当します。カンマで区切られた数値は、そのトランザクションで購入された商品のIDを表しています。

今回のサンプルデータは商品数1,000件、トランザクション数10,000件で作成しています。

Mahoutを実行する2つの方法

Mahoutは、次の2つの実行方法をサポートしています。

  • コマンドラインから実行する
  • プログラム内部からライブラリとして実行する

「とりあえずデータを分析してみたい」といった場合では前者が、⁠任意のプログラムへ組み込んで利用したい」という場合は後者が向いているでしょう。

本連載では、この2つの方法についてそれぞれ解説します。

Mahoutをコマンドラインから実行するには

Mahoutをコマンドラインで利用する場合、Mahoutのインストールディレクトリから次のコマンドを実行します。

bin/mahout

何もオプションを指定せずに実行すると、第1引数に指定できるオプションが表示されます。この中に含まれている「fpg」が、今回利用するMahoutのFP-Growth実装です。つまり、fpgは次のコマンドで実行できます。

bin/mahout fpg

コマンドラインからFP-Growth以外のアルゴリズムを実行する場合も、fpgと同じように実行したいアルゴリズムを第1引数に指定します。アルゴリズムだけでなく、出力結果の閲覧などの実行コマンドも第1引数で指定します。

FP-Growthをコマンドラインから実行する

入力ファイルと出力先を指定する

では、コマンドラインからFP-Growthを実行してみましょう。

コマンドラインからMahoutのインストールディレクトリに移動して、次のコマンドを実行してください。

bin/mahout fpg -i gihyo-mahout-fpg-sample.csv -o output/gihyo-mahout-fpg-sample

ここでは「-i」「-o」という2つのオプションを利用していますが、それぞれ次の事柄を意味します。

  • -i(--input)⇒ 入力ファイル
  • -o(--output)⇒ 出力先

無事、次のような結果がコマンドライン上に出力されたでしょうか。

実行結果
省略

13/03/01 13:30:33 INFO pfpgrowth.FPGrowthDriver: Dumping Patterns for Feature: 392 
([392],78), ([123, 392],5), ([392, 843],5), ([234, 392],4), ([392, 931],4), ([392, 866],4), ([163, 392],4), ([247, 392],4), ([392, 778],4), ([223, 392],4), ([392, 984],4), ([392, 449],4), ([167, 392],4), ([179, 392],4), ([392, 411, 735],3), ([331, 392],3), ([196, 392],3), ([392, 933],3), ([392, 898],3), ([392, 434],3), ([122, 392],3), ([392, 567],3), ([392, 534],3), ([392, 92],3), ([160, 392],3), ([381, 392],3), ([392, 851],3), ([392, 729],3), ([392, 83],3), ([392, 930],3), ([392, 409],3), ([392, 791],3), ([392, 651],3), ([392, 899],3), ([392, 897],3), ([135, 392],3), ([392, 7],3), ([392, 67],3), ([392, 598],3), ([392, 563],3), ([392, 871],3), ([392, 973],3), ([392, 564],3), ([392, 472],3), ([379, 392],3), ([240, 392],3), ([392, 423],3), ([197, 392],3), ([121, 392],3), ([387, 392],3)
13/03/01 13:30:33 INFO pfpgrowth.FPGrowthDriver: Dumping Patterns for Feature: 38 
([38],79), ([38, 952],5), ([38, 56],5), ([38, 511],5), ([38, 77],4), ([301, 38],4), ([38, 469],4), ([38, 645],4), ([204, 38],4), ([38, 39],4), ([38, 45],4), ([38, 951],4), ([38, 44],4), ([315, 38],3), ([38, 808],3), ([38, 562],3), ([38, 964],3), ([38, 999],3), ([38, 712],3), ([38, 857],3), ([38, 382],3), ([38, 436],3), ([38, 854],3), ([38, 595],3), ([148, 38],3), ([38, 472],3), ([320, 38],3), ([267, 38],3), ([38, 881],3), ([38, 954],3), ([38, 741],3), ([107, 38],3), ([38, 600],3), ([38, 745],3), ([341, 38],3), ([38, 654],3), ([297, 38],3), ([38, 578],3), ([243, 38],3), ([38, 991],3), ([38, 769],3), ([287, 38],3), ([129, 38],3), ([38, 647],3), ([38, 59],3), ([38, 694],3), ([38, 767],3), ([38, 663],3), ([38, 799],3), ([38, 725],3)

省略

13/04/01 13:30:33 INFO pfpgrowth.FPGrowthDriver: Dumping Patterns for Feature: 865 
([865],85)
13/04/01 13:30:33 INFO pfpgrowth.FPGrowthDriver: Dumping Patterns for Feature: 66 
([66],86)

この結果は次のように解釈します。

([組み合わせ],出現頻度)

よって、この出力は次の意味になります。

  • 商品ID392の出現頻度(支持度)が78
  • 商品ID392と392の組み合わせの出現頻度(支持度)が5
  • 商品ID38の出現頻度(支持度)が79

このようにMahoutを利用すると、かんたんかつ高速にアソシエーション分析を行うことができます。

なお、出力を再度確認したい場合は次のようにseqdumperを利用して、出力先に指定したHDFS上にある出力を表示させます。

bin/mahout seqdumper -i output/gihyo-mahout-fpg-sample

最低支持度を指定する

先の出力では、商品ID392や商品ID38の組み合わせのうち、最も頻度が少ないものが3となっています。これは前回解説した最低支持度のデフォルト値が3であるためです。

この値は、--minSupport(または-s)オプションで指定することができます。

bin/mahout fpg -s 5 -i gihyo-mahout-fpg-sample.csv -o output/gihyo-mahout-fpg-sample

この値を大きくすればするほど、処理が速くなりますが、出力として得ることのできる組み合わせの数が減少します。

maxHeapSizeで処理対象のアイテムを調整する

続いて、先の出力における商品ID865の支持度に注目してください。商品ID865については頻度のみが出力され、商品ID865とほかの商品との組み合わせの頻度が表示されていません。

これは処理対象のアイテム数としてデフォルト値の50が採用されたためです。最大何個のアイテムを処理対象とするかは、--maxHeapSize(または-k)オプションを利用すれば指定することができます。

bin/mahout fpg -k 1000 -i gihyo-mahout-fpg-sample.csv -o output/gihyo-mahout-fpg-sample

試しにmaxHeapSizeの値を100や1000などのより大きな値に設定してみてください。商品ID865やそのほかの商品でも、ほかの商品との組み合わせの頻度が出力されることが確認できるはずです。

MapReduceで実行する

Mahoutのメリットの1つとして、Hadoopを利用して分散処理できることが挙げられます。しかし特にオプションを指定しない場合、MahoutはMapReduceを利用せずにfpgを実行します。MapRecudeで実行したい場合は、次のように--methodオプションにmapreduceを指定します。

bin/mahout fpg -method mapreduce -i input/gihyo-mahout-fpg-sample.csv -o output/gihyo-mahout-fpg-sample

なお、MapReduceを利用した実行の場合はデフォルトのsequential実行の場合と異なり、入力ファイルはデフォルトではHDFS上を参照します。その際、ローカルのファイルシステムを参照させたい場合は「file:///」などを明示的に指定することで対応できます。

bin/mahout fpg -method mapreduce -i file:///opt/gihyo-mahout-fpg-sample.csv -o output/gihyo-mahout-fpg-sample

これら以外にも、いくつかオプションが用意されています。次のコマンドで確認できますので、適宜参照して利用してください。

bin/manout fpg -h

FP-Growthをライブラリ呼び出しで実行する

コマンドラインから実行する場合も同じメソッドが呼び出されている

ライブラリを利用してMahoutのFP-Growthを利用する場合は、次のFPGrowthクラスのgenerateTopKFrequentPatternsメソッドを利用します。

public final void org.apache.mahout.fpm.pfpgrowth.fpgrowth.FPGrowth.generateTopKFrequentPatterns(
   Iterator<Pair<List<A>,Long>> transactionStream,
   Collection<Pair<A, Long>> frequencyList,
   long minSupport,
   int k,
   Collection<A> returnableFeatures,
   OutputCollector<A,List<Pair<List<A>,Long>>> output,
   StatusUpdater updater) throws IOException

前述したコマンドラインからの実行は次のFPGrowthDriverクラスで実装されていますが、この内部でもFPGrowthクラスのメソッドが呼び出されています。

org.apache.mahout.fpm.pfpgrowth.FPGrowthDriver

そのため、ライブラリ呼び出しで実装する場合はこのコマンドラインのコードがとても参考になります。適宜参照することをおすすめします。

あるアイテムに注目した出力を得るには

MahoutのFP-Growthのコマンドライン実装には1つ問題があります。それは、すべてのアイテムの組み合わせの頻度(支持度)を出力しようとする点です。

そのため、⁠この商品とよくいっしょに売れる商品を知りたい」といった、ある特定のアイテムにのみ注目する場合、処理時間もリソースも無駄に多くかかり、大量の出力の中から特定のアイテムの情報をわざわざ探し出さなければなりません。

出力するアイテムを限定する方法が提供されていないのは、コマンドライン実行の実装であるFPGrowthDriverクラスにて、コマンドライン引数として受け取る実装がなされていないためです。

ただし、MahoutのFPGrowth実装そのものでは、上記generateTopKFrequentPatternsメソッドで第5引数として指定するreturnableFeaturesにて、出力するアイテムを限定することができます。今回のサンプルデータであれば、returnableFeaturesに392を指定すれば商品ID392を含む組み合わせのみを表示することができます。

次回は、行動履歴からのユーザのグループ分け(セグメンテーション分け)をテーマに取り上げます。お楽しみに!

おすすめ記事

記事・ニュース一覧