{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"colab":{"provenance":[],"toc_visible":true},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":103436,"databundleVersionId":12476472,"sourceType":"competition"}],"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nimport category_encoders as ce\nfrom sklearn.preprocessing import LabelEncoder\nfrom category_encoders import TargetEncoder\nfrom lightgbm import LGBMClassifier\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score\nfrom sklearn.model_selection import cross_val_score","metadata":{"id":"FETSRjNwEA6-"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Load data","metadata":{"id":"fM22-XMZFQoD"}},{"cell_type":"code","source":"# delay\ndata_delay_4_6 = pd.read_csv('/delay_4_6_CONDITION_PRODUCT_SUPPLIER.csv')\ndata_delay_7_9 = pd.read_csv('/delay_7_9_CONDITION_PRODUCT_SUPPLIER.csv')\n\n# not delay\ndata_not_delay_4_6 = pd.read_csv('/not_delay_4_6_CONDITION_PRODUCT_SUPPLIER.csv')\ndata_not_delay_7_9 = pd.read_csv('/not_delay_7_9_CONDITION_PRODUCT_SUPPLIER.csv')\n\n# test data\ndata_10 = pd.read_csv('/PILOT_10.csv')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Shape of delay 4_6: ', data_delay_4_6.shape)\nprint('Shape of delay 7_9: ', data_delay_7_9.shape)\nprint('Shape of not delay 4_6: ', data_not_delay_4_6.shape)\nprint('Shape of not delay 7_9: ', data_not_delay_7_9.shape)","metadata":{"id":"z0w8qHRcydQE","outputId":"451bb4a4-f272-413f-bda4-69ffcb371d6d"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merge data 4_6\nfull_data_4_6 = pd.concat([data_delay_4_6, data_not_delay_4_6], ignore_index=True)\nfull_data_4_6 = full_data_4_6.sample(frac=1).drop_duplicates().reset_index()\n\n# merge data 7_9\nfull_data_7_9 = pd.concat([data_delay_7_9, data_not_delay_7_9], ignore_index=True)\nfull_data_7_9 = full_data_7_9.sample(frac=1).drop_duplicates().reset_index()","metadata":{"id":"OIyP7GnSFdBv"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Lọc thuộc tính hữu ích","metadata":{"id":"WAtnro-9I0lY"}},{"cell_type":"code","source":"useful_features = ['Order date', 'SO QTY', 'SO_TIME', 'SO_DAY_OF_MONTH', 'SO_DAY_OF_WEEK',\n                'WEIGHT PER PIECE',\n                'SUPPLIER_CD','SUPPLIER INV AMOUNT','SUPPLIER_DIV','VSD','Ship Mode',\n                'DELI_DIV', 'Stock class','PACKING RANK','label']\n\nuseful_features1 = ['Order date', 'SO QTY', 'SO_TIME', 'SO_DAY_OF_MONTH', 'SO_DAY_OF_WEEK',\n                'WEIGHT PER PIECE',\n                'SUPPLIER_CD','SUPPLIER INV AMOUNT','SUPPLIER_DIV','VSD','Ship Mode',\n                'DELI_DIV', 'Stock class','PACKING RANK']","metadata":{"id":"ZL4gG3H_Flm4"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Lọc các thuộc tính useful cho tập data\nfull_data_4_6 = full_data_4_6[useful_features]\nfull_data_7_9 = full_data_7_9[useful_features]\n\nfull_data = pd.concat([full_data_4_6, full_data_7_9], ignore_index=True)\ndata_10 = data_10[useful_features1]","metadata":{"id":"mOowMY29FmJN"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Xử lý missing value","metadata":{"id":"fLy7j0FnI33C"}},{"cell_type":"code","source":"full_data = full_data.replace(r'^\\s*$', np.nan, regex=True)\ndata_10 = data_10.replace(r'^\\s*$', np.nan, regex=True)\n\n# train\nfull_data = full_data.dropna(subset=['SUPPLIER_DIV','Ship Mode'])\n\n# test\ndata_10['Ship Mode'] = data_10['Ship Mode'].fillna(data_10['Ship Mode'].mode()[0])\ndata_10['SUPPLIER_DIV'] = data_10['SUPPLIER_DIV'].fillna(data_10['SUPPLIER_DIV'].mode()[0])","metadata":{"id":"CY6rddTeHlQH"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_10.info()","metadata":{"id":"ru55pVpIqZZ5","outputId":"e99e4a0c-370b-4fe5-a284-f7cc155bf18e"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Ép kiểu","metadata":{"id":"_aXRQXHGMq95"}},{"cell_type":"code","source":"def constrain_numeric_type(data):\n    convert_dict = {\n        'SO QTY' : int,\n        'SUPPLIER INV AMOUNT' : int,\n        #'label' : 'category',\n        'WEIGHT PER PIECE'  : int,\n        'SUPPLIER_DIV'  : int,\n        'SO_DAY_OF_MONTH' : int,\n        'SO_DAY_OF_WEEK' : int,\n        'SO_TIME' : int\n      }\n    data_constrain_value = data.astype(convert_dict)\n    data_constrain_value.info()\n    return data_constrain_value\n\nfull_data = constrain_numeric_type(full_data)\nfull_data['label'] = full_data['label'].astype(int)\n\ndata_10 = constrain_numeric_type(data_10)","metadata":{"id":"4v-GocqkqKOZ","outputId":"a8228c5d-6d60-422d-a0c3-fe8a97623ba0"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def constrain_type(data):\n    convert_dict = {\n        'Order date': 'datetime64[ns]',\n        'SUPPLIER_CD': 'category',\n        'Stock class':'category',\n        'SO QTY' : 'int32',\n        'SUPPLIER INV AMOUNT' : 'float32',\n        'PACKING RANK' : 'category',\n        'VSD' : 'datetime64[ns]',\n        'DELI_DIV' : 'category',\n        #'label' : 'category',\n        'Ship Mode' : 'category',\n        'WEIGHT PER PIECE'  : 'float32',\n        'SUPPLIER_DIV'  : 'category',\n        'SO_DAY_OF_MONTH' : 'int32',\n        'SO_DAY_OF_WEEK' : 'int32',\n        'SO_TIME' : 'int32',\n      }\n    data_constrain_value = data.astype(convert_dict)\n    data_constrain_value.info()\n    return data_constrain_value\n\nfull_data = constrain_type(full_data)\nfull_data['label'] = full_data['label'].astype('category')\n\ndata_10 = constrain_type(data_10)","metadata":{"id":"QtXsyys7z0ke","outputId":"c5b71460-c471-44be-a2d3-a6e0c04cd910"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"encoder = TargetEncoder(cols='SUPPLIER_CD')\nfull_data['SUPPLIER_CD'] = encoder.fit_transform(full_data['SUPPLIER_CD'], full_data['label'])\ndata_10['SUPPLIER_CD'] = encoder.transform(data_10['SUPPLIER_CD'])","metadata":{"id":"rYMAJ5g1YQg7"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data engineer","metadata":{"id":"VlqZvwTqV9Kw"}},{"cell_type":"code","source":"# chỉnh sửa, tạo đặc trưng cho data\ndef feature_engineer(data):\n\n    feature_date = ['Order date', 'VSD']\n\n    # Tạo đặc trưng khoảng cách ngày nhận\n    data['day_range'] = (pd.to_datetime(data['VSD']) - pd.to_datetime(data['Order date'])).dt.days\n\n    # Tạo đặc trưng ngày, tháng, năm\n    data['WAITING_DAY'] = pd.to_datetime(data['day_range']).dt.day\n    data['SO_MONTH'] = pd.to_datetime(data['Order date']).dt.month\n\n    # Loại bỏ những cột không còn cần thiết\n    data = data.drop(feature_date, axis=1)\n\n    return data","metadata":{"id":"9D_jVJCtV-lr"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"full_data = feature_engineer(full_data)\ndata_10 = feature_engineer(data_10)","metadata":{"id":"8vYyGwxfWrcq"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Split data","metadata":{"id":"tDqMAppTXjFL"}},{"cell_type":"code","source":"X = full_data.drop('label', axis=1)\ny = full_data['label']\n\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n\nprint('Shape of X_train (full_data): ', X_train.shape)\nprint('Shape of X_test (full_data): ', X_test.shape)\n\nprint('Shape of data_10: ', data_10.shape)","metadata":{"id":"QQKgHvB-XkCS","outputId":"ad8d6591-d53c-4bad-809c-950c86b0cda7"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model","metadata":{"id":"zQteQg08Xm16"}},{"cell_type":"code","source":"model_lgb = LGBMClassifier(n_estimators=1220, learning_rate=0.15, num_leaves=200, min_child_samples=90,\n                           objective='binary', subsample=0.9, colsample_bytree=0.85, reg_lambda=0.02,\n                           metric='binary_logloss', random_state=42, is_unbalance=True, max_depth=10\n                           )\n\n# model_rf = RandomForestClassifier()\n\n# model_cb = CatBoostClassifier(cat_features=categorical_features)","metadata":{"id":"93VP0MrcXmZx"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_lgb.fit(X_train, y_train)\nlgb_pred = model_lgb.predict(X_test)\n\n# model_rf.fit(X_train, y_train)\n# rf_pred = model_rf.predict(X_test)\n\n# model_cb.fit(X_train, y_train)\n# cb_pred = model_cb.predict(X_test)","metadata":{"id":"kBufftKvY4Sx","outputId":"4c9b5c27-4109-4292-ca2a-03e539b731a8"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Đánh giá accuracy, f1 score","metadata":{"id":"j-GQ8XOpY_gg"}},{"cell_type":"code","source":"# Hàm tính toán và in ra kết quả\ndef result(y_pred, y_test):\n    accuracy = accuracy_score(y_test, y_pred)\n    precision = precision_score(y_test, y_pred)\n    recall = recall_score(y_test, y_pred)\n    f1 = f1_score(y_test, y_pred)\n\n    print(\"Accuracy:\", accuracy)\n    print(\"Precision:\", precision)\n    print(\"Recall:\", recall)\n    print(\"F1 Score:\", f1)\n\n    return accuracy, f1\n\n# In kết quả từng mô hình\n# print(\"Logistic Regression:\")\n# lr_result = result(lr_pred, y_test)\n# print('*' * 100)\n\nprint(\"LightGBM:\")\nlgb_result = result(lgb_pred, y_test)\nprint('*' * 100)\n\n# print(\"Random Forest:\")\n# rf_result = result(rf_pred, y_test)\n# print('*' * 100)\n\n# # print(\"Decision Tree:\")\n# # dt_result = result(dt_pred, y_test)\n# # print('*' * 100)\n\n# # print(\"Naive Bayes:\")\n# # nb_result = result(nb_pred, y_test)\n# # print('*' * 100)\n\n# print(\"CatBoost:\")\n# cb_result = result(cb_pred, y_test)\n# print('*' * 100)\n\n# # Vẽ biểu đồ trực quan accuracy và f1 score của từng mô hình\n# models = ['LightGBM', 'RandomForest', 'CatBoost']\n# accuracy_scores = [lgb_result[0], rf_result[0], cb_result[0]]\n# f1_scores = [lgb_result[1], rf_result[1], cb_result[1]]\n\n# ind = np.arange(len(models))\n# width = 0.35\n\n# fig, ax = plt.subplots(figsize=(8, 6))\n# rects1 = ax.bar(ind - width/2, accuracy_scores, width, label='Accuracy')\n# rects2 = ax.bar(ind + width/2, f1_scores, width, label='F1 Score')\n\n\n# ax.set_ylabel('Scores')\n# ax.set_title('Accuracy và F1 Score của các mô hình')\n# ax.set_xticks(ind)\n# ax.set_xticklabels(models)\n# ax.set_ylim(0, 1.2)\n# ax.legend()\n# ax.bar_label(rects1, fmt='%.2f', padding=3)\n# ax.bar_label(rects2, fmt='%.2f', padding=3)\n\n# plt.tight_layout()\n# plt.show()","metadata":{"id":"dtb9xBeZY_87","outputId":"f0e47bb2-106a-41c7-f77b-e411f1d9518d"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Predict","metadata":{"id":"t8FwhfJ_ZTcq"}},{"cell_type":"code","source":"best_model_lgb = LGBMClassifier(n_estimators=1220, learning_rate=0.15, num_leaves=200, min_child_samples=90,\n                           objective='binary', subsample=0.9, colsample_bytree=0.85, reg_lambda=0.02,\n                           metric='binary_logloss', random_state=42, is_unbalance=True, max_depth=10\n                           )\n\n# Huấn luyện lại mô hình Random Forest với bộ siêu tham số tốt nhất trên toàn bộ tập dữ liệu X và y\nbest_model_lgb.fit(X, y)","metadata":{"id":"MPw2uCM2bmnv","outputId":"b639836e-441d-4099-cc98-ce5d2c0cf779"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Dự đoán trên data_10 bằng mô hình đã huấn luyện lại\nresult = best_model_lgb.predict(df_test_encoded)\nlen(result)","metadata":{"id":"rOfq2SHiuSbR","outputId":"33abce70-521e-4204-f0ea-802feaf6abb1"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# xuất kết quả ra file result\nresult = pd.DataFrame({\n    'ID': range(1, len(result) + 1),\n    'label': result\n})\n\nresult.to_csv('lgb.csv', index=False)","metadata":{"id":"23qx_1S8y782"},"outputs":[],"execution_count":null}]}