predict_caLamviec_nhansu/README.md

19 KiB
Raw Blame History

🏢 Dự Đoán Nhân Sự Ca Làm Việc

Hệ thống Machine Learning dự đoán số lượng nhân sự cần thiết cho mỗi ca làm việc dựa trên đặc điểm tòa nhà và công việc


📋 Mục Lục


🎯 Tổng Quan

Dự án này sử dụng Machine Learning để tự động dự đoán số lượng nhân sự cần thiết cho mỗi ca làm việc tại các tòa nhà, dựa trên:

  • Đặc điểm vật lý của tòa nhà (diện tích, số tầng, số WC, v.v.)
  • Loại công việc và nội dung công việc (text features)
  • Thông tin ca làm việc (ca sáng, chiều, tối, đêm)

📊 Cấu Trúc Dữ Liệu

🗂️ Dữ Liệu Gốc (data_raw/)

📌 Mục đích: Chứa thông tin về các ca làm việc

Nội dung:

  • Danh sách các ca làm việc của từng tòa nhà
  • Thời gian làm việc (ca sáng, chiều, tối, đêm)
  • Công việc thường (all_task_normal)
  • Công việc định kỳ (all_task_dinhky)
  • Số nhân sự thực tế cho mỗi ca

Vai trò: Cung cấp dữ liệu về phân canội dung công việc cho model


📌 Mục đích: Chứa thông tin về đặc điểm vật lý của các tòa nhà

Nội dung:

  • Diện tích từng tầng của mỗi tòa nhà
  • Số lượng WC, phòng, v.v.
  • Thông tin cơ sở hạ tầng

⚠️ LƯU Ý QUAN TRỌNG:

Các trường liên quan đến diện tích trong final_2.csv là TỔNG diện tích của TẤT CẢ các tầng trong mỗi tòa nhà, không phải diện tích trung bình hay diện tích một tầng!

Ví dụ: Nếu tòa nhà có 10 tầng, mỗi tầng 500m², thì tong_dien_tich = 5000m²


📈 Dữ Liệu Training

final_2.csv (hoặc final_2.xlsx)

📌 Mục đích: Dataset chính để huấn luyện model

Nguồn dữ liệu:

  • Thông tin ca làm việc ← từ data_raw/Link LLV 1_5_2025.json
  • Thông tin diện tích tòa nhà ← từ data_raw/Link LLV 2025_clean.json (TỔNG diện tích các tầng)

Các nhóm features chính:

Nhóm Features Nguồn Ví dụ
Thông tin ca Link LLV ca_sang, ca_chieu, ca_toi, ca_dem
Diện tích Link LLV 2025 tong_dien_tich, dien_tich_wc, dien_tich_hanh_lang
Cơ sở vật chất Link LLV 2025 so_tang, so_wc, so_phong
Text features Sinh ra từ tasks num_cleaning_tasks, cleaning_ratio, area_diversity
Target Link LLV so_nhan_su (số nhân sự thực tế)

📁 Các File Chính

1. 📓 All_feature_Readme.ipynb

Notebook giải thích chi tiết về Text Features

Nội dung:

  • 📖 Giải thích từng loại text feature được trích xuất từ công việc
  • 🔍 Các keyword được sử dụng để nhận diện công việc
  • 📊 Ví dụ minh họa cho từng feature
  • 📈 Phân tích tầm quan trọng của các features

Khi nào đọc: Khi bạn muốn hiểu cách hệ thống trích xuất thông tin từ đoạn text công việc


2. 🤖 artifacts/

Thư mục chứa các model đã được huấn luyện

Các file trong thư mục:

artifacts/
├── extratrees_log1p.joblib           # Model chính (Extra Trees với log transform)
├── extratrees_staff_model.joblib     # Model dự đoán nhân sự
├── model_meta.joblib                 # Metadata của model (params, metrics)
└── X_proc_columns.joblib             # Danh sách features và thứ tự columns

Định dạng: Joblib (compressed pickle format)

Cách load:

import joblib
model = joblib.load('artifacts/extratrees_log1p.joblib')

3. 📄 input.json

File input mẫu để dự đoán cho MỘT ca làm việc của MỘT tòa nhà

Cấu trúc:

