今回は業務でPythonの「mlxtend」というライブラリを使ってアソシエーション分析を行ったので、手順などをメモしておきます
Aprioriとアソシエーション分析
Aprioriとは、アソシエーション分析を実践するためのアルゴリズムを指します。Aprioriは「頻出アイテム(商品・サービス)の組み合わせを検出し、アソシエーションルールを決定するための評価指標(Support、Confidence、Liftなど)を算出する機能」を有した最も有名なアソシエーション分析アルゴリズムの1つです。
前準備
まずはライブラリをインストールします
$ pip install mlxtend==0.21.0
ライブラリのバージョンは以下で確認できます。
import mlxtend print(mlxtend.__version__) # 0.21.0
分析に使用するデータの準備
mlxtendに投げるデータは購入した商品群をバスケット単位でリストにしてまとめた多次元配列のリスト形式でないといけません。具体的には以下のような感じです。POSデータなどの実際の元データではこうなっていないはいないと思うので、前処理を行う必要があります。
dataset = [ ['玉ねぎ', 'ニンジン','ジャガイモ', '牛肉', '卵', 'ヨーグルト', 'カレー粉'], ['たまねぎ', 'ニンジン', '豚肉', 'シチュー粉', '卵'], ['牛乳', 'リンゴ', 'ピーナッツ', '卵'], ['牛乳','ピーナッツ','ヨーグルト'], ['玉ねぎ', 'ニンジン', '卵', 'アイスクリーム'], ['豚肉', '玉ねぎ', '醤油', 'ウーロン茶'], ['牛肉', '玉ねぎ', 'ウーロン茶'], ['鳥肉', 'ヨーグルト', 'リンゴ', 'ウーロン茶'], ['豚肉', 'ヨーグルト', 'ジャガイモ', 'カレー粉'], ]
このバスケットデータをTransactionEncoder()でアイテム×アイテム行列に変換します。
from mlxtend.preprocessing import TransactionEncoder import pandas as pd # データをテーブル形式に加工 te = TransactionEncoder() te_array = te.fit(dataset).transform(dataset) df = pd.DataFrame(te_array, columns=te.columns_) df
aprioriの算出
まずは商品別の支持度を算出します。コードは以下のように記述します
from mlxtend.frequent_patterns import apriori freq_items = apriori(df, # データフレーム min_support = 0.01, # 支持度(support)の最小値 use_colnames = True, # 出力値のカラムに購入商品名を表示 max_len = None, # 生成されるitemsetsの個数 #verbose = 0, # low_memory=Trueの場合のイテレーション数 #low_memory = False, # メモリ制限あり&大規模なデータセット利用時に有効 )
これの分析結果を表示するためには以下のように記述します
# 結果出力 freq_items = freq_items.sort_values("support", ascending = False).reset_index(drop=True) print(freq_items)
上記で得られた結果をもとに、アソシエーション・ルールを抽出するための評価値を取得します。
アソシエーション・ルールの抽出
次は商品の組み合わせごとの支持度とリフト値を算出します。
from mlxtend.frequent_patterns import association_rules # アソシエーション・ルール抽出 df_rules = association_rules(freq_items, # supportとitemsetsを持つデータフレーム metric = "confidence", # アソシエーション・ルールの評価指標 min_threshold = 0.1, # metricsの閾値 )
実際のデータに当てはめた際にdf_rulesが空のデータフレームになる場合は設定した条件を満たす組み合わせが存在しないということを意味しており、その場合は metricsの閾値を0.001や0.0001みたく小さくしてあげる必要があります。
min_threshold = 0.1, # metricsの閾値
<実行結果>
# リフト値で結果を絞る df_rules2 = df_rules[df_rules["lift"]>=2.0] print(df_rules2)
注意点
アソシエーション分析はレコメンドなどでよく用いられますが、問題点としては、全ての入力商品(x)を対象とするのが難しいという点があります。
この場合はすべての入力商品が対象となるまでトランザクション数を増やす、協調フィルタリング(アイテムベース)などを用いることで補完する、といった対処法があります。
コメント