Sử dụng Machine Learning trên Compute Engine để recommend sản phẩm (phần 2)

Cung cấp các recommendations

Lược đồ của bảng Recommendation như sau:

CREATE TABLE Recommendation
(
  userId varchar(255),
  accoId varchar(255),
  prediction float,
  PRIMARY KEY(userId, accoId),
  FOREIGN KEY (accoId)
    REFERENCES Accommodation(id)
);

Code walkthrough

Lấy dữ liệu từ Cloud SQL

jdbcUrl    = 'jdbc:mysql://%s:3306/%s?user=%s&password=%s' % (CLOUDSQL_INSTANCE_IP, CLOUDSQL_DB_NAME, CLOUDSQL_USER, CLOUDSQL_PWD)
dfAccos = sqlContext.read.jdbc(url=jdbcUrl, table=TABLE_ITEMS)
dfRates = sqlContext.read.jdbc(url=jdbcUrl, table=TABLE_RATINGS)

Chuyển đổi DataFrame sang RDD và tạo ra các bộ dữ liệu khác nhau

Spark sử dụng một khái niệm được gọi là RDD (Resilient Distributed Dataset), tạo điều kiện thuận lợi cho việc làm việc với các elements song song. RDDs là bộ sưu tập chỉ đọc được tạo từ bộ nhớ lưu trữ liên tục. Chúng có thể được xử lý trong bộ nhớ, vì vậy chúng rất thích hợp cho quá trình xử lý lặp.

Để có được mô hình tốt nhất cho dự đoán của bạn, bạn cần chia các bộ dữ liệu của mình thành ba bộ khác nhau. Đoạn mã sau sử dụng một chức năng trợ giúp ngẫu nhiên phân chia các giá trị không chồng chéo trên cơ sở tỷ lệ phần trăm 60/20/20:

rddTraining, rddValidating, rddTesting = dfRates.rdd.randomSplit([6,2,2])

Lưu ý: Điều quan trọng là tạo bảng Rating với các cột theo thứ tự sau: accoId, userId, rating. ALS cần làm việc với các cặp sản phẩm-người dùng xác định để dự đoán. Bạn có thể sửa đổi cơ sở dữ liệu của mình hoặc sử dụng call tới map trên RDD để sắp xếp các cột đúng cách.

Train các mô hình dựa trên các thông số khác nhau

Khi sử dụng phương pháp ALS, hệ thống cần phải làm việc với các thông số xếp hạng, định chuẩn, và lặp lại để tìm ra mô hình tốt nhất. Các xếp hạng tồn tại, vì vậy các kết quả của train phải được so sánh với bộ xác nhận. Bạn muốn đảm bảo rằng xu hướng của người dùng cũng nằm trong tập huấn luyện.

for cRank, cRegul, cIter in itertools.product(ranks, reguls, iters):

  model = ALS.train(rddTraining, cRank, cIter, float(cRegul))
  dist = howFarAreWe(model, rddValidating, nbValidating)
  if dist < finalDist:
    print("Best so far:%f" % dist)
    finalModel = model
    finalRank  = cRank
    finalRegul = cRegul
    finalIter  = cIter
    finalDist  = dist

Lưu ý: Hàm howFarAreWe sử dụng mô hình dự đoán xếp hạng trên tập dữ liệu xác thực, chỉ sử dụng các cặp sản phẩm – người dùng.

def howFarAreWe(model, against, sizeAgainst):
  # Ignore the rating column  
  againstNoRatings = against.map(lambda x: (int(x[0]), int(x[1])) )

  # Keep the rating to compare against
  againstWiRatings = against.map(lambda x: ((int(x[0]),int(x[1])), int(x[2])) )

  # Make a prediction and map it for later comparison
  # The map has to be ((user,product), rating) not ((product,user), rating)
  predictions = model.predictAll(againstNoRatings).map(lambda p: ( (p[0],p[1]), p[2]) )

  # Returns the pairs (prediction, rating)
  predictionsAndRatings = predictions.join(againstWiRatings).values()

  # Returns the variance
  return sqrt(predictionsAndRatings.map(lambda s: (s[0] - s[1]) ** 2).reduce(add) / float(sizeAgainst))

Tính các dự đoán hàng đầu cho người dùng

# Build our model with the best found values
# Rating, Rank, Iteration, Regulation
model = ALS.train(rddTraining, BEST_RANK, BEST_ITERATION, BEST_REGULATION)

# Calculate all predictions
predictions = model.predictAll(pairsPotential).map(lambda p: (str(p[0]), str(p[1]), float(p[2])))

# Take the top 5 ones
topPredictions = predictions.takeOrdered(5, key=lambda x: -x[2])
print(topPredictions)

schema = StructType([StructField("userId", StringType(), True), StructField("accoId", StringType(), True), StructField("prediction", FloatType(), True)])

