Pythonによるアプリオリ・アルゴリズムを用いたアソシエーション・ルール・マイニング

アソシエーションルールマイニングは、異なる項目間の基本的な関係を特定するための手法である。

例えば、顧客が様々な商品を購入するスーパーマーケットを考えてみよう。

通常、顧客が購入するものにはパターンがある。

例えば、赤ちゃんを連れたお母さんは、ミルクやおむつなどのベビー用品を購入します。

独身者はビールやポテトチップスを買うかもしれない。

要するに、取引にはパターンがあるのだ。

異なる取引で購入された品目間の関係を識別することができれば、より多くの利益を生み出すことができる。

例えば、アイテムAとBがより頻繁に一緒に購入されている場合は、利益を増やすためにいくつかの手順を実行することができます。

    1. AとBを一緒に置くことで、顧客がどちらかの製品を買ったときに、もう一方の製品を買うために遠くまで行く必要がないようにすることができる。
    1. 片方の商品を買った人を対象に、もう片方の商品を買うように広告キャンペーンを行うことができる。
  1. 3.お客様が両方の製品を購入する場合、これらの製品で集団割引を提供することができます。
  2. AとBを一緒にパッケージすることができる。

このように、商品間の関連性を特定する作業をアソシエーションルールマイニングと呼ぶ。

関連ルールマイニングのためのアプリオリ・アルゴリズム

アソシエーションルールマイニングを実装するために、様々な統計アルゴリズムが開発されており、Aprioriもそのようなアルゴリズムの1つです。

この記事では、Aprioriアルゴリズムの背後にある理論を勉強し、後でPythonでAprioriアルゴリズムを実装します。

アプリオリ・アルゴリズムの理論

Apriori アルゴリズムには3つの主要な構成要素がある。

  • サポート
  • 信頼性
  • リフト

これらの3つのコンセプトを例題を使って説明する。

例えば、1,000 件の顧客取引の記録があり、ハンバーガーとケチャップのような 2 品目について支持率、信頼度、リフトを求めるとする。

1,000件の取引のうち、100件はケチャップ、150件はハンバーガーである。

ハンバーガーが購入された150件の取引のうち、50件はケチャップも含まれている。

このデータを使って、支持率、信頼度、揚力を求めたい。

サポート

支持率とは、ある項目のデフォルトの人気度を意味し、特定の項目を含む取引数を総取引数で割ることによって計算することができる。

例えば、商品Bの支持率を求めるとすると、次のように計算されます。

Support(B) = (Transactions containing (B))/(Total Transactions)


たとえば、1000件のトランザクションのうち、100件がケチャップを含むとすると、ケチャップの支持率は次のように計算されます。

Support(Ketchup) = (Transactions containingKetchup)/(Total Transactions)


Support(Ketchup) = 100/1000
                 = 10%


信頼性

信頼度とは、ある商品Aが買われたとき、その商品Bも買われる可能性のことである。

AとBが一緒に買われた取引の数を、Aが買われた取引の総数で割ることで計算できる。

数学的には、次のように表される。

Confidence(A→B) = (Transactions containing both (A and B))/(Transactions containing A)


今回の問題に戻ると、ハンバーガーとケチャップが一緒に買われた取引は50件でした。

一方、150件の取引では、ハンバーガーが買われました。

すると、ハンバーガーを買ったときにケチャップを買う可能性は、ハンバーガーの信頼度 – ケチャップの信頼度と表すことができ、数学的に次のように書くことができます。

Confidence(Burger→Ketchup) = (Transactions containing both (Burger and Ketchup))/(Transactions containing A)


Confidence(Burger→Ketchup) = 50/150
                           = 33.3%


これはナイーブベイスのアルゴリズムと似ていることに気がつくかもしれないが、この2つのアルゴリズムは異なる種類の問題を対象としている。

リフト

Lift(A – B)とは、Aが売れたときにBが売れる割合が増えることを指します。

