{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.12"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"databundleVersionId":46665,"isSourceIdPinned":false,"sourceId":4117,"sourceType":"competition"},{"databundleVersionId":16635023,"datasetId":10054120,"sourceId":15696207,"sourceType":"datasetVersion"}],"dockerImageVersionId":31329,"isGpuEnabled":true,"isInternetEnabled":true,"language":"python","sourceType":"notebook"},"papermill":{"default_parameters":{},"duration":6.525119,"end_time":"2026-04-12T16:52:40.479133+00:00","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2026-04-12T16:52:33.954014+00:00","version":"2.7.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"1e7dd852","cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import log_loss\n\n# ==========================================\n# CẤU HÌNH ĐƯỜNG DẪN\n# ==========================================\nOUT_DIR = '/kaggle/input/datasets/huylhn1810/linear-stacking-dataset'\n\n# Tự động dò đường dẫn file submission mẫu để lấy cột Id\npath_1 = '/kaggle/input/competitions/malware-classification/sampleSubmission.csv'\npath_2 = '/kaggle/input/malware-classification/sampleSubmission.csv'\nSUBMISSION_CSV = path_1 if os.path.exists(path_1) else path_2\n\nprint(\"=\"*50)\nprint(\"BẮT ĐẦU FUSE BẰNG LOGISTIC REGRESSION\")\nprint(\"=\"*50)\n\n# 1. TẢI DỮ LIỆU ĐÃ LƯU TỪ CÁC BƯỚC TRƯỚC\nprint(\"Đang tải dữ liệu Meta-features (Probabilities)...\")\n# Nhãn tập Train\ny_train = np.load(os.path.join(OUT_DIR, 'y_train.npy'))\n\n# Output của phương pháp ML ban đầu (Tree-based Level-0)\nML_train_probs = np.load(os.path.join(\"/kaggle/input/datasets/huylhn1810/linear-stacking-dataset\", 'X_train_level1.npy'))\nML_test_probs = np.load(os.path.join(\"/kaggle/input/datasets/huylhn1810/linear-stacking-dataset\", 'X_test_level1.npy'))\n\n# Output của phương pháp Deep Learning (Swin + ResNet)\nDL_train_probs = np.load(os.path.join(\"/kaggle/input/datasets/huylhn1810/linear-stacking-dataset\", 'DL_train_probs.npy'))\nDL_test_probs = np.load(os.path.join(\"/kaggle/input/datasets/huylhn1810/linear-stacking-dataset\", 'DL_test_probs.npy'))\n\n# 2. GHÉP NỐI ĐẶC TRƯNG (FUSION)\nprint(\"Đang nối xác suất của ML và DL...\")\nX_train_fusion = np.hstack([ML_train_probs, DL_train_probs])\nX_test_fusion = np.hstack([ML_test_probs, DL_test_probs])\n\nprint(f\"-> Kích thước tập Train Fusion: {X_train_fusion.shape}\")\nprint(f\"-> Kích thước tập Test Fusion: {X_test_fusion.shape}\")\n\n# 3. HUẤN LUYỆN LOGISTIC REGRESSION\nprint(\"\\nĐang huấn luyện Logistic Regression làm Meta-Learner...\")\n# max_iter=2000 để đảm bảo mô hình hội tụ tốt\nmeta_logreg = LogisticRegression(\n    multi_class='multinomial', \n    solver='lbfgs', \n    max_iter=2000, \n    C=1.0, # Tham số chuẩn hóa, có thể tinh chỉnh (0.1, 1.0, 10.0)\n    random_state=42\n)\n\nmeta_logreg.fit(X_train_fusion, y_train)\n\n# Đánh giá nhanh LogLoss trên tập Train (chỉ để tham khảo)\ntrain_preds = meta_logreg.predict_proba(X_train_fusion)\ntrain_logloss = log_loss(y_train, train_preds)\nprint(f\"✅ Hoàn tất Train! LogLoss trên tập Train: {train_logloss:.5f}\")\n\n# 4. CHẠY DỰ ĐOÁN TRÊN TẬP TEST\nprint(\"\\nĐang dự đoán xác suất cuối cùng trên tập Test...\")\nfinal_probabilities = meta_logreg.predict_proba(X_test_fusion)\n\n# 5. XUẤT FILE SUBMISSION\nprint(\"Đang tạo file Submit chuẩn định dạng Kaggle...\")\nsub_df = pd.read_csv(SUBMISSION_CSV)\ntest_ids = sub_df['Id'].tolist()\n\n# Đảm bảo số lượng dòng khớp nhau\nif len(test_ids) != final_probabilities.shape[0]:\n    raise ValueError(f\"Lỗi: Số lượng ID ({len(test_ids)}) không khớp số dòng dự đoán ({final_probabilities.shape[0]})!\")\n\n# Tạo DataFrame với 9 cột Prediction\ncol_names = [f'Prediction{i}' for i in range(1, 10)]\nsubmission = pd.DataFrame(final_probabilities, columns=col_names)\nsubmission.insert(0, 'Id', test_ids)\n\n# Lưu file CSV\nsub_filename = '/kaggle/working/submission_logreg_fusion.csv'\nsubmission.to_csv(sub_filename, index=False)\n\nprint(f\"\\n🎉 HOÀN TẤT! File submit đã được lưu tại: {sub_filename}\")\nprint(\"Hãy tải file này về hoặc submit trực tiếp lên cuộc thi!\")","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2026-04-12T16:52:36.690683Z","iopub.status.busy":"2026-04-12T16:52:36.690329Z","iopub.status.idle":"2026-04-12T16:52:39.957051Z","shell.execute_reply":"2026-04-12T16:52:39.955950Z"},"papermill":{"duration":3.27234,"end_time":"2026-04-12T16:52:39.958962+00:00","exception":false,"start_time":"2026-04-12T16:52:36.686622+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}