頻出な組を決まりに変える
アソシエーションルールとは、「Aを買った人はBも買う」という形で、品物どうしの関係を書いた決まりです。信頼度とリフトの2つの数字で、その決まりが役に立つかを確かめられます。
頻出な組を見つけただけでは、まだ使えません。「おにぎりを買う客にお茶をすすめる」のように、向きのある決まりにして、強さを測ります。
このレッスンのゴール
メモ
頻出な組をルールにして、信頼度とリフトで強さを評価できる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| ルール | 「Aが入っていたらBも入る」という形の決まり | おにぎり → お茶 |
| 前提 | ルールの左側の品物 | |
| 結論 | ルールの右側の品物 | |
| 信頼度 | 前提が入ったかごのうち、結論も入っていた割合 | |
| リフト | 信頼度を、結論だけの支持度で割った値 |
学生が入力するセルは、このプレビューでは空白です。
ルールには向きがある
「おにぎり → お茶」は、おにぎりが入っていたらお茶も入る、というルールです。左側を前提、右側を結論と呼びます。
信頼度は、前提が入ったかごのうち、結論も入っていた割合です。おにぎりは6かご、そのうちお茶もあるのは5かごなので、5 ÷ 6 で約 0.83 です。
例: 4つのルールの信頼度
| ルール | 両方あるかご | 前提のかご | 信頼度 |
|---|---|---|---|
| おにぎり → お茶 | 5 | 6 | 0.83 |
| お茶 → おにぎり | 5 | 5 | 1.00 |
| パン → 牛乳 | 3 | 5 | 0.60 |
| 牛乳 → パン | 3 | 3 | 1.00 |
学生が入力するセルは、このプレビューでは空白です。
コマンドで信頼度を求める
次のコマンドは、おにぎりが入ったかごのうち、お茶も入っていた割合を求めます。前のレッスンと同じ10かごを、文字で書きました。
r はおにぎり、t はお茶です。答えは 0.83 です。
おにぎり → お茶の信頼度
docker exec jupyter python3 -c 'B=["rt","rte","bm","rtb","bme","rt","bm","re","be","rt"]; print(round(sum(["r" in x and "t" in x for x in B]) / sum(["r" in x for x in B]), 2))'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
信頼度だけでは人気の品物にだまされる
レジ袋のように、ほとんどの客が買う品物があるとします。どんな品物を前提にしても、袋が入る信頼度は高くなります。
リフトは、信頼度を結論の支持度で割った値です。1より大きければ、結論が単独のときより入りやすいことを表します。1なら関係なし、1より小さければ入りにくい、です。
例: 信頼度とリフト
| ルール | 信頼度 | 結論の支持度 | リフト |
|---|---|---|---|
| おにぎり → お茶 | 0.83 | 0.5 | 1.67 |
| パン → 牛乳 | 0.60 | 0.3 | 2.00 |
| パン → たまご | 0.40 | 0.4 | 1.00 |
| おにぎり → たまご | 0.33 | 0.4 | 0.83 |
| おにぎり → 袋(別の店) | 1.00 | 0.9 | 1.11 |
学生が入力するセルは、このプレビューでは空白です。
コマンドでリフトを求める
次のコマンドは、おにぎり → お茶のリフトを求めます。信頼度 0.83 を、お茶の支持度 0.5 で割ると 1.67 になります。
コマンドでは、かごの数だけで同じ値を計算します。答えは 1.67 です。
おにぎり → お茶のリフト
docker exec jupyter python3 -c 'B=["rt","rte","bm","rtb","bme","rt","bm","re","be","rt"]; both=sum(["r" in x and "t" in x for x in B]); print(round(both * len(B) / (sum(["r" in x for x in B]) * sum(["t" in x for x in B])), 2))'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
信頼度が高いルールは、よいルールだと考えがちです。実際は、ほとんどのかごに入る品物が結論なら、どのルールも信頼度が高くなります。リフトが1に近いルールは、何も教えてくれません。
ノートブックに入力: 週末は忙しい
import csv
days = []
for row in csv.DictReader(open("hires.csv")):
items = []
if row["weekday"] in ["Sat", "Sun"]:
items.append("weekend")
if row["weather"] == "rainy":
items.append("rainy")
if float(row["temp_c"]) >= 12:
items.append("warm")
if int(row["hires"]) >= 300:
items.append("busy")
days.append(items)
def how_many(first, second):
total = 0
for items in days:
if first in items and second in items:
total = total + 1
return total
left = "weekend"
right = "busy"
confidence = how_many(left, right) / how_many(left, left)
print("信頼度:", round(confidence, 2))
print("リフト:", round(confidence / (how_many(right, right) / len(days)), 2))