Lift(A -> B)は、「Confidence(A ->)」を「Support(B)`」で割ることによって算出される。

数学的には次のように表すことができる。

Lift(A→B) = (Confidence (A→B))/(Support (B))


ハンバーガーとケチャップの問題に戻ると、Lift(Burger -> Ketchup)は次のように計算されます。

Lift(Burger→Ketchup) = (Confidence (Burger→Ketchup))/(Support (Ketchup))


Lift(Burger→Ketchup) = 33.3/10
                     = 3.33


Liftは基本的に、ハンバーガーとケチャップを一緒に買う可能性は、ケチャップだけを買う可能性の3.33倍であることを示しています。

1より大きい場合は、製品AとBが一緒に買われる可能性が高いことを意味する。

最後に、Liftが1より小さい場合は、2つの製品が一緒に買われる可能性が低いことを意味する。

アプリオリ アルゴリズムのステップ

大規模なデータセットでは、何十万ものトランザクションの中に何百もの項目が存在することがある。

アプリオリ・アルゴリズムは、各項目の可能な組み合わせに対してルールを抽出しようとする。

例えば、項目1と項目2、項目1と項目3、項目1と項目4、そして項目2と項目3、項目2と項目4、そして項目1、項目2、項目3、同様に項目1、項目2、項目4といった組み合わせに対してLiftを計算することが可能である。

上記の例からわかるように、この処理は組み合わせの数が多いため、非常に時間がかかることがあります。

この処理を高速化するためには、次のような手順が必要です。

  1. 支持率と信頼度の最小値を設定する。これは、特定のデフォルトの存在(例:サポート)を持ち、他の項目との共起度(例:確信度)に最小値を持つ項目のルールだけを見つけることに関心があることを意味する。
    1. サポートの値が最小しきい値より大きい部分集合をすべて抽出する。
  2. 3.部分集合から、信頼度が最小閾値より高いルールを全て選択する。
    1. Liftの降順でルールを並べる。

Pythonによるアプリオリ・アルゴリズムの実装

理論はもう十分なので、今度はアプリオリ・アルゴリズムを実際に見てみましょう。

このセクションでは、フランスの小売店での1週間の7500のトランザクションから、異なる商品間の関連性を記述するルールを見つけるために、アプリオリ・アルゴリズムを使用します。

データセットは以下のリンクからダウンロードできる。

302 Moved

もう一つの興味深い点は、すべての可能なアイテムの組み合わせについて、サポート、信頼度、リフトを計算するスクリプトを書く必要がないことである。

我々は、すべてのコードがすでに実装されている既製のライブラリを使用する。

そのライブラリとはapyoriで、ソースはここにある。

先に進む前に、このライブラリをダウンロードし、Pythonライブラリのデフォルトパスにインストールすることをお勧めします。

注:この記事のすべてのスクリプトはSpyder IDE for Pythonを使って実行されています。

PythonでAprioriアルゴリズムを実装するには、以下のステップに従ってください。

ライブラリをインポートする

いつものように、最初のステップは必要なライブラリのインポートです。

以下のスクリプトを実行してください。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from apyori import apriori


上のスクリプトでは、pandas、numpy、pyplot、aprioriのライブラリをインポートしています。

データセットのインポート

では、データセットをインポートして、どんな作業をしているのか見てみましょう。

データセットをダウンロードして、Dドライブの “Datasets “フォルダに入れ(または、以下のコードをコンピュータ上のファイルのパスに合わせて変更し)、以下のスクリプトを実行してください。

store_data = pd.read_csv('D:Datasetsstore_data.csv')


head()`関数を呼び出して、データセットがどのように見えるか見てみよう。

store_data.head()


データセットの断片は上のスクリーンショットのとおりである。

データを注意深く見ると、ヘッダーが実は最初のトランザクションであることがわかる。

各行が取引に対応し、各列がその取引で購入された品目に対応する。

