【機械学習アルゴリズム学習備忘録】Accociation Rule Learning – Apriori –

Accociation Rule Learning - Apriori - プログラミング

Pythonプログラミング学習備忘録。機械学習アルゴリズムについて。

今回は、Accociation Rule Learningの中のAprioriについて。

内容は、Udemyコース「【世界で74万人が受講】基礎から理解し、Pythonで実装!機械学習26のアルゴリズムを理論と実践を通じてマスターしよう」で学んだ内容を自分用備忘録としてまとめたものです。

Association Rule Learningとは

Association Rule Learning (アソシエーション・ルール・ラーニング)とは、「ある特定の事象Aが起こったときに、事象Bが起こる確率」すなわち、事象Aと事象Bの相関性を分析する手法。

マーケティング分野などで、たとえば、紙オムツを買う客はビールも買っている=紙オムツとビールには相関性がある、というような分析に使われる。

そのAssociation Rule Learningの手法の一つが、今回のAprioriである。

直感的理解1 – 買い物を例に –

例えば、あるお店に5人のお客さんが買い物に来る場合を想定し、それぞれ次のような買い物をしたとする。

a. 牛乳、納豆、たまご、のり

b. 牛乳、たまご

c. 納豆、たまご、のり

d. たまご、のり

e. 牛乳、のり

このとき、

  • 牛乳を買った人がたまごも買う
  • 牛乳を買った人がのりも買う
  • たまごを買った人がのりも買う
  • 納豆を買った人がたまごも買う

といった相関性があることが直感的にも理解できる。

直感的理解2 – 買い物を例に –

先程の例を、数式を用いてもう少し定量的に分析する。

先程の例で、牛乳とたまごの相関性を牛乳を基準にして分析する場合を考える。

そのときに用いられる3つの指標:support, confidence, lift

support : 牛乳を買った人の数 ÷ すべてのデータの数

confidence: たまごを買った人の数 ÷ 牛乳を買った人の数

lift: confidence ÷ support

たとえば、そのお店に100人の人が来店したとする。

そのうち、10人が牛乳を買い、たまごを買った人も10人。牛乳とたまごの両方を買った人が3人いたとする。このとき、3つの指標は以下の通りになる。

support = 10 ÷ 100 = 0.1 (牛乳を買った人 ÷ すべてのデータの数)

*このとき、例えばあまり買われていない商品を基準とすると最終的な分析結果が不十分なものとなることがある。したがって、実際の分析の際には、minimum supportという値を設定し、一定の値以上のsupportになるデータを対象とするように絞り込みを行うことが一般的。

confidence = 3 ÷ 10 = 0.3 (たまごを買った人 ÷ 牛乳を買った人)

このとき、support, confidenceの値からliftが下記のように求められる。

lift = 0.3 ÷ 0.1 = 3 (confidence ÷ support)

このliftの値が大きければ大きいほど、牛乳を買った人がたまごも買う可能性が高い、という結果と言える。

Pythonによる実装1 – ライブラリの準備 –

上記のような計算をPythonを用いて実装していく。

データセットは、次のようなサンプルデータを用いる。

Accociation Rule Learning - Apriori -
サンプルcsvファイル

まずは使用するライブラリのインストールから。

!pip install apyori

今回は、scikit-learnやkerasなどではなく、apyoriというライブラリを用いてAprioriを実装していく。

次に必要なライブラリをインポートしていく。

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

ライブラリの準備ができたら、次にデータの前処理に入る。

Pythonによる実装2 – データの前処理 –

次にデータの前処理を行う。先程用意したサンプルcsvファイルを読み込み、それぞれのデータをPythonのリスト型に格納していく。

dataset = pd.read_csv("Sample.csv", header = None)

# header = Noneは対象のデータに見出しがなく、1行目からデータとして読み込んでいく場合に設定する。Apriori分析において必須というわけではない。