{
  "ma_dia_diem": "TD-001",
  "loai_ca": "Hành chính",
  "bat_dau": "07:00:00",
  "ket_thuc": "15:00:00",
  "tong_gio_lam": 8.0,
  "so_ca_cua_toa": 3,
  "all_task_normal": "Lau sàn hành lang; Thu gom rác WC; Vệ sinh sảnh chính; Lau kính thang máy",
  "all_task_dinhky": "Cọ bồn cầu WC tầng 2; Đánh sàn lobby; Trực phát sinh",
  "so_tang": 12,
  "so_cua_thang_may": 4,
  "dien_tich_ngoai_canh": 350.0,
  "dien_tich_sanh": 220.0,
  "dien_tich_hanh_lang": 1800.0,
  "dien_tich_wc": 420.0,
  "dien_tich_phong": 2600.0,
  "dien_tich_tham": 800.0,
  "dien_tich_kinh": 560.0,
  "doc_ham": 1,
  "vien_phan_quang": 0,
  "op_tuong": 1,
  "op_chan_tuong": 1,
  "ranh_thoat_nuoc": 1
}

📝 Giải Thích Chi Tiết Các Trường:

🏢 Thông tin tòa nhà & ca:

  • ma_dia_diem: Mã định danh tòa nhà
  • loai_ca: Loại ca làm việc (Hành chính / Ca sáng / Ca chiều / Ca tối / Ca đêm)
  • bat_dau, ket_thuc: Thời gian bắt đầu và kết thúc ca (HH:MM:SS)
  • tong_gio_lam: Tổng số giờ làm việc trong ca
  • so_ca_cua_toa: Tổng số ca làm việc trong ngày của tòa nhà

📋 Công việc - 2 loại quan trọng:

all_task_normal - CÔNG VIỆC HẰNG NGÀY:

  • Các task được thực hiện MỖI NGÀY trong ca này
  • Ví dụ: Lau sàn, Thu rác, Vệ sinh WC (mỗi ngày đều phải làm)
  • Tần suất: Ngày nào cũng làm, ca nào cũng làm
  • Format: Các task cách nhau bởi dấu chấm phẩy (;)

all_task_dinhky - CÔNG VIỆC ĐỊNH KỲ (TUẦN/THÁNG):

  • Các task được thực hiện THEO TUẦN hoặc THEO THÁNG
  • Ví dụ: Cọ bồn cầu (1 tuần/lần), Đánh sàn (1 tháng/lần), Trực phát sinh
  • Tần suất: Không làm hàng ngày, chỉ làm định kỳ
  • Format: Các task cách nhau bởi dấu chấm phẩy (;)

Sự khác biệt:

all_task_normal all_task_dinhky
Tần suất Hằng ngày Theo tuần/tháng
Ví dụ Lau sàn, Thu rác Cọ rửa, Đánh sàn
Khối lượng Công việc nhẹ, lặp lại Công việc nặng, ít lần

🏗️ Đặc điểm vật lý:

  • so_tang: Tổng số tầng
  • so_cua_thang_may: Số cửa thang máy

📏 Diện tích (m²) - ⚠️ TỔNG TẤT CẢ CÁC TẦNG:

  • dien_tich_ngoai_canh: Khu vực ngoại cảnh (sân, vỉa hè)
  • dien_tich_sanh: Sảnh, lobby
  • dien_tich_hanh_lang: Hành lang, lối đi
  • dien_tich_wc: WC, toilet
  • dien_tich_phong: Các phòng (văn phòng, phòng họp)
  • dien_tich_tham: Sàn có thảm
  • dien_tich_kinh: Kính cần lau

⚠️ CHÚ Ý: Tất cả diện tích là TỔNG của TẤT CẢ các tầng!

Ví dụ: Tòa 12 tầng, mỗi tầng 150m² hành lang → dien_tich_hanh_lang = 1800m²

🔧 Đặc điểm bề mặt (1=Có, 0=Không):

  • doc_ham: Có tầng hầm
  • vien_phan_quang: Có viền phản quang
  • op_tuong: Có ốp tường
  • op_chan_tuong: Có ốp chân tường
  • ranh_thoat_nuoc: Có rãnh thoát nước

4. 🎯 all_predict.py

Script chính để chạy dự đoán

Chức năng:

  1. 📖 Đọc file input.json
  2. 🔄 Trích xuất text features từ công việc
  3. 🏗️ Xây dựng feature vector đầy đủ
  4. 🤖 Load model từ artifacts/
  5. 📊 Dự đoán số nhân sú cần thiết
  6. 💾 Xuất kết quả