NaN`は、その列で表される品目がその特定の取引で購入されなかったことを示す。

このデータセットにはヘッダー行がない。

しかし、デフォルトでは pd.read_csv 関数は最初の行をヘッダーとして扱います。

この問題を解決するには、以下のように pd.read_csv 関数に header=None オプションを追加してください。

store_data = pd.read_csv('D:Datasetsstore_data.csv', header=None)


次に、head()関数を実行します。

store_data.head()


この更新された出力では、以下のように、最初の行がヘッダではなくレコードとして扱われていることがわかります。

それでは、アプリオリ・アルゴリズムを使って、どの商品がよく一緒に売られているかを調べ、店主が利益を上げるために、関連する商品を一緒に置いたり、一緒に広告を出したりするアクションを取ることができるようにします。

データプロセシング

我々が使おうとしているAprioriライブラリは、データセットがリストのリストの形であることを要求します。

ここで、データセット全体は大きなリストであり、データセット内の各トランザクションは外側の大きなリストの中の内側のリストです。

現在、私たちはpandasのdataframeの形でデータを持っています。

pandasのdataframeをリストのリストに変換するには、以下のスクリプトを実行します。

records = []
for i in range(0, 7501):
    records.append([str(store_data.values[i,j]) for j in range(0, 20)])


アプリオリの適用

次のステップは、データセットに Apriori アルゴリズムを適用することである。

これを行うには、apyori ライブラリからインポートした apriori クラスを使用することができます。

aprioriクラスは動作するためにいくつかのパラメータ値を必要とします。

最初のパラメータは、ルールを抽出したいリストのリストである。

2つ目のパラメータはmin_supportパラメータである。

このパラメータは、パラメータで指定した値よりも大きなサポート値を持つ項目を選択するために使用される。

次に、min_confidenceパラメータは、パラメータで指定された信頼度の閾値よりも大きい信頼度を持つルールをフィルタリングします。

同様に、min_liftパラメータは、短いリストアップされたルールの最小リフト値を指定します。

最後に、min_length` パラメータは、ルールに含まれるアイテムの最小数を指定します。

例えば、1日に5回以上購入される商品、つまり1週間に7×5=35回購入される商品についてのみルールを設定するとします(データセットは1週間分です)。

これらのアイテムのサポートは35/7500 = 0.0045と計算できる。

ルールの最小信頼度は20%または0.2である.同様に、liftの値を3とし、最終的に min_length は2です。

これはルールの中に少なくとも2つの製品が必要だからです。

これらの値はほとんど任意に選んだものなので、これらの値で遊んでみて、返ってくるルールにどんな違いが出るか見てみてください。

以下のスクリプトを実行してみてください。

association_rules = apriori(records, min_support=0.0045, min_confidence=0.2, min_lift=3, min_length=2)
association_results = list(association_rules)


2行目では、aprioriクラスが見つけたルールをlistに変換しています。

この形式の方が結果を見やすくなるからです。

結果を表示する

まず、aprioriクラスによってマイニングされたルールの総数を求めてみましょう。

以下のスクリプトを実行する。

print(len(association_rules))


上のスクリプトは48を返すはずです。

各項目は1つのルールに対応する。

最初のルールを見るために、association_rules リストの最初の項目を表示してみましょう。

以下のスクリプトを実行する。

print(association_rules[0])


出力はこのようになるはずである。

RelationRecord(items=frozenset({'light cream', 'chicken'}), support=0.004532728969470737, ordered_statistics[OrderedStatistic(items_base=frozenset({'light cream'}), items_add=frozenset({'chicken'}), confidence=0.29059829059829057, lift=4.84395061728395)])


リストの最初の項目は、3つの項目を含むリストそのものです。

リストの最初の項目は、ルールの中の食料品の項目を示しています。

たとえば、最初の項目から、ライトクリームとチキンがよく一緒に買われていることがわかります。

これは、生クリームを買う人は、食べるものに気を使っているので、牛肉などの赤身の肉ではなく、鶏肉などの白身の肉を買う可能性が高いということを意味しています。

あるいは、鶏肉のレシピに生クリームがよく使われることを意味しているのかもしれない。

最初のルールの支持値は0.0045です。

この数値は、ライトクリームを含む取引数を総取引数で割ることによって計算される。

このルールの信頼水準は0.2905で、これはライト・クリームを含むすべての取引のうち、29.05%がチキンも含むことを示している。

