{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# 期末专题：Store Sales 销量预测挑战赛\n# 组员1：周文璇（2025416030133）\n# 组员2：李沛琳（2025416030110）\n# 组员3：王嘉瑶（2025416030120）\n# 团队Kaggle主页链接：https://www.kaggle.com/competitions/store-sales-time-series-forecasting/team","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-15T15:48:50.420749Z","iopub.execute_input":"2026-06-15T15:48:50.421061Z","iopub.status.idle":"2026-06-15T15:48:50.437474Z","shell.execute_reply.started":"2026-06-15T15:48:50.421031Z","shell.execute_reply":"2026-06-15T15:48:50.436404Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport os\n\n# 固定正确路径\nbase_path = \"/kaggle/input/competitions/store-sales-time-series-forecasting\"\n\n# 读取全部数据集\ntrain = pd.read_csv(f\"{base_path}/train.csv\", parse_dates=[\"date\"])\ntest = pd.read_csv(f\"{base_path}/test.csv\", parse_dates=[\"date\"])\noil[\"dcoilwtico\"] = oil[\"dcoilwtico\"].ffill()\nstores = pd.read_csv(f\"{base_path}/stores.csv\")\nholidays = pd.read_csv(f\"{base_path}/holidays_events.csv\", parse_dates=[\"date\"])\ntrans = pd.read_csv(f\"{base_path}/transactions.csv\", parse_dates=[\"date\"])\nsample_sub = pd.read_csv(f\"{base_path}/sample_submission.csv\")\n\n# 油价缺失值前向填充\noil[\"dcoilwtico\"] = oil[\"dcoilwtico\"].fillna(method=\"pad\")\n\n# 打印验证是否读取成功\nprint(\"训练集行数：\", train.shape[0])\nprint(\"测试集行数：\", test.shape[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-15T15:48:53.037755Z","iopub.execute_input":"2026-06-15T15:48:53.03814Z","iopub.status.idle":"2026-06-15T15:48:55.383912Z","shell.execute_reply.started":"2026-06-15T15:48:53.038107Z","shell.execute_reply":"2026-06-15T15:48:55.382768Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 构造时间特征：年月、星期、周末、发薪日、地震标记\ndef create_time_feature(df):\n    df[\"year\"] = df[\"date\"].dt.year\n    df[\"month\"] = df[\"date\"].dt.month\n    df[\"day\"] = df[\"date\"].dt.day\n    df[\"weekday\"] = df[\"date\"].dt.weekday\n    df[\"is_weekend\"] = np.where(df[\"weekday\"] >= 5, 1, 0)\n    # 每月15号、月底为发薪日\n    df[\"is_payday\"] = np.where((df[\"day\"] == 15) | (df[\"date\"].dt.is_month_end), 1, 0)\n    # 2016地震区间标记\n    df[\"is_earthquake\"] = np.where((df[\"date\"] >= \"2016-04-16\") & (df[\"date\"] <= \"2016-06-01\"), 1, 0)\n    return df\n\n# 给训练、测试集统一生成时间特征\ntrain = create_time_feature(train)\ntest = create_time_feature(test)\n\n# 油价7日滚动均值特征\noil[\"oil_7roll\"] = oil[\"dcoilwtico\"].rolling(window=7).mean().ffill()\n\n# 关联油价、门店信息到主数据集\ntrain = train.merge(oil[[\"date\", \"dcoilwtico\", \"oil_7roll\"]], on=\"date\", how=\"left\")\ntrain = train.merge(stores, on=\"store_nbr\", how=\"left\")\ntest = test.merge(oil[[\"date\", \"dcoilwtico\", \"oil_7roll\"]], on=\"date\", how=\"left\")\ntest = test.merge(stores, on=\"store_nbr\", how=\"left\")\n\n# 类别文本编码为数字\ncate_cols = [\"family\", \"city\", \"state\", \"type\", \"cluster\"]\nfor col in cate_cols:\n    train[col] = train[col].astype(\"category\").cat.codes\n    test[col] = test[col].astype(\"category\").cat.codes\n\nprint(\"全部特征构造完成\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-15T15:49:21.236892Z","iopub.execute_input":"2026-06-15T15:49:21.237323Z","iopub.status.idle":"2026-06-15T15:49:22.3783Z","shell.execute_reply.started":"2026-06-15T15:49:21.237289Z","shell.execute_reply":"2026-06-15T15:49:22.37689Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 测试集预测销量\nX_test = test[feature_cols]\ntest[\"sales\"] = model.predict(X_test, num_iteration=model.best_iteration_)\n\n# 生成比赛标准上传csv\nsub = sample_sub.copy()\nsub[\"sales\"] = test[\"sales\"]\nsub.to_csv(\"/kaggle/working/submission.csv\", index=False)\n\nprint(\"✅ 提交文件生成完成，路径：/kaggle/working/submission.csv\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# 全门店每日平均销量时序趋势图\nplt.figure(figsize=(12,4))\ntrain.groupby(\"date\")[\"sales\"].mean().plot()\nplt.title(\"Average Daily Sales Trend of All Stores\")\nplt.xlabel(\"Date\")\nplt.ylabel(\"Average Sales Volume\")\nplt.show()\n\n# 油价与销量相关性散点图\nplt.figure(figsize=(8,4))\nplt.scatter(train[\"dcoilwtico\"], train[\"sales\"], alpha=0.2)\nplt.xlabel(\"Crude Oil Price\")\nplt.ylabel(\"Sales Volume\")\nplt.title(\"Correlation Between Oil Price and Sales\")\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}