Cách chạy:

python all_predict.py

Output: Số nhân sự dự đoán cho ca làm việc trong input.json


5. 🔧 predict.py

Module chứa hàm trích xuất text features từ công việc

Hàm chính:

extract_text_features_to_json(task_normal: str, task_dinhky: str) -> str

Input:

  • task_normal: Text công việc HẰNG NGÀY (các task làm mỗi ngày)
  • task_dinhky: Text công việc ĐỊNH KỲ TUẦN/THÁNG (các task làm định kỳ)

Output: JSON string chứa 18 text features:

  • task_counts (7 features): Số lượng từng loại công việc
  • area_coverage (7 features): Số công việc theo khu vực
  • ratios_and_diversity (4 features): Tỷ lệ và độ đa dạng

Vai trò: Module này được gọi bởi all_predict.py để trích xuất keyword features từ text công việc


6. 📊 outputs/

Thư mục chứa kết quả dự đoán và đánh giá model

File quan trọng:

val_predictions_extratrees.csv

  • 📌 Mục đích: So sánh kết quả dự đoán với giá trị thực tế trên tập validation
  • 📊 Nội dung:
    • y_true: Số nhân sự thực tế (ground truth label)
    • y_pred: Số nhân sự dự đoán bởi model
    • Các features đầu vào
    • Metrics: MAE, RMSE, Error %
  • 🎯 Công dụng: Phân tích lỗi, kiểm tra độ chính xác của model trên validation set

Ví dụ nội dung:

ma_dia_diem,y_true,y_pred,error,error_pct,dien_tich_hanh_lang,...
TD-001,8,7.5,0.5,6.25%,1800.0,...
TD-002,12,11.8,0.2,1.67%,2400.0,...
...

7. 🔧 Các File Script Khác

extract_25_features_new.py

  • Trích xuất 25 features từ text công việc (phiên bản đầy đủ)
  • Tương tự predict.py nhưng với nhiều features hơn

merge_all_features.py

  • Gộp các features từ nhiều nguồn khác nhau
  • Tạo ra dataset hoàn chỉnh cho training

🔄 Pipeline Dự Đoán

graph TB
    A[input.json] --> B[all_predict.py]
    B --> C[Gọi predict.py]
    C --> D[Trích xuất Keyword Features]
    D --> E[Trả về JSON features]
    E --> B
    B --> F[Tiền xử lý các trường khác]
    F --> G[Kết hợp tất cả features]
    G --> H[Load Model từ artifacts/]
    H --> I[Dự đoán số nhân sự]
    I --> J[Output: Số nhân sự cần thiết]

Chi tiết từng bước:

  1. Input 📥

    • all_predict.py đọc input.json chứa thông tin ca làm việc
    • Bao gồm 2 loại công việc: all_task_normal (hằng ngày) và all_task_dinhky (định kỳ)
  2. Text Feature Extraction 🔤

    • all_predict.py GỌI predict.py
    • predict.py trích xuất 18 keyword features từ text công việc
    • Gộp cả 2 loại công việc (normal + dinhky) để phân tích
    • Trả về JSON chứa features cho all_predict.py
  3. Feature Engineering 🏗️

    • all_predict.py tiền xử lý các trường còn lại:
      • Diện tích (hanh_lang, wc, sanh, v.v.)
      • Đặc điểm tòa nhà (so_tang, so_cua_thang_may)
      • Đặc điểm bề mặt (doc_ham, op_tuong, v.v.)
    • Kết hợp text features với building features
    • Chuẩn hóa dữ liệu theo chuẩn của training set
  4. Model Prediction 🤖

    • all_predict.py load model đã được train từ artifacts/
    • Đẩy feature vector đầy đủ vào model
    • Model dự đoán số nhân sự
  5. Output 📤

    • Trả về số nhân sự cần thiết cho ca đó

🚀 Hướng Dẫn Sử Dụng

Yêu cầu hệ thống

pip install pandas numpy scikit-learn joblib openpyxl

1. Dự đoán cho MỘT ca làm việc

Bước 1: Chuẩn bị input.json