最後に、揚力4.84は、チキンが売られる可能性が既定値より4.84倍も高いことを示す。

次のスクリプトは、各ルール、サポート、信頼度、リフトをより分かりやすく表示する。

for item in association_rules:


# first index of the inner list
    # Contains base item and add item
    pair = item[0] 
    items = [x for x in pair]
    print("Rule: " + items[0] + " -> " + items[1])


#second index of the inner list
    print("Support: " + str(item[1]))


#third index of the list located at 0th
    #of the third index of the inner list


print("Confidence: " + str(item[2][0][2]))
    print("Lift: " + str(item[2][0][3]))
    print("=====================================")


上記のスクリプトを実行すると、aprioriクラスが返す全てのルールが表示される。

apriori` クラスが返す最初の4つのルールは次のようなものである。

Rule: light cream -> chicken
Support: 0.004532728969470737
Confidence: 0.29059829059829057
Lift: 4.84395061728395
=====================================
Rule: mushroom cream sauce -> escalope
Support: 0.005732568990801126
Confidence: 0.3006993006993007
Lift: 3.790832696715049
=====================================
Rule: escalope -> pasta
Support: 0.005865884548726837
Confidence: 0.3728813559322034
Lift: 4.700811850163794
=====================================
Rule: ground beef -> herb & pepper
Support: 0.015997866951073192
Confidence: 0.3234501347708895
Lift: 3.2919938411349285
=====================================


最初の規則についてはすでに説明した。

次に、2番目のルールについて説明しましょう。

2番目のルールは、マッシュルームクリームソースとエスカロップがよく買われることを述べています。

マッシュルームクリームソースの支持率は 0.0057 です。

この規則の信頼度は0.3006であり、これはマッシュルームを含むすべての取引のうち、30.06%の取引が同様にエスカロップを含む可能性があることを意味している。

最後に、3.79の揚力は、エスカロップが既定の販売と比較して、マッシュルームクリームソースを購入する顧客によって購入される可能性が3.79高いことを示しています。

さらに上を目指す – 手作りのEnd to Endプロジェクト

好奇心旺盛なあなたは、もっと先を目指したいと思っていませんか?そんなあなたには、ガイド付きプロジェクトがおすすめです。

「ハンズオン住宅価格予測 – Pythonによる機械学習” をご覧ください。

をご覧ください。

このプロジェクトでは、Scikit-LearnとKerasのモデルから住宅価格を予測するために、従来の機械学習モデルや深層学習モデル、アンサンブル学習、メタラーを利用した強力な構築方法を学ぶことができます。

Tensorflowの上に構築された深層学習APIであるKerasを使って、アーキテクチャを試し、積み重ねたモデルのアンサンブルを構築し、メタラーナーのニューラルネットワーク(レベル1モデル)を訓練して、家の価格を割り出すことにします。

ディープラーニングは素晴らしいものですが、それに頼る前に、浅い学習アルゴリズムのような、より単純な技術で問題を解決することも試みることをお勧めします。

ベースラインの性能は、ランダムフォレスト回帰アルゴリズムに基づくものです。

さらに、Scikit-Learnを使用して、バギングや投票などの手法により、モデルのアンサンブルを作成することも検討します。

これはエンドツーエンドのプロジェクトであり、他の機械学習プロジェクトと同様に、探索的データ分析から始まり、データ前処理を経て、最後に浅い学習と深い学習のモデルを構築して、以前に探索しクリーニングしたデータに適合させることになります。

結論

アプリオリのようなアソシエーションルールマイニングアルゴリズムは、データ項目間の単純な関連性を見つけるのに非常に有用である。

実装も簡単で、説明能力も高い。

しかし、GoogleやAmazonなどで使われているような、より高度な洞察には、レコメンダーシステムのような、より複雑なアルゴリズムが使われます。

しかし、この方法は、あなたのユースケースに必要な基本的な関連性を得るための非常にシンプルな方法であることがお分かりいただけると思います。

タイトルとURLをコピーしました