Das ist das Beispiel von "Freitagabend Omeletts und Bier werden zusammen gekauft". Bei der Korbanalyse werden drei Indikatoren, Unterstützung, Vertrauen und Auftrieb, aus Verkaufsdaten berechnet. Dieser Artikel soll mit PySpark implementiert werden. Weitere Analysemethoden finden Sie in anderen Artikeln. Es gibt auch einige in Qiita.
Unterstützung(A⇒B)=P(A∩B)=\frac{Anzahl der Körbe mit A und B.}{Gesamtzahl der Körbe}
Vertrauen(A⇒B) = \frac{P(A∩B)}{P(A)}=\frac{Anzahl der Körbe mit A und B.}{Gesamtzahl der Körbe mit A.}
Erwartetes Vertrauen(A⇒B) = P(B)=\frac{Anzahl der Körbe mit B.}{Gesamtzahl der Körbe}
Aufzug(A⇒B) = \frac{P(A∩B)}{P(A)P(B)}=\frac{Vertrauen}{期待Vertrauen}
Ich werde Lebensmittel verwenden, die im Beispiel für die Analyse der R-Sprachassoziation verwendet werden. Es gibt viele Kommentarartikel und Youtube-Videos, sodass Sie die Berechnungsergebnisse leicht überprüfen können. Diese Datei enthält eine Zeile pro Korb und enthält Daten für insgesamt 9835 Körbe. Eine Zeile wird manchmal als Transaktion bezeichnet. Die ersten fünf Zeilen lauten wie folgt.
groceries.csv
citrus fruit,semi-finished bread,margarine,ready soups
tropical fruit,yogurt,coffee
whole milk
pip fruit,yogurt,cream cheese ,meat spreads
other vegetables,whole milk,condensed milk,long life bakery product
support.py
# -*- coding: utf-8 -*-
import sys
from itertools import combinations
from pprint import pprint
from pyspark import SparkContext
#Daten gelesen. Trimmen und normalisieren Sie auf Kleinbuchstaben
sc = SparkContext()
baskets = (
sc.textFile(sys.argv[1])
.map(lambda row: set([word.strip().lower() for word in row.split(",")]))
).cache()
#Gesamtzahl der Körbe
total = float(baskets.count())
result = (
baskets
#Geben Sie den Ausweis in den Warenkorb
.zipWithIndex()
#Machen Sie ein Paar Waren. Die Sortierung erfolgt für stabile Paare.
.flatMap(lambda (items, basket_id): ((tuple(sorted(c)), (basket_id,)) for c in combinations(items, 2)))
#Zählen Sie die Anzahl der Körbe mit einem Produktpaar als Schlüssel
.reduceByKey(lambda a, b: a + b)
.map(lambda pair_baskets: (pair_baskets[0], len(pair_baskets[1])))
#Unterstützung hinzufügen
.map(lambda pair_count: (pair_count[0], (pair_count[1], pair_count[1] / total * 100)))
#Nach Support in absteigender Reihenfolge sortieren
.sortBy(lambda (pair, stats): -stats[1])
)
#Top 10-Unterstützung anzeigen
pprint(result.take(10))
(Gemüse, Milch) war mit einer Häufigkeit von 736 und einer Unterstützung von 7,48% von 9835 die Spitze. Das Folgende sind Daten von Westlern wie Brot und Milch, Milch und Joghurt usw., so dass vernünftige Ergebnisse erzielt wurden.
$ spark-submit support.py groceries.csv
[((u'other vegetables', u'whole milk'), (736, 7.483477376715811)),
((u'rolls/buns', u'whole milk'), (557, 5.663446873411286)),
((u'whole milk', u'yogurt'), (551, 5.602440264361973)),
((u'root vegetables', u'whole milk'), (481, 4.89069649211998)),
((u'other vegetables', u'root vegetables'), (466, 4.738179969496695)),
((u'other vegetables', u'yogurt'), (427, 4.341637010676156)),
((u'other vegetables', u'rolls/buns'), (419, 4.260294865277071)),
((u'tropical fruit', u'whole milk'), (416, 4.229791560752415)),
((u'soda', u'whole milk'), (394, 4.006100660904932)),
((u'rolls/buns', u'soda'), (377, 3.833248601931876))]
Dann machen wir einen kurzen Umweg, um zu sehen, was die schlechtesten 10 sind. Es ist in Ordnung, wenn Sie die Reihenfolge von sortBy auf "stats [1]" setzen. Mayonnaise und Weißwein, Brandy und Süßigkeiten, Gummi und Rotwein, künstlicher Süßstoff und Hundefutter, Glühbirne und Marmelade usw. waren lustige Ergebnisse.
[((u'mayonnaise', u'white wine'), (1, 0.010167768174885612)),
((u'chewing gum', u'red/blush wine'), (1, 0.010167768174885612)),
((u'chicken', u'potato products'), (1, 0.010167768174885612)),
((u'brandy', u'candy'), (1, 0.010167768174885612)),
((u'chewing gum', u'instant coffee'), (1, 0.010167768174885612)),
((u'artif. sweetener', u'dog food'), (1, 0.010167768174885612)),
((u'meat spreads', u'uht-milk'), (1, 0.010167768174885612)),
((u'baby food', u'rolls/buns'), (1, 0.010167768174885612)),
((u'baking powder', u'frozen fruits'), (1, 0.010167768174885612)),
((u'jam', u'light bulbs'), (1, 0.010167768174885612))]
Da (X⇒Y) und (Y⇒X) unterschiedliche Konfidenzniveaus sind, habe ich Permutationen anstelle von Kombinationen verwendet, um alle Fälle aufzulisten.
confidence.py
# -*- coding: utf-8 -*-
import sys
from itertools import permutations, combinations
from pprint import pprint
from pyspark import SparkContext
#Daten gelesen. Trimmen und normalisieren Sie auf Kleinbuchstaben
sc = SparkContext()
baskets = (
sc.textFile(sys.argv[1])
.map(lambda row: set([word.strip().lower() for word in row.split(",")]))
).cache()
#Gesamtzahl der Körbe
total = float(baskets.count())
#Geben Sie den Ausweis in den Warenkorb
baskets_with_id = baskets.zipWithIndex()
# (Ein Paar Waren,Anzahl der darin enthaltenen Körbe)machen.
pair_count = (
baskets_with_id
.flatMap(lambda (items, basket_id): [(pair, (basket_id,)) for pair in permutations(items, 2)])
#Erstellen Sie eine Liste mit Körben, die ein Produktpaar als Schlüssel enthalten
.reduceByKey(lambda a, b: a + b)
#Zählen Sie die Anzahl der Körbe und fügen Sie hinzu(pair, count)
.map(lambda pair_baskets: (pair_baskets[0], len(pair_baskets[1])))
)
#Anzahl der Körbe mit Produkt X.
x_count = (
baskets_with_id
.flatMap(lambda (items, basket_id): [(x, (basket_id,)) for x in items])
#Erstellen Sie eine Liste der Warenkorb-IDs, die Produkt X enthalten
.reduceByKey(lambda a, b: a + b)
#Zählen Sie die Anzahl der Körbe und fügen Sie hinzu(x, count)
.map(lambda x_baskets: (x_baskets[0], len(x_baskets[1])))
)
#Berechnen Sie das Vertrauen für X.
confidence = (
pair_count
#Transformiert, sodass X als Schlüssel für JOIN verwendet werden kann
.map(lambda (pair, count): (pair[0], (pair, count)))
.join(x_count)
#Vertrauen hinzufügen
.map(lambda (x, ((pair, xy_count), x_count)): (pair, (xy_count, x_count, float(xy_count) / x_count * 100)))
#Sortieren Sie nach Vertrauen in absteigender Reihenfolge
.sortBy(lambda (pair, stats): -stats[2])
)
pprint(confidence.take(10))
Das Ergebnis ist ein Tupel von ((Produkt X, Produkt Y), (Anzahl der Körbe, die XY enthalten, Anzahl der Körbe, die X enthalten, Konfidenz%)). Nach Gewissheit sortiert, ist es 100% ige Gewissheit, aber es ist nur ein Beispiel für eine seltene Kombination, die nur einmal vorkommt.
$ spark-submit confidence.py groceries.csv
[((u'baby food', u'waffles'), (1, 1, 100.0)),
((u'baby food', u'cake bar'), (1, 1, 100.0)),
((u'baby food', u'dessert'), (1, 1, 100.0)),
((u'baby food', u'brown bread'), (1, 1, 100.0)),
((u'baby food', u'rolls/buns'), (1, 1, 100.0)),
((u'baby food', u'soups'), (1, 1, 100.0)),
((u'baby food', u'chocolate'), (1, 1, 100.0)),
((u'baby food', u'whipped/sour cream'), (1, 1, 100.0)),
((u'baby food', u'fruit/vegetable juice'), (1, 1, 100.0)),
((u'baby food', u'pastry'), (1, 1, 100.0))]
Wenn ich also nach [der Anzahl der Körbe, die X enthalten, der Anzahl der Körbe, die XY enthalten] sortiert habe, wurden die folgenden Ergebnisse erhalten. Milch wird am häufigsten gekauft, und das Vertrauen, dass Gemüse, Brot, Joghurt usw. zusammen gekauft werden, liegt bei 11% bis 29%.
[((u'whole milk', u'other vegetables'), (736, 2513, 29.287703939514525)),
((u'whole milk', u'rolls/buns'), (557, 2513, 22.16474333465977)),
((u'whole milk', u'yogurt'), (551, 2513, 21.92598487863112)),
((u'whole milk', u'root vegetables'), (481, 2513, 19.140469558296857)),
((u'whole milk', u'tropical fruit'), (416, 2513, 16.55391961798647)),
((u'whole milk', u'soda'), (394, 2513, 15.678471945881418)),
((u'whole milk', u'bottled water'), (338, 2513, 13.450059689614008)),
((u'whole milk', u'pastry'), (327, 2513, 13.01233585356148)),
((u'whole milk', u'whipped/sour cream'), (317, 2513, 12.614405093513728)),
((u'whole milk', u'citrus fruit'), (300, 2513, 11.937922801432551))]
Verdampfung des Quellcodes. Ich werde es veröffentlichen, sobald es gefunden wird.
Wie auch immer, Leute, die etwas kaufen, das wie ein Knopf aussieht, kaufen es eher mit Sake als alleine (lacht).
[((u'cocoa drinks', u'preservation products'), 22352.27272727273),
((u'preservation products', u'cocoa drinks'), 22352.272727272728),
((u'finished products', u'baby food'), 15367.1875),
((u'baby food', u'finished products'), 15367.1875),
((u'baby food', u'soups'), 14679.104477611942),
((u'soups', u'baby food'), 14679.10447761194),
((u'abrasive cleaner', u'preservation products'), 14050.000000000002),
((u'preservation products', u'abrasive cleaner'), 14050.0),
((u'cream', u'baby cosmetics'), 12608.97435897436),
((u'baby cosmetics', u'cream'), 12608.974358974358)]
Die Warenkorbanalyse wurde mit PySpark durchgeführt.
Dieser Artikel wurde vor langer Zeit geschrieben und als Entwurf belassen, sodass er im aktuellen Pyspark möglicherweise nicht funktioniert.
Recommended Posts