{
  "ma_dia_diem": "TD-001",
  "loai_ca": "Hành chính",
  "bat_dau": "07:00:00",
  "ket_thuc": "15:00:00",
  "tong_gio_lam": 8.0,
  "so_ca_cua_toa": 3,
  "all_task_normal": "Lau sàn hành lang; Thu gom rác WC; Vệ sinh sảnh",
  "all_task_dinhky": "Cọ bồn cầu WC; Đánh sàn lobby; Trực phát sinh",
  "so_tang": 12,
  "so_cua_thang_may": 4,
  "dien_tich_hanh_lang": 1800.0,
  "dien_tich_wc": 420.0,
  ...
}

💡 Lưu ý về 2 trường công việc:

  • all_task_normal: Các task làm MỖI NGÀY (lau sàn, thu rác hàng ngày)
  • all_task_dinhky: Các task làm THEO TUẦN/THÁNG (cọ rửa định kỳ, đánh sàn định kỳ)

Bước 2: Chạy prediction

python all_predict.py

Bước 3: Xem kết quả

📊 Dự đoán số nhân sự: 8 người

2. Trích xuất Text Features riêng lẻ (Test predict.py)

from predict import extract_text_features_to_json
import json

# Công việc hằng ngày (daily tasks)
task_normal = "Lau sàn WC tầng 1; Thu gom rác hành lang; Vệ sinh sảnh"

# Công việc định kỳ (weekly/monthly tasks)
task_dinhky = "Cọ bồn cầu WC; Đánh sàn lobby; Trực phát sinh"

# Trích xuất features (gộp cả 2 loại công việc để phân tích)
features_json = extract_text_features_to_json(task_normal, task_dinhky)

# Parse JSON
features = json.loads(features_json)

print(f"Tổng số tasks: {features['task_counts']['num_tasks']}")
print(f"Số tasks vệ sinh: {features['task_counts']['num_cleaning_tasks']}")
print(f"Số tasks cọ rửa: {features['task_counts']['num_deep_cleaning_tasks']}")
print(f"Tỷ lệ vệ sinh: {features['ratios_and_diversity']['cleaning_ratio']}")

3. Training lại model (nếu cần)

Bước 1: Chuẩn bị data

  • Đảm bảo final_2.csv có đủ features
  • Đảm bảo diện tích là TỔNG các tầng

Bước 2: Chạy notebook training

jupyter notebook ML_Training_Pipeline_Complete.ipynb

Bước 3: Model mới sẽ được lưu vào artifacts/

Bước 4: Kiểm tra kết quả validation

  • Xem file outputs/val_predictions_extratrees.csv để đánh giá độ chính xác
  • So sánh y_true (thực tế) vs y_pred (dự đoán)

📊 Đánh Giá Model

File Kết Quả: outputs/val_predictions_extratrees.csv

File này chứa kết quả dự đoán trên tập validation, giúp đánh giá độ chính xác của model:

Cấu trúc file:

ma_dia_diem,loai_ca,y_true,y_pred,error,error_pct,dien_tich_hanh_lang,dien_tich_wc,...
TD-001,Hành chính,8,7.5,0.5,6.25%,1800.0,420.0,...
TD-002,Ca sáng,12,11.8,0.2,1.67%,2400.0,560.0,...
TD-003,Ca chiều,6,6.3,-0.3,-5.0%,1200.0,280.0,...

Các cột quan trọng:

  • ma_dia_diem: Mã tòa nhà
  • loai_ca: Loại ca làm việc
  • y_true: Số nhân sự thực tế (ground truth)
  • y_pred: Số nhân sự dự đoán bởi model
  • error: Sai số = y_pred - y_true
  • error_pct: % sai số = (error / y_true) × 100%
  • Các features khác: dien_tich_, num__tasks, v.v.

Cách sử dụng:

import pandas as pd

# Đọc kết quả validation
df = pd.read_csv('outputs/val_predictions_extratrees.csv')

# Tính metrics
mae = df['error'].abs().mean()
rmse = (df['error']**2).mean() ** 0.5

print(f"MAE: {mae:.2f} người")
print(f"RMSE: {rmse:.2f} người")
print(f"MAPE: {df['error_pct'].abs().mean():.2f}%")

# Xem những dự đoán sai nhiều nhất
worst_predictions = df.nlargest(10, 'error')
print(worst_predictions[['ma_dia_diem', 'y_true', 'y_pred', 'error']])

📈 Text Features Chi Tiết