transactions = [] #リスト型を宣言
for i in range(0, 7501):
    transactions.append([str(dataset.values[i,j]) for j in range(0, 20)] 

#リスト内包表記を使ってpandasで読み込んだデータをリスト型に格納していく。

これでデータの前処理は完了。

Pythonによる実装3 – モデルの訓練 –

データの前処理ができたので、いよいよモデルの訓練を行う。

rules = apriori(transactions = transactions, min_support = 0.003, min_confidence = 0.2, min_lift = 3, min_length = 2, max_length = 2)

# min_supportは、上述の通り、ある一定水準以上の有効性を持つデータに絞るために設定する。
# min_supportの決め方は、データによって異なるが、たとえばデータがあるお店の1週間の売上データだとすると、1週間に1個しか売れていない商品は有効性が低いだろう。
# 一方で、毎日朝昼晩それぞれの時間帯で1個以上売れている商品であれば、ある程度の有効性が認められる可能性がある、と判断されれば、21÷全データ数の値をmin_supportの値として設定する、というような感じで決めることもできる。
# min_confidenceは、confidenceの最小値。ある程度直感的に決めることも可能。今回は仮に0.2(=20%)と設定した。
# min_length, max_lengthは、データの数。今回は2つの商品ペアの相関性を分析するので、min_length, max_lengthとも2を設定している。
# min_support, min_confidence, min_liftについては、最終的な結果を見ながら適宜調整していく方法もある。

results = list(rules) #結果をリスト型に変換

これを実行し、結果を出力すると、次のような結果が得られる。

[RelationRecord(items=frozenset({'chicken', 'light cream'}), support=0.004532728969470737, ordered_statistics=[OrderedStatistic(items_base=frozenset({'light cream'}), items_add=frozenset({'chicken'}), confidence=0.29059829059829057, lift=4.84395061728395)]),
 RelationRecord(items=frozenset({'mushroom cream sauce', 'escalope'}), support=0.005732568990801226, ordered_statistics=[OrderedStatistic(items_base=frozenset({'mushroom cream sauce'}), items_add=frozenset({'escalope'}), confidence=0.3006993006993007, lift=3.790832696715049)]),
 RelationRecord(items=frozenset({'pasta', 'escalope'}), support=0.005865884548726837, ordered_statistics=[OrderedStatistic(items_base=frozenset({'pasta'}), items_add=frozenset({'escalope'}), confidence=0.3728813559322034, lift=4.700811850163794)]),
 RelationRecord(items=frozenset({'fromage blanc', 'honey'}), support=0.003332888948140248, ordered_statistics=[OrderedStatistic(items_base=frozenset({'fromage blanc'}), items_add=frozenset({'honey'}), confidence=0.2450980392156863, lift=5.164270764485569)]),
 RelationRecord(items=frozenset({'ground beef', 'herb & pepper'}), support=0.015997866951073192, ordered_statistics=[OrderedStatistic(items_base=frozenset({'herb & pepper'}), items_add=frozenset({'ground beef'}), confidence=0.3234501347708895, lift=3.2919938411349285)]),
 RelationRecord(items=frozenset({'ground beef', 'tomato sauce'}), support=0.005332622317024397, ordered_statistics=[OrderedStatistic(items_base=frozenset({'tomato sauce'}), items_add=frozenset({'ground beef'}), confidence=0.3773584905660377, lift=3.840659481324083)]),
 RelationRecord(items=frozenset({'olive oil', 'light cream'}), support=0.003199573390214638, ordered_statistics=[OrderedStatistic(items_base=frozenset({'light cream'}), items_add=frozenset({'olive oil'}), confidence=0.20512820512820515, lift=3.1147098515519573)]),
 RelationRecord(items=frozenset({'olive oil', 'whole wheat pasta'}), support=0.007998933475536596, ordered_statistics=[OrderedStatistic(items_base=frozenset({'whole wheat pasta'}), items_add=frozenset({'olive oil'}), confidence=0.2714932126696833, lift=4.122410097642296)]),
 RelationRecord(items=frozenset({'pasta', 'shrimp'}), support=0.005065991201173177, ordered_statistics=[OrderedStatistic(items_base=frozenset({'pasta'}), items_add=frozenset({'shrimp'}), confidence=0.3220338983050847, lift=4.506672147735896)])]

これで、モデルの訓練と結果の表示が完了。

Pythonによる実装4 – 結果を整理して表示 –

最後にモデル訓練の結果を整理して表示していく。

def inspect(results):
    lhs = [tuple(result[2][0][0])[0] for result in results]
    rhs = [tuple(result[2][0][1])[0] for result in results]
    supports = [result[1] for result in results]
    confidences = [result[2][0][2] for result in results]
    lifts = [result[2][0][3] for result in results]
    return list(zip(lhs, rhs, supports, confidences, lifts))
resultsinDataFrame = pd.DataFrame(inspect(results), columns = ['Left Hand Side', 'Right Hand Side', 'Support', 'Confidence', 'Lift'])

このコードを実行することで、モデルが計算した結果をpandasのDataFrame型で整理して出力することができる。

この整理した結果を用いて、マーケティングなどの分析に応用していく。

以上。

コメント

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