Der zweite in der Spark-Serie. Dieses Mal werden wir MLlib verwenden, um Empfehlungen mithilfe von Co-Filterung umzusetzen.
Erster Schuss [Maschinelles Lernen] Starten Sie Spark mit iPython Notebook und probieren Sie MLlib aus http://qiita.com/kenmatsu4/items/00ad151e857d546a97c3
Umgebung
Bitte beachten Sie, dass dieser Artikel beschreibt, was in der oben genannten Umgebung getan wurde, sodass die Einstellungen in anderen Umgebungen abweichen können. Außerdem soll Spark grundsätzlich auf iPython Notebook ausgeführt werden. Informationen hierzu finden Sie unter oben.
Starten Sie zuerst Spark.
#Starten Sie Spark
import os, sys
import pandas as pd
import numpy as np
from datetime import datetime as dt
print "loading PySpark setting..."
spark_home = os.environ.get('SPARK_HOME', None)
print spark_home
if not spark_home:
raise ValueError('SPARK_HOME environment variable is not set')
sys.path.insert(0, os.path.join(spark_home, 'python'))
sys.path.insert(0, os.path.join(spark_home, 'python/lib/py4j-0.8.2.1-src.zip'))
execfile(os.path.join(spark_home, 'python/pyspark/shell.py'))
Dies sind die Beispieldaten, die in Spark enthalten sind, und es gibt Daten zu Filmüberprüfungsinformationen, die als MovieLens bezeichnet werden. Verwenden Sie diese also. Lesen Sie die Daten in SPARK_HOME wie unten gezeigt.
#Beispiel zum Lesen von Daten
df = pd.read_csv(os.path.join(spark_home, 'data/mllib/als/sample_movielens_ratings.txt'),
delimiter='::', names=('uid', 'iid', 'rating','time'),engine='python')
pv_rating = df.pivot(index='uid', columns='iid', values='rating').fillna(0)
print pv_rating
Die Daten sehen so aus. uid ist die Benutzer-ID, iid ist die Element- (Film-) ID und die darin enthaltenen Daten sind die Bewertung des Films für jeden Benutzer.
uid\iid | 0 | 1 | 2 | 3 | 4 | ... | 95 | 96 | 97 | 98 | 99 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 3 | 1 | 0 | ... | 2 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 2 | 1 | 2 | ... | 0 | 1 | 1 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 3 | ... | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 |
... | |||||||||||
27 | 1 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 1 | 0 |
28 | 3 | 1 | 4 | 1 | 0 | ... | 2 | 0 | 0 | 1 | 1 |
29 | 0 | 0 | 0 | 1 | 1 | ... | 0 | 0 | 1 | 0 | 1 |
Lassen Sie uns zunächst visualisieren, um welche Art von Daten es sich handelt.
#Bewertungsvisualisierung
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.cm as cm
n_y, n_x = pv_rating.shape
X, Y = np.meshgrid(range(n_x+1), range(n_y+1))
Z = pv_rating.as_matrix()
Z.astype(np.float32)
Z = Z[::-1,:]
print Z.shape
fig = plt.figure(figsize=(19,5))
ax = plt.subplot(111)
plt.ylim(0,30)
plt.xlim(0,99)
ax.set_xticks([])
ax.set_yticks([])
cax = ax.pcolor(X, Y, Z, cmap=cm.get_cmap('ocean_r'), alpha=0.6)
cbar = fig.colorbar(cax, ticks=range(6))
#cbar.ax.set_yticklabels(['5', '4', '3', '2', '1', '0'])# vertically oriented colorbar
plt.show()
Die vertikale Achse ist der Benutzer und die horizontale Achse ist der Film. In den weißen Bereichen gibt es keine Bewertung. Wo es eine Farbe gibt, gibt es Bewertungsinformationen und die Zahlen sind farblich gekennzeichnet, wie in der Leiste rechts gezeigt.
Das Hauptthema ist von hier. Empfehlungen werden mit der in Spark enthaltenen Methode ALS (Alternating Least Squares) in MLlib abgegeben. Dies ist eine Technik, die als Co-Filterung bezeichnet wird und Rückschlüsse auf Informationen eines Benutzers und eines anderen Benutzers mit ähnlichem Geschmack zieht (hier Filmbewertung). Eine der Funktionen ist, dass der Inhalt des Films in gewissem Sinne ignoriert und aus dem Verhalten des Benutzers abgeleitet wird.
Wir werden anfangen, aus den Daten zu lernen.
from pyspark.mllib.recommendation import ALS, MatrixFactorizationModel, Rating
#Vorbereitung der Trainingsdaten
sc_rating = sc.parallelize(df.as_matrix())
ratings = sc_rating.map(lambda l: Rating(int(l[0]), int(l[1]), float(l[2])))
# ALS(Alternating Least Squares)Generieren Sie Empfehlungen mit
rank = 10
numIterations = 10
model = ALS.train(ratings, rank, numIterations)
#Geben Sie dem Teil eine Bewertung, in dem keine Daten aus den gelernten Daten vorhanden waren
n_y, n_x = pv_rating.shape
X, Y = np.meshgrid(range(n_x+1), range(n_y+1))
f_XY = np.c_[Y.flatten(), X.flatten()]
predictions_all = model.predictAll(sc.parallelize(f_XY)).map(lambda r: ((r[0], r[1]), limitter(r[2]) ))
def selector(x, y):
if x is None:
return y
elif x != 0:
return x
else:
return y
#Behalten Sie bei, wo bereits eine Bewertung vorliegt, und ersetzen Sie den von ALS berechneten Wert, wenn keine Bewertung vorliegt
ratesAndPreds = ratings.map(lambda r: ((r[0], r[1]), r[2])).rightOuterJoin(predictions_all).map(lambda r: ((r[0][0], r[0][1]), selector(r[1][0], r[1][1])) )
result = np.array(ratesAndPreds.sortBy(lambda x: (x[0], x[1])).collect())
Z = result[:,1]
Z = Z.astype(np.float32).reshape(pv_rating.shape)[::-1,:]
Visualisieren Sie die abgeleiteten Ergebnisse. In der vorherigen Grafik gab es viele weiße Teile (Teile ohne Bewertung), aber sie sind fast verschwunden! Die Stelle, an der der numerische Wert an dieser leeren Stelle eingegeben wird, ist die Empfehlungsinformation. Sie können hierfür einen bestimmten Schwellenwert festlegen und sagen: "Empfehlen, wenn er höher ist": smile:
fig = plt.figure(figsize=(19,5))
ax = plt.subplot(111)
plt.ylim(0,29)
plt.xlim(0,99)
ax.set_xticks([])
ax.set_yticks([])
cax = ax.pcolor(X, Y, Z, cmap=cm.get_cmap('ocean_r'), alpha=0.6)
cbar = fig.colorbar(cax, ticks=range(6))
plt.show()
Schauen wir uns zum Schluss die Genauigkeit dieses Lernens an. Messen Sie anhand des durchschnittlichen quadratischen Fehlers, wie weit der vorhergesagte Wert von der Stelle entfernt ist, an der ursprünglich eine Bewertung vorliegt.
#Berechnung der Genauigkeit
testdata = ratings.map(lambda p: (p[0], p[1]))
predictions = model.predictAll(testdata).map(lambda r: ((r[0], r[1]), limitter(r[2]) ))
ratesAndPreds = ratings.map(lambda r: ((r[0], r[1]), r[2])).join(predictions)
MSE = ratesAndPreds.map(lambda r: (r[1][0] - r[1][1])**2).mean()
print("Mean Squared Error = " + str(MSE))
out
#Durchschnittlicher quadratischer Fehler
Mean Squared Error = 0.0558736464582
Darüber hinaus sind die Ergebnisse bei numerischer Betrachtung wie folgt. Wenn es eine Bewertung gibt, sind die Zahlen nahe beieinander und wenn es keine gibt, ist die vorhergesagte Bewertung enthalten.
out
((uid, iid), (rating, predict))
[((29, 17), (3.0, 2.9547048179008057)),
((23, 51), (None, 1.421916504776083)),
((11, 7), (None, 1.9669319580489901)),
((28, 10), (None, 0.06769150007295854)),
((9, 93), (None, 2.349846935916598)),
((23, 91), (None, 2.597452490149535)),
((17, 13), (2.0, 2.0700773308441507)),
((16, 38), (1.0, 0.8512992797830536)),
((22, 12), (None, 3.331810711043588)),
((12, 50), (4.0, 4.095528922729588)),
((11, 15), (None, 1.1874705514088135)),
((22, 52), (None, 3.4707062021048283)),
((0, 14), (None, 0.503229802782621)),
((8, 94), (None, 1.0007500227764983)),
((29, 89), (None, 0.4272431835442813)),
((5, 1), (1.0, 1.2148556310982808)),
((4, 42), (None, 1.030942641195369)),
((25, 13), (None, 1.5033919417064503)),
((3, 55), (None, 2.50649511105159))]
Spark 1.5.0 Machine Learning Library (MLlib) Guide http://spark.apache.org/docs/latest/mllib-guide.html
MLlib - Collaborative Filtering http://spark.apache.org/docs/latest/mllib-collaborative-filtering.html
Movie Recommendation with MLlib https://databricks-training.s3.amazonaws.com/movie-recommendation-with-mllib.html
Code für diesen Artikel (GitHub) https://github.com/matsuken92/Qiita_Contents/blob/master/MLlib_recommendation/Spark_MLlib-recommendation.ipynb
Recommended Posts