5. Nội dung nghiên cứu
2.3.1. Đánh giá dự đoán xếp hạng sản phẩm
- Sai số tuy t đối trung bình (MAE - Mean Absolute Error): MAE
đo độ lớn trung bình của các lỗi trong một tập hợp các dự đoán mà không cần xem xét hƣớng của chúng. Đó là giá trị trung bình trên mẫu thử nghiệm về sự
khác biệt tuyệt đối giữa dự đoán và quan sát thực tế, trong đó tất cả các khác biệt riêng lẻ có trọng số bằng nhau.
| | ∑ | ̂ |
( )
- Lỗ ìn p ƣơn ốc (RMSE - Root Mean Squared Error) :
RMSE là một quy tắc t nh điểm bậc hai cũng đo độ lớn trung bình của lỗi. Đó là căn bậc hai của trung bình của sự khác biệt bình phƣơng giữa dự đoán và quan sát thực tế.
√| | ∑ ( ̂ )
( )
Trong đó:
- T là tập dữ liệu đánh giá gồm các cặp (u,i)
- biểu diễn đánh giá của ngƣời dùng u trên bộ phim i
- ̂ biểu diễn đánh giá dự đoán của ngƣời dùng u trên bộ phim i
* Thuật toán 1: Đán á độ l ch theo RMSE, MAE [7]:
Input: Cơ sở dữ liệu D đã bao gồm dữ liệu huấn luyện và dữ liệu
đánh giá.
Output: Độ lệch của dự đoán xếp hạng theo độ đo RMSE, MAE. Action:
Duyệt từng cặp ngƣời dùng (u) và sản phẩm (i) theo quan hệ RATED_LATER (r):
- Thực hiện tính predictRating = predictRating(u, i) - T nh độ lệch r.rating – predictRating
T nh độ lệch error căn bậc hai trung bình tổng độ lệch bình phƣơng (cho RMSE) hoặc trung bình độ lệch (cho MAE).
* Lƣu dự đoán v o Neo4j [7]:
def listUM():
rec = graph.run('MATCH (u:User)-[r:RATED_LATER]->(m:Movie) RETURN u.id as userid, m.id as movieid, r.rating as rating, r.predCosin as predCosin, r.predPearson as predPearson')
df = rec.to_data_frame() return df def predictData(): df = listUM() for i in range(len(df)): uid = df.iloc[i].userid mid = df.iloc[i].movieid
predP = predictRatingPearson(uid, mid) predC = predictRatingCosin(uid, mid) if predP == None:
predP = 0 if predC == None:
predC = 0
graph.run('''MATCH (u:User{id:$userid})-[r:RATED_LATER]-
>(m:Movie{id:$movieid}) SET r.predPearson = $predP SET r.predCosin = $predC''', userid=uid, movieid = mid, predP = predP, predC = predC)
* C đặt thuật toán sử dụn độ tƣơn tự Cosin [7]:
def mae_rmse(): df = listUM() s1 = 0
s2 = 0
tg = abs(df.iloc[i].rating-df.iloc[i].predCosin) ttg = tg * tg s1 = s1 + tg s2 = s2 + ttg mae = s1/len(df) rmse = math.sqrt(s2/len(df)) return mae, rmse
a, b = mae_rmse() print(a, b)
* C đặt thuật toán sử dụn độ tƣơn quan Pearson [7]:
def mae_rmse(): df = listUM() s1 = 0 s2 = 0 for i in range(len(df)): tg = abs(df.iloc[i].rating-df.iloc[i].predPearson) ttg = tg * tg s1 = s1 + tg s2 = s2 + ttg mae = s1/len(df) rmse = math.sqrt(s2/len(df)) return mae, rmse
a, b = mae_rmse() print(a, b)
2.3.2. Đánh giá gợi ý sản phẩm [8]
TP (True Positives): Những bộ phim n ƣời dùng thích và hệ thống có gợi ý.
FP (False Positives): Những bộ phim n ƣời dùng không thích và hệ
TN (True Negatives): Những bộ phim n ƣời dùng không thích nhƣng hệ thống không đƣa ra gợi ý.
FN (False negatives): Những bộ phim n ƣời dùng thích nhƣng hệ thống không đƣa ra gợi ý.
- Độ chính xác Precision: - Độ bao ph Recall: - Độ đo F1-Score:
* Thuật toán 2: Đán á độ chính xác c a gợi ý sản phẩm cho n ƣời dùng [7]
Input: Cơ sở dữ liệu D đã bao gồm dữ liệu huấn luyện và dữ liệu
đánh giá.
Output: Độ lệch của gợi ý Precision, Recall, F1 Action:
Duyệt từng cặp ngƣời dùng (u) và sản phẩm (i) theo quan hệ RATED_LATER (r):
- Thêm thuộc tính like vào quan hệ RATED_LATER là 1 nếu rating>=3, 0 nếu ngƣợc lại
- Thực hiện tính predictRating = predictRating(u, i)
predictRating> 3, ngƣợc lại là 0
Duyệt từng cặp ngƣời dùng (u) và sản phẩm (i) theo quan hệ RATED_LATER (r):
- Nếu like = 1 và like_late = 1 thì TP = TP + 1 - Nếu like = 1 và like_late = 0 thì FN = FN + 1 - Nếu like = 0 và like_late = 1 thì FP = FP + 1 - Nếu like = 0 và like_late = 0 thì TN =TN + 1 Precision = TP/(TP + FP)
Recall = TP/(TP + FN)
F1Score = 2 * Precision * Recall / (Precision + Recall)
return Precision, Recall, F1Score
* C đặt thuật toán tính Precision, Recall và F1 Score sử dụng Pearson [7]: def precision_recall_F1(): df = listUM() TP = 0 TN = 0 FP = 0 FN = 0 for i in range(len(df)): r = df.iloc[i].rating p = df.iloc[i].predPearson if r >=3 and p >=3: TP = TP + 1 if r >=3 and p < 3: FN = FN + 1 if r < 3 and p >=3: FP = FP + 1 if r < 3 and p < 3: TN = TN + 1 pre = TP/(TP + FP)
rec = TP/(TP + FN)
f1 = 2*pre*rec/(pre+rec) return pre, rec, f1
* C đặt thuật toán tính Precision, Recall và F1 Score sử dụng Cosin [7]: def precision_recall_F1(): df = listUM() TP = 0 TN = 0 FP = 0 FN = 0 for i in range(len(df)): r = df.iloc[i].rating p = df.iloc[i].predCosin if r >=3 and p >=3: TP = TP + 1 if r >=3 and p < 3: FN = FN + 1 if r < 3 and p >=3: FP = FP + 1 if r < 3 and p < 3: TN = TN + 1 pre = TP/(TP + FP) rec = TP/(TP + FN) f1 = 2*pre*rec/(pre+rec) return pre, rec, f1
2.4. Ti u kết ƣơn 2
Trong chƣơng này luận văn đã tìm hiểu cách tổ chức dữ liệu và xây dựng CSDL trên Neo4j, thực hiện các thuật toán của hệ gợi ý dựa trên bộ dữ liệu MovieLens để đƣa ra gợi ý các bộ phim cho ngƣời dùng dựa vào các phim họ đã đánh giá và những ngƣời dùng khác đã đánh giá cũng nhƣ thuật toán top k-sản phẩm bằng NNLT Python, ngôn ngữ truy vấn Cypher và thƣ viện py2neo. Đồng thời cũng trình bày và xây dựng các thuật toán đánh giá độ tin cậy của dự đoán xếp hạng sản phẩm bằng các độ đo MAE và RMSE,
đồng thời đánh giá kết quả gợi ý sản phẩm cho ngƣời dùng bằng độ chính xác Precision, độ bao phủ Recall và độ đo F1-Score [8].
Trong chƣơng tiếp theo, luận văn sẽ tập trung thực nghiệm các thuật toán, thu thập kết quả và đánh giá kết quả thực nghiệm để nhìn nhận những kết quả đạt đƣợc cũng nhƣ những vấn đề còn tồn tại mà đề tài đã đặt ra. Đồng thời, từ kết quả đã đạt đƣợc, luận văn cũng đƣa ra hƣớng phát triển, mở rộng đề tài về sau.
CHƢƠNG 3. THỰC NGHIỆM
Trong chƣơng này, luận văn tập trung trình bày các kết quả thực nghiệm các thuật toán của hệ gợi ý dựa trên bộ dữ liệu MovieLens để đƣa ra gợi ý các bộ phim đã trình bày trong chƣơng 2. Đánh giá và so sánh kết quả dự đoán của luận văn so với dự đoán trực tiếp, đồng thời đánh giá độ chính xác của các thuật toán đó.
3.1. Công cụ thực nghi m
Cơ sở dữ liệu mô hình đồ thị: Neo4j Desktop phiên bản 1.4.8.
Ngôn ngữ lập trình: Python phiên bản 3.8.8, kết hợp thƣ viện py2neo. Dữ liệu:
- Sử dụng bộ dữ liệu Movielens 100k (download tại:
https://grouplens.org/datasets/movielens/100k/). Số ngƣời dùng: 943, số bộ
phim: 1.682, số lƣợt xếp hạng: 100.000.
- Sử dụng bộ dữ liệu Movielens 1M (download tại:
https://grouplens.org/datasets/movielens/1m/). Số ngƣời dùng: 6040, số bộ
phim: 3952, số lƣợt xếp hạng: 1.000.209.
- Sử dụng bộ dữ liệu Movielens 20M (download tại:
https://grouplens.org/datasets/movielens/20m/). Số ngƣời dùng: 138.493, số
bộ phim: 27.278, số lƣợt xếp hạng: 20.000.263.
Máy tính: Laptop Dell 5480 Chip Intel Core i5-7440HQ CPU 2.8 GHz, RAM: 24GB, SSD: 1TB, Hệ điều hành Windows 10.
Mã lệnh thực nghiệm của luận văn đƣợc công bố tại:
https://github.com/LQ-Computer/Recomendation-System-on-Graph-Database
Neo4j bằng cách sử dụng Ngôn ngữ lập trình Python, ngôn ngữ truy vấn Cypher và thƣ viện py2neo:
#Import thư viện và kết nối Neo4j import csv
import os
from py2neo import Graph, Node
graph=Graph("bolt://localhost:7687",auth=("neo4j", "123456789")) #Load file movies.csv và tạo node Movie
def loadMovies():
with open('data/ml-20m/movies.csv', encoding="latin-1") as csvfile:
readCSV = csv.reader(csvfile, delimiter=',') for i, row in enumerate(readCSV):
createMovieNodes(row) def createMovieNodes(row):
movieData = parseRowMovie(row) id = movieData[0]
title = movieData[1]
mov = Node("Movie", id=id, title=title) graph.create(mov)
def parseRowMovie(row): id = row[0] title = row[1] return (id, title) loadMovies()
#Load file ratings.csv, tạo node User và tạo quan hệ User - RATED - Movie
def createUserNodes(row):
user = Node("User", id="User " + row[0]) graph.merge(user, "User", "id")
def createRatingRelationship(row):
ratingData = parseRowRatingRelationships(row) graph.run(
'MATCH (u:User {id: $userId}), (m:Movie {id: $movieId}) CREATE (u)-[:RATED { rating: $rating, timestamp: $timestamp }]- >(m)',
userId=ratingData[0], movieId=ratingData[1],
rating=ratingData[2], timestamp=ratingData[3]) def parseRowRatingRelationships(row):
userId = "User " + row[0] movieId = row[1]
rating = float(row[2]) timestamp = row[3]
return (userId, movieId, rating, timestamp) def loadRatings():
with open('data/ml-20m/ratings.csv', encoding="latin-1") as csvfile:
readCSV = csv.reader(csvfile, delimiter=',') for i,row in enumerate(readCSV):
createUserNodes(row)
createRatingRelationship(row) loadRatings()
# Tạo Index cho các đối tượng
graph.run('CREATE INDEX ON :User(id)') graph.run('CREATE INDEX ON :Movie(id)')
3.2. Thực nghi m
Bản 3. 1. Cá ộ dữ l u t ự n
Tên bộ dữ li u Số n ƣời dùng Số bộ phim Số lƣợt rating
Movielens100K 943 1.682 100.000
Movielens1M 6.040 3.952 1.000.000
Thực nghi m 1: Đánh giá tốc độ gợi ý
Mục đ ch thực nghiệm là đánh giá tốc độ gợi ý các bộ phim cho một ngƣời dùng bằng 2 cách:
i) Nạp và xử lý trực tiếp dữ liệu từ file .csv bằng Python; ii) Dữ liệu lƣu trong cơ sở dữ liệu Neo4j.
Thao tác thực nghiệm: t nh và đƣa ra danh sách các bộ phim cho một ngƣời dùng cụ thể sử dụng độ đo Cosin.
Kết quả thực nghiệm trên 3 bộ dữ liệu nhƣ sau:
Bản 3. 2. Kết quả t ự n về tố độ xử lý
Bộ dữ li u Dữ li u csv Dữ li u Neo4j
Movielens100K 0.16s 0.19s
Movielens1M 2.4s 1.6s
Movielens20M Không xử lý đƣợc 24.23s
Qua thực nghiệm cho thấy với dữ liệu lớn thì việc gợi ý trên dữ liệu đƣợc lƣu trữ tr n cơ sở dữ liệu mô hình đồ thị sẽ hiệu quả hơn về thời gian. Qua đó cũng có thể thấy đƣợc có thể sử dụng mô hình đồ thị trong các hệ gợi ý thực tế.
Thực nghiệm 2. Đánh giá độ chính xác gợi ý
Dữ liệu đánh giá: Bộ dữ liệu Movielens 100K đã đƣợc chia làm 2 phần đánh giá và huấn luyện theo tỷ lệ 20%, 80% với 5 cách chia khác nhau đƣợc cung cấp bởi Movilens Group. Cách đánh giá đƣợc thực hiện theo Thuật toán 1 và Thuật toán 2.
Bản 3. 3. ết quả t ự n độ n xá
RMSE MAE PRECISION RECALL F1 SCORE Cosin 1.047 0.831 0.870 0.895 0.882
Pearson 0.987 0.764 0.897 0.869 0.883
3.3. Phân tích kết quả thực nghi m
Qua việc thực nghiệm ta thấy việc sử dụng cơ sở dữ liệu mô hình đồ thị để lƣu trữ và tính toán cho gợi ý có 2 ƣu điểm:
i) Tốc độ tính toán nhanh vì trong chức năng lọc cộng tác dùng nhiều thao tác duyệt quan hệ;
ii) Công cụ truy vấn của các cơ sở dữ liệu (cụ thể là Cypher của Neo4j trong thực nghiệm) đủ khả năng t nh toán cho những chức năng cơ bản của một hệ gợi ý và sử dụng những câu lệnh khá đơn giản.
KẾT LUẬN
Luận văn này tập trung vào khai thác, sử dụng cơ sở dữ liệu đồ thị Neo4j để giải quyết bài toán Hệ gợi ý trên dữ liệu lớn đặc biệt là những dữ liệu có cấu trúc dạng đồ thị.
* Các kết quả đã đạt đƣợc:
Với đề tài: ―SỬ DỤNG CƠ SỞ DỮ LIỆU ĐỒ THỊ TRONG HỆ GỢI Ý‖. Luận văn đã trình bày kiến thức tổng quan về CSDL đồ thị, cụ thể là CSDL đồ thị Neo4j và các phƣơng pháp tiếp cận cơ bản để xây dựng một hệ thống gợi ý.
Hệ thống hóa cơ sở lý thuyết về hệ gợi ý và phân tích, tổng hợp các nghiên cứu liên quan nhằm đề ra quy trình, lựa chọn các công cụ thích hợp để xây dựng hệ thống gợi ý dựa trên lọc cộng tác.
Hệ gợi ý sử dụng phƣơng pháp lọc cộng tác có ƣu điểm là không đòi hỏi biểu diễn sản phẩm dƣới dạng các đặc trƣng. Lọc cộng tác cho kết quả chính xác trong một số dạng bài toán không yêu cầu nhiều đặc trƣng (nội dung) của sản phẩm. Tuy nhiên, lọc cộng tác vẫn gặp nhiều hạn chế cần phải tiếp tục nghiên cứu nhƣ: vấn đề ngƣời dùng mới, vấn đề sản phẩm mới, vấn đề dữ liệu thƣa…
Luận văn cũng đã áp dụng các thuật toán thông dụng của hệ gợi ý bằng phƣơng pháp lọc cộng tác vào CSDL Neo4j để thực hiện bài toán gợi ý trên tập dữ liệu Movielens. Kết quả thực nghiệm cho thấy việc sử dụng CSDL Neo4j vào hệ gợi ý trên dữ liệu lớn đạt đƣợc độ tin cậy cần thiết.
* Hƣớng phát tri n, mở rộn đề tài:
Thế giới đang trong quá trình chuyển đổi số, với sự đột phá về công nghệ số (Điện toán đám mây, IoT, AI, Block chain, Big data, Data science..),
sự tăng trƣởng của dữ liệu rất nhanh trong một thời gian ngắn, khối lƣợng dữ liệu cực lớn đƣợc thu thập theo thời gian mà vấn đề xử lý và phân tích quá phức tạp với các công cụ quản trị cơ sở dữ liệu thông thƣờng.
Trong các nghiên cứu tiếp theo luận văn sẽ khai thác các thƣ viện của cơ sở dữ liệu đồ thị kết hợp với các kỹ thuật Graph Learning để giải bài toán gợi ý bằng phƣơng pháp học máy. Cùng với đó luận văn cũng tiếp tục phát triển các kỹ thuật để tăng tốc độ xử lý bằng các kỹ thuật tính toán song song trên cụm máy t nh để có thể gợi ý với cơ sở dữ liệu lớn.
DANH MỤC TÀI LIỆU THAM KHẢO
[1] Renzo Angles, "The Property Graph Database Model," http://ceur-
ws.org/, Vols. Vol-2100, no. May 21-25, p. paper26, 2018.
[2] Aleksa Vukotic, Nicki Watt, Tareq Abedrabbo and Dominic Fox, "Neo4j in Action," Manning Publications, December 2014.
[3] "Neo4j Documentation," Neo4j, Inc., [Online]. Available: https://neo4j.com/docs. [Accessed 28 01 2021].
[4] "The Neo4j Cypher Manual v4.2," [Online]. Available:
https://neo4j.com/docs/cypher-manual/current/. [Accessed 16 06 2021]. [5] Charu C. Aggarwal, "Recommender Systems," Springer, 2016.
[6] Trần Thiên Thành, "Sử dụng cơ sở dữ liệu mô hình đồ thị trong hệ gợi ý," Kỷ yếu Hội thảo CITA 2021, Trường Đại học Công nghệ thông tin
truyền thông Việt – Hàn, Đà Nẵng, 2021. .
[8] Vũ Sơn Lâm, L Quang Hùng, Nguyễn Văn Vinh, "Đánh giá hệ gợi ý: Khảo sát và thực nghiệm", Hội thảo quốc gia lần thứ XXIII: Một số
vấn đề chọn lọc của Công nghệ thông tin và truyền thông – Quảng Ninh , 5-6/11/2020. .
[9] "Tutorialspoint," [Online]. Available:
https://www.tutorialspoint.com/neo4j/neo4j_overview.htm. [Accessed 28 01 2021].
[10] Noor Mohammedali, "Recommendation System Based on Graph Database Techniques," International Research Journal of Engineering
and Technology, vol. 06, 2019.
[12] Mark Needham and Amy E. Hodler, "Graph Algorithms: Practical Examples in Apache Spark and Neo4j," O'Reilly Media, 2020.
[13] Michael D. Ekstrand, John T. Riedl and Joseph A. Konstan, "Collaborative Filtering Recommender Systems," Foundations and Trends® in Human–Computer Interaction, vol. 4, pp. 81-173, 2011.
[14] Greg Linden, Brent Smith and Jeremy York, "Item-to-Item Collaborative Filtering," IEEE Internet Computing, vol. 7, pp. 76-80, 2003.