Upload files to "/"

This commit is contained in:
nguyenletai16122001 2026-01-13 18:57:48 +07:00
parent ec513d49b7
commit 3de6cc4a75
1 changed files with 737 additions and 0 deletions

737
All_feature_Readme.ipynb Normal file
View File

@ -0,0 +1,737 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "aafd0f86",
"metadata": {},
"source": [
"# 📋 Định Nghĩa Các Trường Trong final_2.xlsx\n",
"\n",
"**Dataset:** final_2.xlsx \n",
"**Nguồn:** Extract từ text + Feature Engineering \n",
"**Module:** extract_25_features.py + cell 1 của test3.ipynb\n",
"\n",
"**Tổng số features:** 41 features\n",
"- 19 Text Features (từ tasks text) \n",
"- 13 Building Features (thông tin tòa nhà, diện tích)\n",
"- 6 Shift/Time Features (ca làm việc)\n",
"- 1 Additional Feature (so_ca_cua_toa)\n",
"- 2 Metadata (ma_dia_diem, text columns)\n",
"\n",
"\n",
"**Target:** `so_luong` - Số lượng nhân sự cần thiết---\n"
]
},
{
"cell_type": "markdown",
"id": "746c6835",
"metadata": {},
"source": [
"## 📊 NHÓM 1: Task Counts - Đếm Theo Loại Công Việc (7 features)\n",
"\n",
"### 1. `num_tasks`\n",
"**Định nghĩa:** Tổng số công việc \n",
"**Cách tính:** \n",
"```python\n",
"# Tách text thành các tasks riêng lẻ bằng delimiter: ; | hoặc \\n\n",
"tasks = re.split(r'[;|\\n]+', tasks_text)\n",
"tasks = [t.strip() for t in tasks if t.strip()]\n",
"num_tasks = len(tasks)\n",
"```\n",
"**Ví dụ:** 50, 100, 150\n",
"\n",
"---\n",
"\n",
"### 2. `num_cleaning_tasks`\n",
"**Định nghĩa:** Số công việc vệ sinh thường ngày \n",
"**Keywords (18):**\n",
"- vệ sinh, tvs, tổng vệ sinh\n",
"- lau, chùi, quét, hút\n",
"- đẩy khô, lau ẩm, đẩy ẩm\n",
"- làm sạch, lau bụi, quét bụi\n",
"- lau kính, lau sàn, quét sàn\n",
"- hút bụi, lau nền\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"cleaning_keywords = ['vệ sinh', 'tvs', 'lau', 'chùi', 'quét', 'hút', ...]\n",
"num_cleaning_tasks = count_tasks_with_keywords(tasks, cleaning_keywords)\n",
"# Đếm số tasks chứa ÍT NHẤT 1 keyword\n",
"```\n",
"**Ví dụ:** 28, 45, 60 \n",
"**Tỷ lệ:** ~55.9% công việc\n",
"\n",
"---\n",
"\n",
"### 3. `num_trash_collection_tasks`\n",
"**Định nghĩa:** Số công việc thu gom/thay rác \n",
"**Keywords (13):**\n",
"- thu gom rác, thay rác, vận chuyển rác\n",
"- tua rác, đổ rác, thu rác\n",
"- gom rác, chuyển rác, bỏ rác\n",
"- đẩy rác, quét rác nổi\n",
"- trực rác, rác nổi\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"trash_keywords = ['thu gom rác', 'thay rác', 'tua rác', ...]\n",
"num_trash_collection_tasks = count_tasks_with_keywords(tasks, trash_keywords)\n",
"```\n",
"**Ví dụ:** 5, 10, 15 \n",
"**Tỷ lệ:** ~7.9% công việc\n",
"\n",
"---\n",
"\n",
"### 4. `num_monitoring_tasks`\n",
"**Định nghĩa:** Số công việc trực/kiểm tra phát sinh \n",
"**Keywords (10):**\n",
"- trực, trực phát sinh, trực lại\n",
"- trực ps, trực tua\n",
"- kiểm tra, check\n",
"- giám sát, theo dõi, tuần tra\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"monitoring_keywords = ['trực', 'trực phát sinh', 'kiểm tra', 'check', ...]\n",
"num_monitoring_tasks = count_tasks_with_keywords(tasks, monitoring_keywords)\n",
"```\n",
"**Ví dụ:** 8, 12, 20 \n",
"**Tỷ lệ:** ~16.1% công việc\n",
"\n",
"---\n",
"\n",
"### 5. `num_deep_cleaning_tasks`\n",
"**Định nghĩa:** Số công việc vệ sinh chuyên sâu \n",
"**Keywords (14):**\n",
"- cọ rửa, cọ bồn cầu, cọ\n",
"- gạt kính, gạt\n",
"- đánh sàn, đánh chân tường, đánh cọ\n",
"- đánh vết bẩn, chà tường, đánh dép\n",
"- cọ gương, cọ lavabo, cọ thùng rác\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"deep_cleaning_keywords = ['cọ rửa', 'cọ bồn cầu', 'gạt kính', 'đánh sàn', ...]\n",
"num_deep_cleaning_tasks = count_tasks_with_keywords(tasks, deep_cleaning_keywords)\n",
"```\n",
"**Ví dụ:** 3, 8, 12 \n",
"**Tỷ lệ:** ~4.5% công việc\n",
"\n",
"---\n",
"\n",
"### 6. `num_support_tasks`\n",
"**Định nghĩa:** Số công việc hỗ trợ/chuẩn bị \n",
"**Keywords (12):**\n",
"- giao ca, bàn giao, bàn giao ca\n",
"- chụp ảnh, nhận ca\n",
"- vsdc (vệ sinh dụng cụ)\n",
"- vệ sinh dụng cụ, chuẩn bị dụng cụ\n",
"- vệ sinh xe đồ, chuẩn bị nước\n",
"- chuẩn bị, giao ban\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"support_keywords = ['giao ca', 'bàn giao', 'vsdc', 'chuẩn bị dụng cụ', ...]\n",
"num_support_tasks = count_tasks_with_keywords(tasks, support_keywords)\n",
"```\n",
"**Ví dụ:** 2, 5, 8 \n",
"**Tỷ lệ:** ~5.8% công việc\n",
"\n",
"---\n",
"\n",
"### 7. `num_other_tasks`\n",
"**Định nghĩa:** Số công việc KHÔNG thuộc các loại trên \n",
"**Cách tính:** \n",
"```python\n",
"# Gộp TẤT CẢ keywords từ 6 nhóm trên\n",
"all_keywords = cleaning_keywords + trash_keywords + monitoring_keywords + \n",
" deep_cleaning_keywords + support_keywords\n",
"\n",
"# Đếm tasks KHÔNG chứa bất kỳ keyword nào\n",
"num_other_tasks = count_tasks_without_any_keywords(tasks, all_keywords)\n",
"```\n",
"**Ví dụ:** 3, 8, 15"
]
},
{
"cell_type": "markdown",
"id": "b264dfaf",
"metadata": {},
"source": [
"## 🏢 NHÓM 2: Area Coverage - Đếm Theo Khu Vực (7 features)\n",
"\n",
"### 8. `num_wc_tasks`\n",
"**Định nghĩa:** Số công việc tại WC/Toilet \n",
"**Keywords (12):**\n",
"- wc, toilet, nhà vệ sinh\n",
"- restroom, phòng vệ sinh\n",
"- bồn cầu, lavabo\n",
"- tiểu nam, bồn tiểu\n",
"- wc công cộng, wc nhân viên, nhà wc\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"wc_keywords = ['wc', 'toilet', 'nhà vệ sinh', 'bồn cầu', 'lavabo', ...]\n",
"num_wc_tasks = count_tasks_with_keywords(tasks, wc_keywords)\n",
"```\n",
"**Ví dụ:** 10, 15, 25 \n",
"**Tỷ lệ:** ~20.4% công việc\n",
"\n",
"---\n",
"\n",
"### 9. `num_hallway_tasks`\n",
"**Định nghĩa:** Số công việc tại hành lang \n",
"**Keywords (7):**\n",
"- hành lang, corridor, lối đi\n",
"- hall, hành lang tầng\n",
"- hl, hanh lang\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"hallway_keywords = ['hành lang', 'corridor', 'lối đi', 'hall', 'hl', ...]\n",
"num_hallway_tasks = count_tasks_with_keywords(tasks, hallway_keywords)\n",
"```\n",
"**Ví dụ:** 8, 12, 20 \n",
"**Tỷ lệ:** ~13.7% công việc\n",
"\n",
"---\n",
"\n",
"### 10. `num_lobby_tasks`\n",
"**Định nghĩa:** Số công việc tại sảnh \n",
"**Keywords (8):**\n",
"- sảnh, lobby, tiền sảnh\n",
"- sảnh đỏ, sảnh chính\n",
"- sảnh tầng, sanh\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"lobby_keywords = ['sảnh', 'lobby', 'tiền sảnh', 'sảnh chính', ...]\n",
"num_lobby_tasks = count_tasks_with_keywords(tasks, lobby_keywords)\n",
"```\n",
"**Ví dụ:** 5, 8, 12 \n",
"**Tỷ lệ:** ~7.6% công việc\n",
"\n",
"---\n",
"\n",
"### 11. `num_outdoor_tasks`\n",
"**Định nghĩa:** Số công việc tại ngoại cảnh \n",
"**Keywords (10):**\n",
"- ngoại cảnh, sân, vỉa hè\n",
"- khuôn viên, cổng, outdoor\n",
"- bãi xe, tầng hầm\n",
"- sân sau, sân trước\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"outdoor_keywords = ['ngoại cảnh', 'sân', 'vỉa hè', 'khuôn viên', 'bãi xe', ...]\n",
"num_outdoor_tasks = count_tasks_with_keywords(tasks, outdoor_keywords)\n",
"```\n",
"**Ví dụ:** 3, 6, 10 \n",
"**Tỷ lệ:** ~4.3% công việc\n",
"\n",
"---\n",
"\n",
"### 12. `num_elevator_tasks`\n",
"**Định nghĩa:** Số công việc tại thang máy/cầu thang \n",
"**Keywords (9):**\n",
"- thang máy, elevator, lift\n",
"- cầu thang, bậc tam cấp\n",
"- thang bộ, cầu thang bộ\n",
"- tay vịn, tam cấp\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"elevator_keywords = ['thang máy', 'elevator', 'cầu thang', 'bậc tam cấp', ...]\n",
"num_elevator_tasks = count_tasks_with_keywords(tasks, elevator_keywords)\n",
"```\n",
"**Ví dụ:** 5, 10, 15 \n",
"**Tỷ lệ:** ~10.6% công việc\n",
"\n",
"---\n",
"\n",
"### 13. `num_medical_tasks_total` ⭐ MỚI\n",
"**Định nghĩa:** Tổng số công việc Y TẾ (gộp 4 loại phòng) \n",
"**Cách tính:** \n",
"```python\n",
"# GỘP 4 features:\n",
"num_medical_tasks_total = (\n",
" num_patient_room_tasks + # Phòng bệnh\n",
" num_clinic_room_tasks + # Phòng khám\n",
" num_surgery_room_tasks + # Phòng mổ\n",
" num_technical_room_tasks # Phòng kỹ thuật\n",
")\n",
"```\n",
"\n",
"**Keywords tổng hợp:**\n",
"\n",
"**Phòng bệnh (7):** phòng bệnh, giường bệnh, phòng víp, phòng vip, phòng bệnh nhân, pb, phòng bv\n",
"\n",
"**Phòng khám (7):** phòng khám, khoa khám, phòng nội, phòng sản, phòng khám bệnh, khu khám, pk\n",
"\n",
"**Phòng mổ (7):** phòng mổ, hậu phẫu, phòng phẫu thuật, khu mổ, phòng pt, ngoài phòng mổ, trong phòng mổ\n",
"\n",
"**Phòng kỹ thuật (13):** phòng xét nghiệm, phòng chụp, xq, siêu âm, kho dược, phòng xn, labo, phòng thí nghiệm, phòng kỹ thuật, phòng điện tim, phòng nội soi, phòng cấp cứu, phòng hồi sức\n",
"\n",
"**Ví dụ:** 0 (văn phòng), 5, 15, 30 (bệnh viện) \n",
"**Đặc trưng:** Bệnh viện có giá trị >0, Văn phòng =0\n",
"\n",
"---\n",
"\n",
"### 14. `num_indoor_room_tasks` ⭐ MỚI\n",
"**Định nghĩa:** Số công việc tại phòng hành chính/văn phòng \n",
"**Keywords (13):**\n",
"- phòng nhân viên, phòng giám đốc\n",
"- phòng họp, phòng hành chính\n",
"- văn phòng, phòng gd, phòng pgd\n",
"- phòng ban, phòng giao ban\n",
"- phòng bác sĩ, phòng trưởng khoa\n",
"- hội trường, phòng kế toán\n",
"\n",
"**Cách tính:** \n",
"```python\n",
"# RENAME từ num_office_tasks\n",
"office_keywords = ['phòng nhân viên', 'phòng họp', 'văn phòng', ...]\n",
"num_indoor_room_tasks = count_tasks_with_keywords(tasks, office_keywords)\n",
"```\n",
"**Ví dụ:** 2, 5, 10 \n",
"**Tỷ lệ:** ~4.4% công việc"
]
},
{
"cell_type": "markdown",
"id": "69c362e1",
"metadata": {},
"source": [
"## 📐 NHÓM 3: Ratios & Indicators (5 features)\n",
"\n",
"### 15. `cleaning_ratio`\n",
"**Định nghĩa:** Tỷ lệ công việc vệ sinh \n",
"**Cách tính:** \n",
"```python\n",
"cleaning_ratio = num_cleaning_tasks / num_tasks if num_tasks > 0 else 0.0\n",
"cleaning_ratio = round(cleaning_ratio, 4)\n",
"```\n",
"**Range:** 0.0 - 1.0 \n",
"**Ví dụ:** 0.25, 0.40, 0.55 \n",
"**Mean:** ~0.559 (55.9%)\n",
"\n",
"---\n",
"\n",
"### 16. `trash_collection_ratio`\n",
"**Định nghĩa:** Tỷ lệ công việc thu rác \n",
"**Cách tính:** \n",
"```python\n",
"trash_collection_ratio = num_trash_collection_tasks / num_tasks if num_tasks > 0 else 0.0\n",
"trash_collection_ratio = round(trash_collection_ratio, 4)\n",
"```\n",
"**Range:** 0.0 - 1.0 \n",
"**Ví dụ:** 0.10, 0.15, 0.20 \n",
"**Mean:** ~0.079 (7.9%)\n",
"\n",
"---\n",
"\n",
"### 17. `monitoring_ratio`\n",
"**Định nghĩa:** Tỷ lệ công việc trực/kiểm tra \n",
"**Cách tính:** \n",
"```python\n",
"monitoring_ratio = num_monitoring_tasks / num_tasks if num_tasks > 0 else 0.0\n",
"monitoring_ratio = round(monitoring_ratio, 4)\n",
"```\n",
"**Range:** 0.0 - 1.0 \n",
"**Ví dụ:** 0.15, 0.20, 0.30 \n",
"**Mean:** ~0.161 (16.1%)\n",
"\n",
"---\n",
"\n",
"### 18. `area_diversity`\n",
"**Định nghĩa:** Độ đa dạng khu vực (số loại khu vực có công việc) \n",
"**Cách tính:** \n",
"```python\n",
"# Đếm số khu vực có công việc (>0)\n",
"area_counts = [\n",
" num_wc_tasks,\n",
" num_hallway_tasks,\n",
" num_lobby_tasks,\n",
" num_outdoor_tasks,\n",
" num_elevator_tasks,\n",
" num_medical_tasks_total, # Gộp 4 medical\n",
" num_indoor_room_tasks # Office/admin\n",
"]\n",
"\n",
"area_diversity = sum(1 for count in area_counts if count > 0)\n",
"```\n",
"**Range:** 0 - 7 \n",
"**Ví dụ:** 3, 5, 7 \n",
"**Mean:** ~5.8 khu vực\n",
"\n",
"---\n",
"\n",
"### 19. `is_tasks_text_missing` ⭐ MỚI\n",
"**Định nghĩa:** Cờ đánh dấu TẤT CẢ text columns đều missing/empty \n",
"**Cách tính:** \n",
"```python\n",
"text_cols = [\n",
" 'all_task_normal',\n",
" 'all_task_dinhky',\n",
" 'all_tasks_combined',\n",
" 'all_task_text',\n",
" 'all_task_text_backup'\n",
"]\n",
"\n",
"# Check nếu TẤT CẢ columns đều missing hoặc empty\n",
"missing_mask = True\n",
"for col in text_cols:\n",
" if col in df.columns:\n",
" is_null = df[col].isna()\n",
" is_empty = df[col].astype(str).str.strip() == \"\"\n",
" missing_mask = missing_mask & (is_null | is_empty)\n",
"\n",
"is_tasks_text_missing = missing_mask.astype(int)\n",
"# 1 = TẤT CẢ text missing\n",
"# 0 = Có ít nhất 1 text column có data\n",
"```\n",
"**Range:** 0 hoặc 1 (binary) \n",
"**Ví dụ:** 0 (có text), 1 (không có text) \n",
"**Ý nghĩa:** Giúp model biết data quality, handle missing text better"
]
},
{
"cell_type": "markdown",
"id": "a4f6ee08",
"metadata": {},
"source": [
"## 🏗️ NHÓM 4: Building Features (13 features)\n",
"\n",
"### 4.1 Thông Tin Tòa Nhà (2 features)\n",
"\n",
"| Feature | Định Nghĩa | Data Type | Ví Dụ |\n",
"|---------|-----------|-----------|--------|\n",
"| `so_tang` | Số tầng của tòa nhà | Integer | 5, 10, 20, 30 |\n",
"| `so_cua_thang_may` | Số cửa thang máy | Integer | 2, 4, 6, 8 |\n",
"\n",
"---\n",
"\n",
"### 4.2 Diện Tích Các Khu Vực (6 features - đơn vị: m²)\n",
"\n",
"| Feature | Định Nghĩa | Data Type | Ví Dụ |\n",
"|---------|-----------|-----------|--------|\n",
"| `dien_tich_phong` | Diện tích các phòng làm việc | Float | 500.0, 1200.5 |\n",
"| `dien_tich_hanh_lang` | Diện tích hành lang | Float | 200.0, 450.0 |\n",
"| `dien_tich_sanh` | Diện tích sảnh chính | Float | 300.0, 600.0 |\n",
"| `dien_tich_wc` | Diện tích toilet/WC | Float | 50.0, 120.0 |\n",
"| `dien_tich_ngoai_canh` | Diện tích ngoại cảnh | Float | 150.0, 300.0 |\n",
"| `dien_tich_kinh` | Diện tích kính (cửa kính, vách kính) | Float | 100.0, 250.0 |\n",
"\n",
"---\n",
"\n",
"### 4.3 Vật Liệu / Đặc Điểm Khác (5 features)\n",
"\n",
"| Feature | Định Nghĩa | Data Type | Ví Dụ |\n",
"|---------|-----------|-----------|--------|\n",
"| `dien_tich_tham` | Diện tích thảm | Float | 50.0, 150.0 |\n",
"| `doc_ham` | Độc hầm (có tầng hầm) | Binary 0/1 | 0 (không), 1 (có) |\n",
"| `vien_phan_quang` | Viền phản quang | Binary/Float | 0/1 hoặc số lượng |\n",
"| `op_tuong` | Ốp tường | Binary/Float | 0/1 hoặc diện tích |\n",
"| `op_chan_tuong` | Ốp chân tường | Binary/Float | 0/1 hoặc chiều dài |\n",
"| `ranh_thoat_nuoc` | Rãnh thoát nước | Binary/Float | 0/1 hoặc chiều dài |"
]
},
{
"cell_type": "markdown",
"id": "896efd61",
"metadata": {},
"source": [
"## ⏰ NHÓM 5: Shift/Time Features (6 features)\n",
"\n",
"| Feature | Định Nghĩa | Data Type | Ví Dụ |\n",
"|---------|-----------|-----------|--------|\n",
"| `loai_ca` | Loại ca làm việc | String/Categorical | \"Ca sáng\", \"Ca chiều\", \"Ca tối\" |\n",
"| `bat_dau` | Giờ bắt đầu ca (raw string) | String | \"07:00:00\", \"14:00:00\" |\n",
"| `ket_thuc` | Giờ kết thúc ca (raw string) | String | \"15:00:00\", \"22:00:00\" |\n",
"| `tong_gio_lam` | Tổng số giờ làm (raw string) | String | \"8:00\", \"8.5\" |\n",
"| `so_ca_cua_toa` | Số ca của tòa nhà | Integer | 2, 3, 4 |\n",
"\n",
"**Note:** `bat_dau`, `ket_thuc`, `tong_gio_lam` là raw string, cần parse thành numeric nếu dùng trong model.\n",
"\n",
"---\n",
"\n",
"## 🎯 Target Variable\n",
"\n",
"### `so_luong`\n",
"**Định nghĩa:** Số lượng nhân sự cần thiết cho ca làm việc \n",
"**Data Type:** Integer \n",
"\n",
"**Range:** 0 - 64 **Note:** Đã extract thành features, giữ lại để tham khảo\n",
"\n",
"**Mean:** ~8.5 người **Data Type:** String \n",
"\n",
"**Median:** ~7 người **Định nghĩa:** Text thô của các công việc \n",
"\n",
"**Std:** ~6.2### `all_task_normal`, `all_task_dinhky`\n",
"\n",
"\n",
"\n",
"---**Note:** Không dùng trong model training (ID column)\n",
"\n",
"**Ví dụ:** \"HD-001\", \"HD-123\" \n",
"\n",
"## 📝 Metadata**Data Type:** String \n",
"\n",
"**Định nghĩa:** Mã định danh tòa nhà \n",
"### `ma_dia_diem`"
]
},
{
"cell_type": "markdown",
"id": "3e6d0986",
"metadata": {},
"source": [
"## 💡 Ví Dụ Chi Tiết\n",
"\n",
"### Case 1: Văn Phòng Nhỏ\n",
"\n",
"**Input text:**\n",
"```\n",
"Quét hành lang tầng 1; Lau kính sảnh; Thu gom rác WC; \n",
"Hút bụi phòng họp; Lau sàn văn phòng\n",
"```\n",
"\n",
"**Output features:**\n",
"```python\n",
"{\n",
" # Task Counts\n",
" 'num_tasks': 5,\n",
" 'num_cleaning_tasks': 4, # Quét, Lau kính, Hút bụi, Lau sàn\n",
" 'num_trash_collection_tasks': 1, # Thu gom rác\n",
" 'num_monitoring_tasks': 0,\n",
" 'num_deep_cleaning_tasks': 0,\n",
" 'num_support_tasks': 0,\n",
" 'num_other_tasks': 0,\n",
" \n",
" # Area Coverage\n",
" 'num_wc_tasks': 1, # WC\n",
" 'num_hallway_tasks': 1, # hành lang\n",
" 'num_lobby_tasks': 1, # sảnh\n",
" 'num_outdoor_tasks': 0,\n",
" 'num_elevator_tasks': 0,\n",
" 'num_medical_tasks_total': 0, # Văn phòng → không có medical\n",
" 'num_indoor_room_tasks': 2, # phòng họp, văn phòng\n",
" \n",
" # Ratios & Indicators\n",
" 'cleaning_ratio': 0.8000, # 4/5\n",
" 'trash_collection_ratio': 0.2000, # 1/5\n",
" 'monitoring_ratio': 0.0000,\n",
" 'area_diversity': 4, # WC, hành lang, sảnh, indoor\n",
" 'is_tasks_text_missing': 0 # Có text\n",
"}\n",
"```\n",
"\n",
"**Dự đoán:** `so_luong` ≈ 3-4 người\n",
"\n",
"---\n",
"\n",
"### Case 2: Bệnh Viện Lớn\n",
"\n",
"**Input text:**\n",
"```\n",
"Vệ sinh phòng bệnh tầng 3; Dọn mổ phòng PT1; \n",
"Cọ rửa WC khu khám; Trực phát sinh tầng 5;\n",
"Lau kính hành lang; Thu gom rác y tế; \n",
"Vệ sinh phòng xét nghiệm; Bàn giao ca sáng\n",
"```\n",
"\n",
"**Output features:**\n",
"```python\n",
"{\n",
" # Task Counts\n",
" 'num_tasks': 8,\n",
" 'num_cleaning_tasks': 4, # VS phòng bệnh, Lau kính, VS XN (3 tasks với \"vệ sinh\")\n",
" 'num_trash_collection_tasks': 1, # Thu gom rác y tế\n",
" 'num_monitoring_tasks': 1, # Trực phát sinh\n",
" 'num_deep_cleaning_tasks': 1, # Cọ rửa WC\n",
" 'num_support_tasks': 1, # Bàn giao ca\n",
" 'num_other_tasks': 1, # Dọn mổ (special medical task)\n",
" \n",
" # Area Coverage\n",
" 'num_wc_tasks': 1, # WC\n",
" 'num_hallway_tasks': 1, # hành lang\n",
" 'num_lobby_tasks': 0,\n",
" 'num_outdoor_tasks': 0,\n",
" 'num_elevator_tasks': 0,\n",
" 'num_medical_tasks_total': 3, # Phòng bệnh(1) + Phòng mổ/PT(1) + Phòng XN(1)\n",
" 'num_indoor_room_tasks': 0,\n",
" \n",
" # Ratios & Indicators\n",
" 'cleaning_ratio': 0.5000, # 4/8\n",
" 'trash_collection_ratio': 0.1250, # 1/8\n",
" 'monitoring_ratio': 0.1250, # 1/8\n",
" 'area_diversity': 3, # WC, hành lang, medical\n",
" 'is_tasks_text_missing': 0 # Có text\n",
"}\n",
"```\n",
"\n",
"**Dự đoán:** `so_luong` ≈ 10-15 người (bệnh viện cần nhiều nhân sự hơn)"
]
},
{
"cell_type": "markdown",
"id": "04e8cc28",
"metadata": {},
"source": [
"## 📈 Thống Kê Thực Tế (302 tòa nhà)\n",
"\n",
"### Task Counts\n",
"\n",
"| Feature | Mean | Std | Min | 25% | 50% | 75% | Max |\n",
"|---------|------|-----|-----|-----|-----|-----|-----|\n",
"| num_tasks | 102.4 | 64.3 | 8 | 55 | 92 | 138 | 384 |\n",
"| num_cleaning_tasks | 57.2 | 38.1 | 0 | 28 | 50 | 78 | 215 |\n",
"| num_trash_collection_tasks | 8.1 | 6.9 | 0 | 3 | 7 | 11 | 42 |\n",
"| num_monitoring_tasks | 16.5 | 14.2 | 0 | 6 | 12 | 23 | 89 |\n",
"| num_deep_cleaning_tasks | 4.6 | 5.3 | 0 | 1 | 3 | 6 | 35 |\n",
"| num_support_tasks | 5.9 | 6.8 | 0 | 1 | 4 | 8 | 45 |\n",
"\n",
"### Area Coverage\n",
"\n",
"| Feature | Mean | Std | Min | 25% | 50% | 75% | Max |\n",
"|---------|------|-----|-----|-----|-----|-----|-----|\n",
"| num_wc_tasks | 20.9 | 14.3 | 0 | 10 | 18 | 28 | 86 |\n",
"| num_hallway_tasks | 14.0 | 10.8 | 0 | 6 | 12 | 19 | 68 |\n",
"| num_lobby_tasks | 7.8 | 6.5 | 0 | 3 | 6 | 11 | 38 |\n",
"| num_outdoor_tasks | 4.4 | 5.9 | 0 | 0 | 2 | 6 | 38 |\n",
"| num_elevator_tasks | 10.9 | 8.7 | 0 | 4 | 9 | 15 | 52 |\n",
"| num_medical_tasks_total | 3.2 | 8.5 | 0 | 0 | 0 | 2 | 65 |\n",
"| num_indoor_room_tasks | 4.5 | 6.1 | 0 | 0 | 2 | 6 | 38 |\n",
"\n",
"### Ratios & Indicators\n",
"\n",
"| Feature | Mean | Std | Min | 25% | 50% | 75% | Max |\n",
"|---------|------|-----|-----|-----|-----|-----|-----|\n",
"| cleaning_ratio | 0.559 | 0.187 | 0.000 | 0.450 | 0.571 | 0.686 | 1.000 |\n",
"| trash_collection_ratio | 0.079 | 0.057 | 0.000 | 0.038 | 0.071 | 0.107 | 0.333 |\n",
"| monitoring_ratio | 0.161 | 0.126 | 0.000 | 0.067 | 0.133 | 0.222 | 0.667 |\n",
"| area_diversity | 5.8 | 1.6 | 1 | 5 | 6 | 7 | 7 |\n",
"| is_tasks_text_missing | - | - | 0 | 0 | 0 | 0 | 1 |"
]
},
{
"cell_type": "markdown",
"id": "ac393173",
"metadata": {},
"source": [
"## 🎯 Key Insights\n",
"\n",
"### 1. Phân bố công việc:\n",
"- **Vệ sinh thường ngày (55.9%)**: Chiếm đa số công việc\n",
"- **Trực/kiểm tra (16.1%)**: Yêu cầu nhân sự liên tục\n",
"- **Thu gom rác (7.9%)**: Công việc định kỳ nhưng quan trọng\n",
"- **Hỗ trợ (5.8%)**: Giao ca, chuẩn bị dụng cụ\n",
"- **Vệ sinh chuyên sâu (4.5%)**: Cọ rửa, đánh bóng\n",
"\n",
"### 2. Khu vực quan trọng:\n",
"- **WC (20.4%)**: Khu vực cần vệ sinh nhiều nhất\n",
"- **Hành lang (13.7%)**: Diện tích lớn, tần suất cao\n",
"- **Thang máy (10.6%)**: Tần suất vệ sinh cao\n",
"- **Sảnh (7.6%)**: Khu vực công cộng quan trọng\n",
"\n",
"### 3. Đặc trưng Y TẾ vs VĂN PHÒNG:\n",
"\n",
"**Bệnh viện:**\n",
"- `num_medical_tasks_total` > 0 (thường >5)\n",
"- `num_indoor_room_tasks` thấp hoặc 0\n",
"- `area_diversity` cao (6-7)\n",
"- `so_luong` trung bình cao hơn (10-20 người)\n",
"\n",
"**Văn phòng:**\n",
"- `num_medical_tasks_total` = 0\n",
"- `num_indoor_room_tasks` cao (>5)\n",
"- `area_diversity` trung bình (4-6)\n",
"- `so_luong` trung bình thấp hơn (3-8 người)\n",
"\n",
"### 4. Features quan trọng nhất (theo Random Forest importance):\n",
"1. `dien_tich_phong` (~0.15)\n",
"2. `num_trash_collection_tasks` (~0.10)\n",
"3. `num_medical_tasks_total` (~0.09) ⭐ Feature mới\n",
"4. `dien_tich_hanh_lang` (~0.08)\n",
"5. `area_diversity` (~0.07)"
]
},
{
"cell_type": "markdown",
"id": "24dbe85d",
"metadata": {},
"source": [
"## 🔧 Sử Dụng\n",
"\n",
"### Load data:\n",
"```python\n",
"import pandas as pd\n",
"\n",
"df = pd.read_excel('final_2.xlsx')\n",
"\n",
"print(f\"Shape: {df.shape}\") # (302, 41)\n",
"print(f\"Columns: {len(df.columns)}\")\n",
"\n",
"# Check new features\n",
"print(\"\\n✅ New features:\")\n",
"print(df['num_medical_tasks_total'].describe())\n",
"print(df['num_indoor_room_tasks'].describe())\n",
"print(df['is_tasks_text_missing'].value_counts())\n",
"```\n",
"\n",
"### Prepare for modeling:\n",
"```python\n",
"# Drop non-model columns\n",
"TARGET = 'so_luong'\n",
"drop_cols = [\n",
" TARGET, # target\n",
" 'ma_dia_diem', # ID\n",
" 'all_task_normal', # text thô (đã extract thành features)\n",
" 'all_task_dinhky', # text thô (đã extract thành features)\n",
" 'bat_dau', # raw time string (cần parse nếu dùng)\n",
" 'ket_thuc', # raw time string (cần parse nếu dùng)\n",
" 'tong_gio_lam' # raw string (cần parse nếu dùng)\n",
"]\n",
"\n",
"X = df.drop(columns=[c for c in drop_cols if c in df.columns])\n",
"y = df[TARGET]\n",
"\n",
"# Handle categorical\n",
"if 'loai_ca' in X.columns:\n",
" X['loai_ca'] = X['loai_ca'].astype('category').cat.codes\n",
"\n",
"# Ensure numeric\n",
"X = X.apply(pd.to_numeric, errors='coerce').fillna(0)\n",
"\n",
"print(f\"X shape: {X.shape}\") # (302, ~35)\n",
"print(f\"y shape: {y.shape}\") # (302,)\n",
"```\n",
"\n",
"### Check medical vs office:\n",
"```python\n",
"# Phân loại tòa nhà\n",
"df['is_hospital'] = (df['num_medical_tasks_total'] > 0).astype(int)\n",
"df['is_office'] = ((df['num_medical_tasks_total'] == 0) & \n",
" (df['num_indoor_room_tasks'] > 0)).astype(int)\n",
"\n",
"print(\"\\n📊 Phân loại tòa nhà:\")\n",
"print(f\" Bệnh viện: {df['is_hospital'].sum()} tòa\")\n",
"print(f\" Văn phòng: {df['is_office'].sum()} tòa\")\n",
"print(f\" Khác: {len(df) - df['is_hospital'].sum() - df['is_office'].sum()} tòa\")\n",
"\n",
"# So sánh số nhân sự\n",
"print(\"\\n👥 Số nhân sự trung bình:\")\n",
"print(f\" Bệnh viện: {df[df['is_hospital']==1]['so_luong'].mean():.1f} người\")\n",
"print(f\" Văn phòng: {df[df['is_office']==1]['so_luong'].mean():.1f} người\")\n",
"```"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}