Nhóm 1: Task Counts (7 features)

Feature Mô tả Keywords
num_tasks Tổng số công việc -
num_cleaning_tasks Công việc vệ sinh vệ sinh, lau, chùi, quét, hút
num_trash_collection_tasks Thu gom rác thu gom rác, thay rác, đổ rác
num_monitoring_tasks Trực/giám sát trực, kiểm tra, check, giám sát
num_deep_cleaning_tasks Vệ sinh sâu cọ rửa, cọ bồn cầu, đánh sàn
num_support_tasks Hỗ trợ giao ca, bàn giao, chụp ảnh, chuẩn bị
num_other_tasks Công việc khác (không match keywords trên)

Nhóm 2: Area Coverage (7 features)

Feature Mô tả Keywords
num_wc_tasks WC/Toilet wc, toilet, nhà vệ sinh, bồn cầu
num_hallway_tasks Hành lang hành lang, corridor, lối đi
num_lobby_tasks Sảnh sảnh, lobby, tiền sảnh
num_outdoor_tasks Ngoại cảnh ngoại cảnh, sân, vỉa hè, khuôn viên
num_elevator_tasks Thang máy thang máy, elevator, cầu thang
num_medical_tasks_total Khu vực y tế phòng bệnh, phòng khám, phòng mổ, xét nghiệm
num_indoor_room_tasks Phòng văn phòng phòng họp, văn phòng, phòng giám đốc

Nhóm 3: Ratios & Diversity (4 features)

Feature Mô tả Công thức
cleaning_ratio Tỷ lệ vệ sinh cleaning_tasks / total_tasks
trash_collection_ratio Tỷ lệ thu rác trash_tasks / total_tasks
monitoring_ratio Tỷ lệ trực monitoring_tasks / total_tasks
area_diversity Độ đa dạng khu vực Số khu vực có ít nhất 1 task

📝 Lưu Ý Quan Trọng

⚠️ Về 2 Loại Công Việc

📋 all_task_normal - CÔNG VIỆC HẰNG NGÀY:

  • Các task thực hiện MỖI NGÀY trong ca
  • Ví dụ: Lau sàn, Thu rác, Vệ sinh WC
  • Đặc điểm: Công việc nhẹ, lặp lại hàng ngày
  • Tần suất: Ngày nào cũng làm

📋 all_task_dinhky - CÔNG VIỆC ĐỊNH KỲ:

  • Các task thực hiện THEO TUẦN hoặc THEO THÁNG
  • Ví dụ: Cọ bồn cầu (1 tuần/lần), Đánh sàn (1 tháng/lần)
  • Đặc điểm: Công việc nặng hơn, không làm hàng ngày
  • Tần suất: Định kỳ (weekly/monthly)

Cách xử lý trong model:

  • Hệ thống sẽ GỘP CẢ 2 LOẠI công việc để phân tích
  • Trích xuất features từ tổng hợp: all_task_normal + all_task_dinhky
  • Điều này giúp model hiểu được TOÀN BỘ KHỐI LƯỢNG CÔNG VIỆC của ca đó

⚠️ Về Diện Tích

TỔNG diện tích trong final_2.csvinput.json là tổng của TẤT CẢ các tầng trong tòa nhà!

Ví dụ:

  • Tòa nhà 15 tầng, mỗi tầng 300m² hành lang
  • dien_tich_hanh_lang = 15 × 300 = 4500m²
  • KHÔNG PHẢI 300m²!

Công thức: dien_tich_X = so_tang × dien_tich_X_moi_tang


📌 Về Ca Làm Việc

  • Mỗi input.json chỉ đại diện cho MỘT ca của MỘT tòa nhà
  • Loại ca: Hành chính, Ca sáng, Ca chiều, Ca tối, Ca đêm
  • Bao gồm thông tin thời gian: bat_dau, ket_thuc, tong_gio_lam

🔤 Về Text Format

  • Text công việc phải bằng tiếng Việt (có dấu hoặc không dấu đều được)
  • Các công việc tách nhau bằng dấu chấm phẩy (;) hoặc | hoặc xuống dòng
  • Hệ thống tự động lowercase và normalize
  • Nên viết rõ ràng: "Lau sàn hành lang" thay vì "Lau sàn"
  • Nên có thông tin khu vực: "Vệ sinh WC tầng 2" thay vì chỉ "Vệ sinh"