Giới thiệu dự án
Thị trường bất động sản (BĐS) tại các đô thị lớn như Hà Nội và TP. Hồ Chí Minh luôn biến động phức tạp dưới tác động đa chiều từ vị trí địa lý, diện tích, quy hoạch hạ tầng và tính pháp lý. Theo các báo cáo thị trường BĐS Việt Nam, hơn 65% giao dịch BĐS thứ cấp gặp tình trạng bất cân xứng thông tin, dẫn đến hiện tượng "thổi giá" hoặc định giá sai lệch so với giá trị thực tế từ 15% đến 30%.
Đề tài "Phân tích dữ liệu và dự báo trong lĩnh vực kinh doanh bất động sản" (Thực hiện bởi sinh viên Phan Hoàng Minh Quân, GVHD: ThS. Trần Anh Dũng - Trường Đại học Công nghệ Thông tin, ĐHQG-HCM) tập trung giải quyết bài toán định giá tự động thông qua các kỹ thuật học máy (Machine Learning).
Vấn đề nghiên cứu cụ thể
- Bất đối xứng thông tin: Người mua và nhà đầu tư cá nhân thiếu công cụ định giá chuẩn xác theo thời gian thực.
- Mối quan hệ phi tuyến tính: Giá nhà chịu ảnh hưởng đồng thời bởi các yếu tố định lượng (diện tích, kích thước mặt tiền, chiều dài, số tầng, số phòng ngủ) và định tính (loại hình BĐS, tình trạng pháp lý).
- Nhiễu dữ liệu: Các tin đăng BĐS thực tế chứa nhiều điểm ngoại lai (outliers) và dữ liệu thiếu (missing values), gây sai số nghiêm trọng nếu áp dụng các mô hình hồi quy tuyến tính cổ điển.
Mục tiêu của dự án
- Xây dựng pipeline thu thập, làm sạch và chuẩn hóa dữ liệu tin đăng BĐS khu vực Hà Nội.
- Ứng dụng kỹ thuật thống kê (IQR) để phát hiện và loại bỏ triệt để các giá trị ngoại lai gây nhiễu.
- Phân tích tương quan và trực quan hóa các yếu tố tác động phi tuyến tính đến đơn giá ($VNĐ/m^2$).
- Huấn luyện mô hình Random Forest Regressor với phương pháp tối ưu siêu tham số kết hợp (Randomized Search + Grid Search).
- Đóng gói mô hình và phát triển RESTful API phục vụ dự đoán giá BĐS từ dữ liệu đầu vào thực tế.
Giải pháp và phạm vi
- Phương pháp tiếp cận: Sử dụng học máy có giám sát (Supervised Learning) với mô hình tổ hợp cây quyết định (Random Forest Regressor) nhằm xử lý tốt đặc trưng phi tuyến và hạn chế hiện tượng quá khớp (overfitting).
- Chỉ số kỳ vọng: Đạt hệ số xác định $R^2 \ge 0.82$, sai số tuyệt đối trung bình (MAE) kiểm soát dưới mức 12% biên độ dao động thị trường, độ trễ phản hồi API $< 50ms$.
- Phạm vi nghiên cứu: Tập dữ liệu gồm 84.495 bản ghi BĐS tại thị trường Hà Nội trong giai đoạn 2019–2020, tập trung vào phân khúc nhà ở riêng lẻ, nhà mặt phố, biệt thự và nhà liền kề.
Phân tích và thiết kế giải pháp
Phân tích hiện trạng
| Tiêu chí |
Phương pháp định giá truyền thống |
Mô hình hồi quy tuyến tính (OLS) |
Giải pháp Random Forest tối ưu |
| Cơ chế xử lý |
Dựa trên kinh nghiệm chuyên gia thẩm định |
Thiết lập hàm tuyến tính đơn biến/đa biến |
Phân rã đa chiều phi tuyến tính qua rừng cây quyết định |
| Xử lý Outlier |
Cảm tính, dễ bỏ sót hoặc loại sai |
Kém, bị ảnh hưởng lớn bởi điểm biên |
Tự động hóa qua thuật toán IQR ($1.5 \times IQR$) |
| Khả năng mở rộng |
Thấp, tốn chi phí nhân sự |
Cao nhưng sai số lớn ($R^2 < 0.60$) |
Rất cao, tích hợp chuẩn hóa qua REST API |
| Độ chính xác |
Phụ thuộc vào dữ liệu cục bộ |
Kém khi dữ liệu có tương quan phức tạp |
Cao ($R^2 > 0.82$), chống overfitting hiệu quả |
Yêu cầu hệ thống theo mô hình MoSCoW
- Must have: Pipeline tiền xử lý (One-Hot Encoding, IQR cleaning), mô hình Random Forest Regressor đã được tối ưu hóa siêu tham số, endpoint API trả về kết quả dự báo.
- Should have: Module trực quan hóa phân phối dữ liệu (Histogram, Scatter Plot tương quan diện tích - đơn giá).
- Could have: Giao diện Web tương tác trực quan cho người dùng cuối.
- Won't have (lần này): Tích hợp dữ liệu chuỗi thời gian (time-series) theo biến động vĩ mô từng tháng.
Thiết kế hệ thống
+---------------------------------------------------------------------------------+
| SYSTEM ARCHITECTURE |
+---------------------------------------------------------------------------------+
| [Data Layer] |
| Kaggle Dataset (Hanoi Housing: 84,495 rows) -> Pandas/NumPy Pipeline |
| String to Float -> Missing Value Drop -> One-Hot Encoding -> IQR Filter (~7.5k)|
| Train/Test Split (80:20) -> RandomizedSearchCV -> GridSearchCV -> RF Model |
| Joblib Serialization -> FastAPI Endpoint (/predict) -> JSON Response |
+---------------------------------------------------------------------------------+
Technology Stack và phiên bản cụ thể
- Ngôn ngữ: Python
3.10.12
- Xử lý dữ liệu: Pandas
2.1.4, NumPy 1.26.2
- Học máy & Tối ưu hóa: Scikit-Learn
1.3.2
- Trực quan hóa: Matplotlib
3.8.2, Seaborn 0.13.0
- Môi trường thực thi & Lưu trữ: Google Colab Pro (13GB RAM, GPU T4/TPU support), Jupyter Notebook
7.0.6
- Triển khai API: FastAPI
0.104.1, Uvicorn 0.24.0
Thiết kế lược đồ dữ liệu (Data Schema)
{
"dientich": "float (m2)",
"dai": "float (m)",
"rong": "float (m)",
"so_tang": "int",
"so_phongngu": "int",
"loai_hinh_nha_o": "Categorical [Nha_biet_thu, Nha_mat_pho, Nha_ngo, Nha_pho_lien_ke]",
"giay_to_phap_ly": "Categorical [Da_co_so, Dang_cho_so, Giay_to_khac]",
"target_gia_m2": "float (Trieu_VND/m2)"
}
Phương pháp luận (Methodology)
Dự án áp dụng quy trình phát triển lặp CRISP-DM (Cross-Industry Standard Process for Data Mining) trải qua 3 giai đoạn chính:
- Giai đoạn 1 (01/10/2024 - 18/10/2024): Thu thập dữ liệu từ Kaggle, làm sạch, chuyển đổi định dạng, loại bỏ outlier và thực hiện phân tích khám phá dữ liệu (EDA).
- Giai đoạn 2 (18/10/2024 - 15/11/2024): Phân chia tập dữ liệu (80:20), thiết lập cấu hình Random Forest, chạy tối ưu 2 tầng (Randomized + Grid Search), đánh giá các chỉ số kiểm thử.
- Giai đoạn 3 (15/11/2024 - 29/11/2024): Đóng gói mô hình
.joblib, viết REST API mô phỏng tích hợp thực tế, hoàn thiện tài liệu kỹ thuật và mã nguồn GitHub.
Implementation và kết quả
Development Process
1. Xử lý và làm sạch dữ liệu
Dữ liệu gốc chứa nhiều giá trị văn bản biểu diễn số lượng (ví dụ: "5 phòng", "đã có sổ"). Quá trình xử lý bao gồm việc chuẩn hóa chuỗi về kiểu số thực và áp dụng kỹ thuật One-Hot Encoding cho các biến phân loại không có thứ bậc (Nominal features).
import pandas as pd
import numpy as np
def preprocess_housing_data(df: pd.DataFrame) -> pd.DataFrame:
# 1. Chuyen doi cac cot sang kieu du lieu so thuc
numeric_cols = ['Gia_m2', 'Dai', 'Rong', 'Dien_tich', 'So_tang', 'So_phong_ngu']
for col in numeric_cols:
df[col] = pd.to_numeric(df[col], errors='coerce')
# 2. Loai bo du lieu thieu (Missing Values)
df = df.dropna(subset=numeric_cols)
# 3. One-Hot Encoding cho bien phan loai
categorical_cols = ['Loai_hinh_nha_o', 'Giay_to_phap_ly']
df = pd.get_dummies(df, columns=categorical_cols, drop_first=False)
return df
2. Kỹ thuật loại bỏ Outlier bằng phương pháp IQR (Interquartile Range)
Các giá trị ngoại lai của đơn giá và diện tích được loại bỏ dựa trên khoảng cách giữa phân vị 25% ($Q_1$) và phân vị 75% ($Q_3$):
$$\text{IQR} = Q_3 - Q_1$$
$$\text{Ngưỡng dưới} = Q_1 - 1.5 \times \text{IQR}, \quad \text{Ngưỡng trên} = Q_3 + 1.5 \times \text{IQR}$$
def remove_outliers_iqr(df: pd.DataFrame, column: str) -> pd.DataFrame:
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]
# Ap dung loc ngoai lai tren tap du lieu
df_cleaned = remove_outliers_iqr(df_processed, 'Gia_m2')
df_cleaned = remove_outliers_iqr(df_cleaned, 'Dien_tich')
# Du lieu sau lam sach con ~7,500 ban ghi chat luong cao
3. Quy trình tối ưu siêu tham số phối hợp (Two-Stage Tuning)
Thay vì thực hiện Grid Search toàn bộ không gian tham số (gây bùng nổ tổ hợp tính toán), hệ thống triển khai chiến lược hai bước:
- Bước 1: Dùng
RandomizedSearchCV để thăm dò diện rộng nhằm xác định vùng hội tụ tối ưu.
- Bước 2: Dùng
GridSearchCV để quét cục bộ chi tiết xung quanh vùng giá trị tiềm năng.
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import RandomizedSearchCV, GridSearchCV
# Buoc 1: Randomized Search tren khong gian rong
param_dist = {
'n_estimators': [50, 100, 200, 300],
'max_depth': [10, 20, 30, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'max_features': ['sqrt', 'log2', None]
}
rf = RandomForestRegressor(random_state=42, n_jobs=-1)
random_search = RandomizedSearchCV(rf, param_distributions=param_dist, n_iter=20, cv=5, random_state=42)
random_search.fit(X_train, y_train)
# Buoc 2: Grid Search tinh chinh cuc bo dua tren ket qua buoc 1
best_p = random_search.best_params_
param_grid = {
'n_estimators': [best_p['n_estimators'] - 20, best_p['n_estimators'], best_p['n_estimators'] + 20],
'max_depth': [best_p['max_depth'] - 5, best_p['max_depth'], best_p['max_depth'] + 5] if best_p['max_depth'] else [25, 30, 35],
'min_samples_split': [best_p['min_samples_split']],
'min_samples_leaf': [best_p['min_samples_leaf']]
}
grid_search = GridSearchCV(rf, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)
best_model = grid_search.best_estimator_
4. Đóng gói mô hình và xây dựng RESTful API
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np
# Load model da train
model = joblib.load("random_forest_housing_model.joblib")
app = FastAPI(title="Real Estate Price Prediction API", version="1.0")
class HousingInput(BaseModel):
dien_tich: float
dai: float
rong: float
so_tang: int
so_phong_ngu: int
loai_nha_mat_pho: int
loai_nha_ngo: int
loai_biet_thu: int
loai_lien_ke: int
so_do_da_co: int
so_do_cho: int
giay_to_khac: int
@app.post("/predict")
def predict_price(data: HousingInput):
features = np.array([[
data.dien_tich, data.dai, data.rong, data.so_tang, data.so_phong_ngu,
data.loai_nha_mat_pho, data.loai_nha_ngo, data.loai_biet_thu, data.loai_lien_ke,
data.so_do_da_co, data.so_do_cho, data.giay_to_khac
]])
predicted_price_m2 = model.predict(features)[0]
total_estimated_price = predicted_price_m2 * data.dien_tich
return {
"status": "success",
"predicted_price_per_m2_million_vnd": round(float(predicted_price_m2), 2),
"total_estimated_price_million_vnd": round(float(total_estimated_price), 2)
}
Testing và validation
Phân tích độ chính xác trên tập kiểm thử (Test Set: 20%)
Mô hình được đánh giá thông qua các chỉ số đo lường chuẩn:
- Hệ số xác định ($R^2$ Score): $0.842$ (Mô hình giải thích được 84.2% phương sai của giá BĐS).
- Sai số tuyệt đối trung bình (MAE): $8.45$ triệu $\text{VNĐ}/m^2$.
- Sai số căn phương trung bình (RMSE): $11.23$ triệu $\text{VNĐ}/m^2$.
+----------------------------------------------------------------------+
| ACTUAL VS PREDICTED SCATTER |
| |
| Predicted (Tr/m2) |
| ^ |
| 200 | * (Ideal Line) |
| 160 | * . / |
| 120 | . * . |
| 80 | . * . |
| 40 | . * . |
| 0 +----------------------------------------------------> |
| 0 40 80 120 160 200 |
| Actual Price (Tr/m2) |
+----------------------------------------------------------------------+
Kết quả đạt được
- Phân loại thành công nhóm giá trị phổ biến: Giá nhà tập trung dày đặc nhất ở mức $100 - 120$ triệu $\text{VNĐ}/m^2$; diện tích phổ biến nhất dao động trong khoảng $30 - 50 m^2$.
- Xử lý triệt để hiện tượng phi tuyến tính giữa diện tích và giá trị đơn giá thông qua cấu trúc cây quyết định phân tầng.
- Giảm thiểu $48%$ thời gian tìm kiếm siêu tham số nhờ mô hình phối hợp RandomizedSearch + GridSearchCV so với GridSearch thuần túy.
Đổi mới và đóng góp
Điểm cải tiến kỹ thuật nổi bật
- Phương pháp tối ưu hai tầng linh hoạt: Tích hợp thành công
RandomizedSearchCV làm phễu lọc thô và GridSearchCV làm phễu tinh chỉnh, giải quyết bài toán nghẽn cổ chai tài nguyên CPU trên Google Colab.
- Pipeline tiền xử lý tự động: Chuẩn hóa quy trình làm sạch từ chuỗi sang số thực kết hợp mã hóa One-Hot và lọc biên IQR khép kín, ngăn ngừa hiện tượng rò rỉ dữ liệu (Data Leakage) khi chia tập train/test.
Bảng so sánh với các giải pháp hiện hành
| Đặc tính |
Mô hình hồi quy OLS truyền thống |
Baseline Random Forest mặc định |
Pipeline Random Forest Đề tài |
| Tiền xử lý Outlier |
Thủ công qua Z-Score |
Không xử lý |
Tự động hóa qua thuật toán IQR |
| Mã hóa phân loại |
Label Encoding (Dễ sai lệch thứ bậc) |
One-Hot thủ công |
Automated One-Hot Pipeline |
| Kỹ thuật Tuning |
Không có |
Mặc định ($n=100$) |
Two-Stage (Randomized + Grid Search) |
| Hệ số $R^2$ |
$0.58$ |
$0.74$ |
$0.842$ (Tăng $13.7%$ so với baseline) |
| Khả năng đóng gói |
Khó tích hợp |
Code script đơn lẻ |
Đóng gói .joblib & FastAPI Endpoint |
Ứng dụng thực tế và triển khai
Tình huống ứng dụng thực tế
- Hỗ trợ quyết định cho nhà đầu tư cá nhân: Nhập các thông số hình học và pháp lý của mảnh đất cần mua để đối soát xem mức giá chủ sở hữu đưa ra có vượt quá biên độ tin cậy của thị trường hay không.
- Công cụ định giá tự động (AVM) cho sàn giao dịch: Tích hợp API vào hệ thống quản lý bất động sản (Real Estate CRM) để tự động gợi ý khoảng giá niêm yết tối ưu cho môi giới khi đăng tin mới.
Chiến lược triển khai và Yêu cầu hạ tầng
- Môi trường Server tối thiểu: Docker Container chạy Linux (Ubuntu 22.04 LTS), 2 vCPU, 4GB RAM.
- Scalability: Do mô hình Random Forest sau khi huấn luyện có kích thước gọn nhẹ (~50MB), có thể scale ngang (Horizontal Scaling) dễ dàng thông qua Kubernetes hoặc AWS ECS đằng sau một Nginx Load Balancer.
- Chi phí - Lợi ích (ROI): Tiết kiệm đến 80% thời gian khảo sát thực địa sơ bộ; giảm thiểu chi phí thuê chuyên gia thẩm định giá đối với các giao dịch phân khúc phổ thông.
Hạn chế và hướng phát triển
Hạn chế kỹ thuật
- Tính chất dữ liệu theo không gian: Chưa tích hợp tọa độ địa lý chính xác (Latitude/Longitude) và khoảng cách thực tế đến các tiện ích trọng điểm (trường học, bệnh viện, ga Metro).
- Yếu tố biến động thời gian: Mô hình chưa xét đến các chỉ số lạm phát, biến động lãi suất ngân hàng và chu kỳ tăng trưởng của nền kinh tế vĩ mô.
Hướng phát triển đề xuất
- Bổ sung Feature Engineering: Tích hợp Geocoding API để trích xuất khoảng cách từ BĐS đến trung tâm quận Hoàn Kiếm hoặc trục đường vành đai.
- Thử nghiệm mô hình Boosting: Nâng cấp và so sánh hiệu năng với các thuật toán Gradient Boosting tiên tiến như XGBoost, LightGBM hoặc CatBoost.
- Xây dựng Giao diện Web hoàn chỉnh: Phát triển ứng dụng Web Front-end trên nền tảng ReactJS/NextJS kết nối trực tiếp với backend FastAPI.
Đối tượng hưởng lợi
+-------------------------------------------------------------------------------+
| BENEFICIARY GROUPS |
+-------------------------------------------------------------------------------+
+-------------------------------------------------------------------------------+
- Sinh viên CNTT / Khoa học dữ liệu: Tài liệu tham khảo hoàn chỉnh về quy trình thực thi đồ án ứng dụng học máy từ khâu tiền xử lý dữ liệu thực tế đến đóng gói sản phẩm.
- Kỹ sư phần mềm & Data Scientist: Cung cấp pattern mẫu về việc kết hợp tối ưu tham số hai tầng và kiến trúc phân tách giữa huấn luyện (Colab) và phục vụ mô hình (Inference API).
- Doanh nghiệp & Nhà đầu tư BĐS: Sở hữu công cụ tham chiếu giá khách quan, giảm thiểu rủi ro mua vượt giá thị trường.
- Nhà nghiên cứu học thuật: Cung cấp baseline đối chuẩn khi thử nghiệm các mô hình học sâu (Deep Learning) hoặc mô hình không gian địa lý (Spatial Econometrics) trong định giá BĐS.
Câu hỏi thường gặp
1. Cần cấu hình phần cứng như thế nào để triển khai mô hình vào thực tế?
Mô hình sau khi huấn luyện đã được tinh giản tham số và đóng gói dưới định dạng nhị phân .joblib. Khi triển khai suy luận (Inference), hệ thống chỉ yêu cầu máy chủ cấu hình tiêu chuẩn gồm 1 vCPU và 2GB RAM là có thể xử lý đồng thời hơn 100 requests/giây với độ trễ phản hồi dưới 50ms.
2. Tại sao chọn Random Forest thay vì Hồi quy tuyến tính hoặc Mạng nơ-ron sâu (Deep Learning)?
Hồi quy tuyến tính giả định mối quan hệ thẳng giữa các biến, điều này không đúng với tương quan phi tuyến giữa diện tích và giá nhà (được chứng minh qua biểu đồ EDA). Trong khi đó, Deep Learning đòi hỏi tập dữ liệu khổng lồ (hàng triệu dòng) và khó giải thích. Random Forest mang lại sự cân bằng lý tưởng: xử lý phi tuyến xuất sắc, kiểm soát overfitting tốt và không yêu cầu tài nguyên phần cứng quá cao.
3. Phương pháp IQR loại bỏ bao nhiêu phần trăm dữ liệu và có làm mất thông tin quan trọng?
Từ 84.495 bản ghi thô ban đầu (chứa nhiều tin rác, trùng lặp và dữ liệu thiếu), sau các bước làm sạch cơ bản và lọc IQR cho hai biến Gia_m2 và Dien_tich, tập dữ liệu còn lại khoảng ~7.500 bản ghi chuẩn hóa cao. Việc loại bỏ các giá trị quá dị biệt (ví dụ nhà có đơn giá 1 tỷ/m2 hoặc diện tích 2m2) giúp mô hình tập trung học đúng phân khúc nhà ở phổ dụng của đại đa số người dùng.
4. Hệ thống xử lý dữ liệu danh mục (Categorical Data) như thế nào để tránh sai lệch thứ bậc?
Đề tài sử dụng kỹ thuật One-Hot Encoding thông qua hàm pd.get_dummies() để chuyển đổi các cột Loai_hinh_nha_o và Giay_to_phap_ly thành các vector nhị phân (0/1). Cách tiếp cận này ngăn ngừa mô hình gán thứ bậc giả định không mong muốn (như khi dùng Label Encoding gán Biệt thự = 0, Nhà ngõ = 2).
5. Chi phí vận hành giải pháp này ước tính bao nhiêu?
Nếu triển khai trên các nền tảng đám mây như AWS Lightsail, DigitalOcean hoặc Render, chi phí duy trì chỉ dao động từ $5 - $10 USD/tháng cho server API cơ bản. Đây là mức đầu tư tối ưu với tỷ suất sinh lời (ROI) vượt trội so với việc duy trì đội ngũ thẩm định thủ công.
Kết luận
Đồ án "Phân tích dữ liệu và dự báo trong lĩnh vực kinh doanh bất động sản" đã hiện thực hóa thành công một giải pháp định giá tự động hoàn chỉnh, đáp ứng đầy đủ các tiêu chuẩn kỹ thuật từ nghiên cứu dữ liệu đến triển khai ứng dụng. Thông qua việc làm sạch dữ liệu bằng phương pháp thống kê IQR, mã hóa One-Hot và tối ưu hóa mô hình Random Forest bằng chiến lược kết hợp RandomizedSearch - GridSearchCV, dự án đạt được độ chính xác cao ($R^2 = 0.842$) và kiểm soát tốt hiện tượng quá khớp.
Hệ thống mở ra tiềm năng ứng dụng rộng lớn cho các sàn giao dịch BĐS và nhà đầu tư cá nhân, giúp minh bạch hóa thị trường và hỗ trợ ra quyết định nhanh chóng. Các nhà phát triển và nghiên cứu có thể tiếp tục kế thừa mã nguồn, tích hợp thêm các đặc trưng địa không gian và nâng cấp thuật toán sang các mô hình Gradient Boosting để mở rộng phạm vi định giá cho toàn bộ các tỉnh thành trên cả nước.