Kiến trúc hệ thống
Hệ thống sử dụng Flask làm nền tảng backend nhẹ, tích hợp SQLAlchemy để truy vấn cơ sở dữ liệu và Jinja2 cho việc render giao diện. Mô hình đề xuất được xây dựng dựa trên thuật toán lọc cộng tác (collaborative filtering) hoặc mô hình dựa trên nội dung (content-based), khai thác dữ liệu hành vi người dùng như lịch sử xem và đặt phòng.
Thiết kế cơ sở dữ liệu
- Các bảng chính:
users:user_id,preferencesrooms:room_id,room_type,price,amenitiesbookings:booking_id,user_id,room_id,created_at
- Mối quan hệ: Một người dùng có nhiều đơn đặt phòng (1:N). Phòng và đặc điểm (tags) có quan hệ nhiều-nhiều thông qua bảng trung gian.
Triển khai thuật toán đề xuất
Lọc cộng tác
Tính độ tương đồng giữa người dùng dựa trên đánh giá/rating từ lịch sử đặt phòng. Sử dụng hệ số tương quan Pearson:
Ví dụ mã Python:
from scipy.spatial.distance import cosine
def pearson_similarity(ratings_u, ratings_v):
if len(ratings_u) == 0 or len(ratings_v) == 0:
return 0.0
# Chuẩn hóa theo trung bình
mean_u, mean_v = sum(ratings_u)/len(ratings_u), sum(ratings_v)/len(ratings_v)
norm_u = [r - mean_u for r in ratings_u]
norm_v = [r - mean_v for r in ratings_v]
# Tính cosine trên vector đã chuẩn hóa
return 1 - cosine(norm_u, norm_v)
Đề xuất dựa trên nội dung
Biểu diễn đặc điểm phòng (giá, loại phòng, tiện nghi) dưới dạng vector TF-IDF. So sánh với hồ sơ người dùng bằng độ tương đồng cosine để tìm phòng phù hợp.
Giao diện API
GET /api/recommend?user_id=123: Trả về danh sách phòng được đề xuất dưới dạng JSON.POST /api/search: Nhận tham số như vị trí, khoảng giá để lọc kết quả.
Giao diện người dùng
Giao diện được render động bằng Jinja2. Kết quả đề xuất được tải không đồng bộ qua Ajax:
fetch('/api/recommend?user_id=' + userId)
.then(res => res.json())
.then(rooms => {
const container = document.getElementById('recommendations');
rooms.forEach(room => {
container.innerHTML += `<div>${room.name} - ${room.price}</div>`;
});
});
Tối ưu hiệu năng
- Cache: Dùng Redis lưu kết quả đề xuất phổ biến, giảm tải tính toán thời gian thực.
- Phân trang: Sử dụng phương thức
paginate()của SQLAlchemy để giới hạn số lượng kết quả mỗi trang.
Triển khai và mở rộng
- Đóng gói ứng dụng vào Docker, dùng Nginx làm reverse proxy phục vụ tài nguyên tĩnh.
- Thiết kế module hóa để dễ dàng tích hợp mô hình học sâu (ví dụ: Wide & Deep) trong tương lai.
Kiểm thử
- Viết unit test bằng PyTest để kiểm chứng logic đề xuất.
- Thực hiện A/B testing để so sánh hiệu quả giữa các chiến lược đề xuất dựa trên tỷ lệ chuyển đổi.
Bảo mật
- Dữ liệu nhạy cảm (như thông tin thanh toán) được mã hóa trước khi lưu vào CSDL.
- Sử dụng truy vấn tham số hóa của SQLAlchemy để ngăn SQL injection.
Lưu ý: Các thành phần như trường dữ liệu, thuật toán cụ thể cần được điều chỉnh theo yêu cầu thực tế của dự án.