入力データを用意する
サンプルデータを確認する
前回はセグメンテーション分析の理論編として、セグメンテーション分析と代表的なクラスタリングアルゴリズムであるK-MeansとCanopyクラスタリングについて解説しました。
今回は、実践編として、K-MeansとCanopyクラスタリングによるセグメンテーション分析をMahoutを用いて実際に行います。
なお、本連載の3回目同様、Mahoutのバージョンは現時点の最新版である0.7を対象とします。
今回利用するサンプルデータは、ARFF形式[1]で顧客のRFMが記載されています。@DATA以降が、実際のデータです。
今回のデータは、以下のような構造になっています。
- 1行が顧客1人のデータを意味する
- カンマ区切りで、左から「R(最終購買日)」「F(購買頻度)」「M(購入金額)」を表す
今回のデータはR、F、Mの3つとも、本来の値を1から100の範囲に収まるように正規化しています。
ARFF形式をVector形式へ変換する
MahoutでK-Meansを実行する場合、入力ファイルはMahoutのVector形式である必要があります。
サンプルデータはARFF形式なので、下記のようにMahoutのarff.vectorコマンドでVector形式に変換します。
arff.vectorコマンドの各パラメータは、それぞれ以下を意味します。
- --input ⇒ 入力ファイル
- --output ⇒ 出力ファイル
- --dictOut ⇒ dictionaryファイルの出力先
生成されたVectorファイルは、以下のように、mahoutのseqdumperコマンドや、vectordumpコマンドで、中身を確認することができます。
なお、CSVファイルを入力ファイルに用いたい場合は、いったんCSVファイルをARFF形式に変換して、上記手順を踏んでください。Mahout自体には、CSV形式をVector形式に変換する機能は用意されていないためです。
K-Meansをコマンドラインから実行する
kmeansコマンドを実行する
それでは、サンプルデータを用いて実際にK-Meansを実行してみましょう。
MahoutのK-Means実装は、以下のようにkmeansコマンドで実行します。
kmeansコマンドのおもなパラメータとして以下があります。
- --input(-i) ⇒ 入力元
- --output(-o) ⇒ 出力先
- --distanceMeasure(-dm) ⇒ 距離計算方法の指定。デフォルト値はユークリッド平方距離
- --numCluster(-n) ⇒ 生成するクラスタの数
- --clusters(-c) ⇒ 初期クラスタ
- --convergenceDelta ⇒ 収束閾値。クラスタ重心の1回の移動距離が閾値以下になった場合、計算を終了する
- --maxIter ⇒ クラスタ重心点の最大計算回数
- --overwrite(-ow) ⇒ 出力先にファイルがすでにあった場合に上書きを行う
- --clustering ⇒ clusteredPointsの出力。clusteredPointsには、各要素がどのクラスタに属するかが記載されている
- --method ⇒ mapreduceを指定した場合はMapReduceによる計算、sequentialを指定した場合はローカルマシンによる計算を行う。デフォルト値はmapreduce
今回は、以下の設定で実行してみます。
- クラスタ重心点の最大計算回数 ⇒ 50回
- 生成するクラスタの数 ⇒ 10個
- クラスタの初期座標 ⇒ ランダム
- clusteredPointsの出力 ⇒ 有り
- 距離計算方法 ⇒ ユークリッド距離
以下のコマンドを入力してみてください。
今回は出力先にhdfsを利用しているので、出力結果のファイル構成を確認するには以下のように実行します。
以下のような出力が表示されたでしょうか?
MahoutのKmaensコマンドは、クラスタの計算回数ごとにclusters-xフォルダを作成します。clusters-0フォルダは初期状態、clusters-1フォルダは1回目の計算終了後の結果を含みます。
最終結果には、postfixとして、finalの文字列が付加されます。
上記出力では、clusters-20-finalが最終結果なので、20回クラスタの計算が行われたことがわかります[2]。
--clusteringパラメータにより生成されるgihyo-kmeans-output/clusteredPointsフォルダには、各要素がどのクラスタに属しているかの情報が保存されています。
K-Meansの実行結果を確認する
次に、実際に生成されたクラスタを確認してみましょう。
生成されたクラスタは、以下のようにclusterdumpコマンドを利用することで出力できます。
clusterdumpコマンドのおもなパラメータとして、以下があります。
- --input(-i) ⇒ 入力元
- --output(-o) ⇒ 出力先
- --outputFormat(-of) ⇒ 出力フォーマット。デフォルトのTEXT以外にCSV、GRAPH_ML(GraphML形式)を指定可能
- --pointsDir(-p) ⇒ clusteredPointsの指定
- --dictionary(-d) ⇒ dictionaryファイル指定
今回は、先ほど実行したkmeansの出力結果のうち、最終結果を確認してみましょう。以下のコマンドを入力してみてください。
次に、clusterdumpで出力したファイルの中身を確認してみます。
ここで表示される出力結果は、以下の意味になります。
- VL-x ⇒ クラスタ
- n ⇒ そのクラスタに属する要素の数
- c ⇒ そのクラスタの重心
- r ⇒ そのクラスタの半径
クラスタ数を10で実行していますので、VLで始まる行が10行生成されているはずです。
各クラスタに属する要素を同時に出力したい場合は、以下のようにclusteredPointsを指定します。
clusteredPointsの内容だけを確認したい場合は、Mahoutのseqdumperコマンドで確認することができます。
CanopyクラスタリングをK-Meansの前処理として実行する
canopyコマンドを実行する
前回でもとりあげたように、K-Meansでは生成するクラスタ数を指定する必要があります。そのため、生成するクラスタの大きさを指定してクラスタリングを行いたい場合、K-Meansのみでは実現が困難です。これは、生成するクラスタのおよその大きさを指定できるCanopyクラスタリングをK-Meansの前処理として利用することで解決が可能です。
Mahoutでは、以下のようにしてCanopyクラスタリングを実行します。
canopyコマンドのおもなパラメータとして、以下があります。
- --input(-i) ⇒ 入力元
- --output(-o) ⇒ 出力先
- --distanceMeasure(-dm) ⇒ 距離計算方法の指定。デフォルト値はユークリッド平方距離
- --t1 ⇒ t1値
- --t2 ⇒ t2値
- --overwrite(-ow) ⇒ 出力先にファイルが既にあった場合に上書きを行う
- --clustering ⇒ clusteredPointsファイルの出力。clusteredPointsファイルには各要素がどのクラスタに所属するか記載されている
- --method ⇒ mapreduceを指定した場合はMapReduceによる計算、sequentialを指定した場合はローカルマシンによる計算を行う。デフォルト値はmapreduce
以下のコマンドを入力し、canopyクラスタリングを実行してみましょう。
今回の入力データは、RFMの3つの値を最大値100で正規化しています。上記の例では、3次元間の距離をおおよそこの1/3程度にしたいと考え、t1値に33を、t2値にはそれより少し大きい値を指定しています。
K-Means同様、Canopyクラスタリングの出力も、以下のようにclusterdumpコマンドで確認することができます。
今回の著者の環境では、クラスタは8個生成されました。
ただし、Canopyクラスタリングはクラスタの初期重心がランダムで生成されるため、必ずしも同じ実行結果になるとは限りません。
Canopyクラスタリングの結果を利用してK-menasを実行する
次に、この結果をK-Meansの初期クラスタとして利用してみましょう。
Canopyクラスタリングの結果をK-Meansの初期値とする場合、--clustersパラメータにCanopyクラスタリングの結果を指定します。
これまでと同様、clusterdumpコマンドで生成されたクラスタを確認すると、Canopyクラスタリングで生成されたクラスタ数と同じく、8個のクラスタが生成されたことがわかると思います。
このように、CanopyクラスタリングをK-Meansの前処理として利用することで、クラスタの数ではなく、生成したいクラスタの大きさからK-Meansを用いたクラスタリングを実現することができるのです。
ライブラリ呼び出しでK-MeansとCanopyクラスタリングを実行するには
ライブラリを利用してMahoutのK-MeansとCanopyクラスタリングを実行するには、それぞれ以下のクラスのrunメソッドを利用します。
- K-Means
- ⇒org.apache.mahout.clustering.kmeans.KMeansDriverクラス
- Canopyクラスタリング
- ⇒org.apache.mahout.clustering.canopy.CanopyDriverクラス
これらは、どちらもコマンドライン実行の処理を実装しているクラスでもあります。そのため、これらのクラス内部に記載されているコマンドライン実装が、それぞれのrunメソッドの使い方の参考にもなります。ライブラリ呼び出しを実装する際は、適宜参考にしてみてください。
次回は、消費者の購買予測を取り上げます。お楽しみに!