Xây dựng Hệ thống gợi ý bài viết (Recommendation System) với Python

AI Hunter

Member
Bạn đã bao giờ thắc mắc tại sao TikTok, Netflix hay YouTube lại "hiểu" bạn đến vậy? Bí mật nằm ở Recommendation System. Đối với các diễn đàn (như XenForo) hay Blog, việc gợi ý đúng nội dung người dùng quan tâm là chìa khóa để giữ chân họ lâu hơn.

Xây dựng Hệ thống gợi ý bài viết (Recommendation System) với Python.jpg

Trong bài viết này, chúng ta sẽ xây dựng một hệ thống gợi ý đơn giản nhưng hiệu quả theo phương pháp Content-based Filtering (Lọc dựa trên nội dung) bằng Python.

1. Nguyên lý hoạt động​


Chúng ta sẽ không cần AI quá phức tạp, mà sử dụng 2 kỹ thuật toán học kinh điển trong Xử lý ngôn ngữ tự nhiên (NLP):

  • TF-IDF (Term Frequency - Inverse Document Frequency): Kỹ thuật này giúp chuyển đổi văn bản (tiêu đề bài viết) thành các con số (vector). Nó thông minh ở chỗ: Nó biết đánh trọng số cao cho các từ khóa quan trọng (như "Python", "XenForo") và hạ thấp trọng số các từ phổ thông ít ý nghĩa (như "là", "của", "những").
  • Cosine Similarity: Dùng để đo "khoảng cách" giữa 2 bài viết. Nếu 2 bài viết có nhiều từ khóa giống nhau, góc giữa chúng sẽ nhỏ và độ tương đồng (Similarity) sẽ tiệm cận 1.

2. Cài đặt thư viện​


Chúng ta sử dụng scikit-learn - thư viện Machine Learning phổ biến nhất của Python.

Python:
pip install pandas scikit-learn

3. Triển khai Code (Full Source)​


Dưới đây là đoạn code hoàn chỉnh. Mình sẽ tạo một bộ dữ liệu giả lập gồm nhiều chủ đề khác nhau (Lập trình, Bóng đá, Nấu ăn) để bạn thấy thuật toán phân loại tốt thế nào.

Python:
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel

# 1. Tạo dữ liệu giả lập (Database bài viết)
data = {
    'id': [1, 2, 3, 4, 5, 6, 7, 8],
    'title': [
        "Hướng dẫn lập trình Python cơ bản cho người mới",      # ID 1: IT
        "Đội tuyển Việt Nam chuẩn bị cho vòng loại World Cup",  # ID 2: Thể thao
        "Cách làm món phở bò gia truyền ngon tại nhà",          # ID 3: Ẩm thực
        "Lộ trình học Python để trở thành Data Scientist",      # ID 4: IT (Liên quan ID 1)
        "Kết quả bóng đá Ngoại hạng Anh hôm nay",               # ID 5: Thể thao (Liên quan ID 2)
        "Bí quyết nấu phở gà Hà Nội chuẩn vị",                  # ID 6: Ẩm thực (Liên quan ID 3)
        "Review các thư viện Python phổ biến nhất",             # ID 7: IT (Liên quan ID 1, 4)
        "Top 10 bàn thắng đẹp nhất lịch sử World Cup"           # ID 8: Thể thao (Liên quan ID 2, 5)
    ]
}

# Chuyển thành DataFrame (Bảng dữ liệu)
df = pd.DataFrame(data)

print("--- DANH SÁCH BÀI VIẾT ---")
print(df[['id', 'title']])
print("\n⏳ Đang tính toán độ tương đồng...")

# 2. Vector hóa văn bản (TF-IDF)
# analyzer='word': Tách theo từ
# ngram_range=(1, 2): Lấy cả cụm từ (VD: "Python cơ bản")
tfidf = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0)

# Chuyển cột 'title' thành Ma trận TF-IDF
tfidf_matrix = tfidf.fit_transform(df['title'])

# 3. Tính độ tương đồng (Cosine Similarity)
# Kết quả là một ma trận vuông (8x8) thể hiện điểm số giữa từng cặp bài viết
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)

# 4. Hàm gợi ý bài viết
def get_recommendations(title, cosine_sim=cosine_sim):
    # Tìm index của bài viết dựa trên tiêu đề
    try:
        idx = df.index[df['title'] == title].tolist()[0]
    except IndexError:
        return ["Không tìm thấy bài viết này!"]

    # Lấy danh sách điểm tương đồng của bài viết đó với các bài khác
    sim_scores = list(enumerate(cosine_sim[idx]))

    # Sắp xếp giảm dần theo điểm số (Bài giống nhất lên đầu)
    sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)

    # Lấy 3 bài viết tương đồng nhất (bỏ qua bài đầu tiên vì là chính nó)
    sim_scores = sim_scores[1:4]

    # Lấy ra index của các bài viết gợi ý
    movie_indices = [i[0] for i in sim_scores]

    # Trả về tiêu đề
    return df['title'].iloc[movie_indices]

# --- CHẠY THỬ NGHIỆM ---

print("\n" + "="*40)
print("DEMO GỢI Ý BÀI VIẾT")
print("="*40)

# Test 1: Đọc bài về Python -> Gợi ý bài Python khác
current_post = "Hướng dẫn lập trình Python cơ bản cho người mới"
print(f"📖 Đang đọc: {current_post}")
print("👉 Gợi ý liên quan:")
recommendations = get_recommendations(current_post)
for rec in recommendations:
    print(f"   - {rec}")

print("-" * 20)

# Test 2: Đọc bài về Bóng đá -> Gợi ý bài Thể thao
current_post = "Đội tuyển Việt Nam chuẩn bị cho vòng loại World Cup"
print(f"📖 Đang đọc: {current_post}")
print("👉 Gợi ý liên quan:")
recommendations = get_recommendations(current_post)
for rec in recommendations:
    print(f"   - {rec}")

4. Phân tích kết quả​


Khi chạy đoạn code trên, bạn sẽ thấy sự "thông minh" của thuật toán:
  • Khi đọc bài về Python, hệ thống sẽ gợi ý bài "Lộ trình học Python" và "Thư viện Python". Nó không gợi ý nhầm sang bài "Nấu phở" hay "Bóng đá".
  • Thuật toán TF-IDF tự động nhận diện từ khóa "Python" là quan trọng nhất để kết nối các bài viết này.

5. Ứng dụng vào Website thực tế​


Để tích hợp vào website (XenForo/WordPress/Laravel) mà không làm chậm web, bạn nên làm theo kiến trúc sau:
  1. Xử lý ngầm (Background Job): Viết script Python chạy định kỳ (ví dụ 6 tiếng/lần) để tính toán lại toàn bộ mối quan hệ giữa các bài viết.
  2. Lưu Database: Lưu kết quả vào một bảng riêng, ví dụ related_threads (thread_id, related_id, score).
  3. Hiển thị: Khi người dùng truy cập web, code PHP chỉ cần SELECT * FROM related_threads WHERE thread_id = X. Truy vấn này cực nhanh (chưa tới 0.001s).

Chúc các bạn áp dụng thành công để tăng Time-On-Site cho website của mình!
 
Back
Top