dfToSave = sqlContext.createDataFrame(topPredictions, schema)
dfToSave.write.jdbc(url=jdbcUrl, table=TABLE_RECOMMENDATIONS, mode='overwrite')

Lưu các dự đoán hàng đầu

Bây giờ bạn có một danh sách tất cả các dự đoán, bạn có thể lưu top 10 trong Cloud SQL để hệ thống có thể đưa ra một số đề xuất cho người dùng. Ví dụ, thời điểm tốt để sử dụng những dự đoán này có thể là khi người dùng đăng nhập vào trang web.

dfToSave = sqlContext.createDataFrame(topPredictions, schema)
dfToSave.write.jdbc(url=jdbcUrl, table=TABLE_RECOMMENDATIONS, mode='overwrite')

Thực hiện các giải pháp

Truy vấn, khi chạy trong Cloud Platform Console mây hoặc MySQL khách, trả về kết quả tương tự như ví dụ sau:

Trong trang web, cùng một truy vấn có thể nâng cao trang chào mừng và tăng khả năng chuyển đổi khách truy cập cho khách hàng:

Giám sát công việc

Giám sát với thiết lập bdutil

The Spark console

Theo dõi với Cloud Dataproc

Xem tài liệu Cloud Dataproc để tìm hiểu thêm về output hoặc web interfaces.

Tutorial

Toàn bộ nội dung tutorial, gồm các hướng dẫn setup và source code trên GitHub.

Các bước tiếp theo

  • Hãy thử các tính năng khác của Google Cloud Platform cho chính bạn. Hãy xem

    hướng dẫn

    của chúng tôi.

  • Tìm hiểu cách sử dụng các sản phẩm của Google Cloud Platform để xây dựng giải pháp end-to-end

Phụ lục

Cross filtering

Mặc dù bạn đã thấy cách xây dựng giải pháp collaborative filter hiệu quả và có thể mở rộng, vượt qua các kết quả với các loại lọc khác có thể cải thiện đề xuất. Nhớ lại hai loại lọc chính khác: dựa vào  content-based và clustering. Một sự kết hợp của những cách tiếp cận này có thể tạo ra một khuyến cáo tốt hơn cho người sử dụng.

Content-based filtering

Một cách phổ biến để tính sự giống nhau giữa hai sản phẩm là sử dụng sự giống nhau giữa cô sin và tìm những tính chất gần nhất:

Kết quả tương tự sẽ là từ 0 đến 1. Gần đến 1, các sản phẩm càng giống nhau.

Trong ma trận này, sự tương tự giữa P1 và P2 có thể được tính như sau:

Bạn có thể lọc được dựa trên nội dung thông qua các công cụ khác nhau. Nếu bạn muốn tìm hiểu thêm, hãy xem:

  • CosineSimilarities Scala được thêm vào MLlib có thể được chạy trong môi trường Spark.Twitter tất cả các cặp giống nhau . Chức năngScala được thêm vào MLlib có thể được chạy trong môi trường Spark.
  • bdutil. Bạn có thể thêm Mahout vào thiết lập hiện tại bằng cách nhân bản dự án GitHub:Mahout . Nếu bạn muốn truy cập vào nhiều thư viện để bổ sung hoặc thay thế một số thuật toán MLlib, bạn có thể cài đặt Mahout vào thiết lập. Bạn có thể thêm Mahout vào thiết lập hiện tại bằng cách nhân bản dự án GitHub:


export MAHOUT_HOME=/path/to/mahout
export MAHOUT_LOCAL=false #For cluster operation
export SPARK_HOME=/path/to/spark
export MASTER=spark://hadoop-m:7077 #Found in Spark console

Clustering

Ví dụ, đối với giải pháp này, một người đang tìm kiếm để thuê một ngôi nhà ở London có thể không quan tâm đến việc cho thuê một cái gì đó ở Auckland, do đó, hệ thống nên lọc ra các trường hợp đó khi thực hiện khuyến nghị.

from pyspark.mllib.clustering import KMeans, KMeansModel
clusters = KMeans.train(parsedData, 2,
                        maxIterations=10,
                        runs=10,
                        initializationMode="random")

Chế độ xem 360 độ

Suy nghĩ nhiều hơn, không chỉ là dữ liệu hệ thống nội bộ sẽ có tác động đến hành vi và lựa chọn của người dùng; các yếu tố bên ngoài cũng quan trọng. Trong trường hợp cho thuê kỳ nghỉ của giải pháp này, việc có thể biết được chất lượng không khí có thể rất quan trọng đối với một gia đình trẻ. Vì vậy, tích hợp công cụ đề xuất được xây dựng trên Cloud Platform với API khác, chẳng hạn như Breezometer, có thể mang lại lợi thế cạnh tranh.