{"metadata":{"kernelspec":{"language":"python","name":"python3","display_name":"Python 3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"name":"python","pygments_lexer":"ipython3","mimetype":"text/x-python","file_extension":".py","version":"3.6.3","nbconvert_exporter":"python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":7391,"databundleVersionId":44328,"sourceType":"competition"},{"sourceId":7277963,"sourceType":"datasetVersion","datasetId":4219617},{"sourceId":7278003,"sourceType":"datasetVersion","datasetId":4219650},{"sourceId":7284090,"sourceType":"datasetVersion","datasetId":4223758}],"dockerImageVersionId":33,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **WORK IN PROGRESS**\n\n- To reduce the database in order to avoid any crash from the Kernel, we will select the 10 most frequent products in the train data base.\n**为了减少数据库以避免内核崩溃，我们将在训练数据库中选择10个最常见的产品。**","metadata":{"_uuid":"efa14b2ddf9cd56eb7a2d4950d9e0122be56827a","_cell_guid":"23de8d51-b15b-48bc-b359-5c3e734e9f11"}},{"cell_type":"code","source":"# 导入一些常用的数据分析和可视化工具库\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom scipy.stats import itemfreq\nimport seaborn as sns\nfrom sklearn.model_selection import train_test_split\n%matplotlib inline\n\nimport datetime\nfrom datetime import date, timedelta","metadata":{"_uuid":"ab46f472418091c00d924254f3bf4d638e0e804e","_cell_guid":"0dc94141-6d73-4e7f-9ddd-c797cc9ff18c","execution":{"iopub.status.busy":"2024-01-02T11:23:54.835824Z","iopub.execute_input":"2024-01-02T11:23:54.836448Z","iopub.status.idle":"2024-01-02T11:23:54.844123Z","shell.execute_reply.started":"2024-01-02T11:23:54.836390Z","shell.execute_reply":"2024-01-02T11:23:54.843451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 列出 \"/kaggle/input\" 目录下的所有文件名和文件夹名\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2024-01-02T11:23:58.110089Z","iopub.execute_input":"2024-01-02T11:23:58.110763Z","iopub.status.idle":"2024-01-02T11:23:58.135215Z","shell.execute_reply.started":"2024-01-02T11:23:58.110701Z","shell.execute_reply":"2024-01-02T11:23:58.134526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Preparation & Initial Study**\n\n## 0. Load the Data\n\nLet's use a part of the code from [inversion's Kernel](https://www.kaggle.com/inversion/dataframe-with-all-date-store-item-combinations).","metadata":{"_uuid":"a14b76823df87a6c14c32f63d7a995ff90233cfe","_cell_guid":"507d45a7-f1ea-4367-b8bb-f166cb0351cf"}},{"cell_type":"code","source":"# 载入数据\ndtypes = {'store_nbr': np.dtype('int64'),\n          'item_nbr': np.dtype('int64'),\n          'unit_sales': np.dtype('float64'),\n          'onpromotion': np.dtype('O')}\n\ntrain = pd.read_csv('../input/favorita-grocery-sales-forecasting3/train.csv', dtype=dtypes)\ntest = pd.read_csv('../input/d/wangfanya/favorita-grocery-sales-forecasting/test.csv', dtype=dtypes)\nstores = pd.read_csv('../input/d/wangfanya/favorita-grocery-sales-forecasting/stores.csv')\nitems = pd.read_csv('../input/d/wangfanya/favorita-grocery-sales-forecasting/items.csv')\ntrans = pd.read_csv('../input/favorita-grocery-sales-forecasting1/transactions.csv')\n#oil = pd.read_csv('../input/oil.csv') #we upload this database later\nholidays = pd.read_csv('../input/d/wangfanya/favorita-grocery-sales-forecasting/holidays_events.csv')","metadata":{"_uuid":"289bc3fd5e48aa096abc4789d0476302e9b9632a","_cell_guid":"5c377747-bed6-402b-8705-d3c0baac678a","execution":{"iopub.status.busy":"2024-01-02T11:24:00.947573Z","iopub.execute_input":"2024-01-02T11:24:00.948307Z","iopub.status.idle":"2024-01-02T11:26:15.999867Z","shell.execute_reply.started":"2024-01-02T11:24:00.948242Z","shell.execute_reply":"2024-01-02T11:26:15.999090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 创建了一个布尔掩码date_mask，用于筛选出日期在'2017-07-15'到'2017-08-15'之间的数据。\n# 然后，根据这个掩码，从train数据框中选择了符合条件的子集，并将结果存储在名为pd_train的新数据框中。\ndate_mask = (train['date'] >= '2017-07-15') & (train['date'] <= '2017-08-15')\npd_train = train[date_mask]\n\n# 打印出pd_train的长度，即符合条件的数据的数量\nlen(pd_train)","metadata":{"_uuid":"2810c2bc6b1d2f2dd2205a7c4388c1a587b0bcc5","_cell_guid":"97b53b08-53f9-4661-8177-0c84284c1a03","execution":{"iopub.status.busy":"2024-01-02T11:26:25.438330Z","iopub.execute_input":"2024-01-02T11:26:25.438949Z","iopub.status.idle":"2024-01-02T11:26:47.176201Z","shell.execute_reply.started":"2024-01-02T11:26:25.438892Z","shell.execute_reply":"2024-01-02T11:26:47.175504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 1. Feature engineering（特征工程）\n**替换缺失值** \n\n- 我们可以观察到在油价数据库中存在一些缺失值.\n","metadata":{"_uuid":"fe55c4746b0f407d180b61fe07dd3f4908337fc8","_cell_guid":"a41298a2-10c8-4575-a45c-2c20c28525c2"}},{"cell_type":"code","source":"# 载入oil数据\noil = pd.read_csv('../input/d/wangfanya/favorita-grocery-sales-forecasting/oil.csv')\n\n#add missing date\nmin_oil_date = min(pd_train.date)\nmax_oil_date = max(pd_train.date)\n\ncalendar = []\n\nd1 = datetime.datetime.strptime(min_oil_date, '%Y-%m-%d')  # start date date(2008, 8, 15)\nd2 = datetime.datetime.strptime(max_oil_date, '%Y-%m-%d')  # end date\n\ndelta = d2 - d1         # timedelta\n\nfor i in range(delta.days + 1):\n    calendar.append(datetime.date.strftime(d1 + timedelta(days=i), '%Y-%m-%d'))\n\ncalendar = pd.DataFrame({'date':calendar})\n\noil = calendar.merge(oil, left_on='date', right_on='date', how='left')","metadata":{"_uuid":"522b904785e4159801287e785366728d66b2c26c","_cell_guid":"1714fafd-c758-4281-9923-49ccc5dbf3f4","execution":{"iopub.status.busy":"2024-01-02T11:27:10.610653Z","iopub.execute_input":"2024-01-02T11:27:10.611190Z","iopub.status.idle":"2024-01-02T11:27:10.936170Z","shell.execute_reply.started":"2024-01-02T11:27:10.611136Z","shell.execute_reply":"2024-01-02T11:27:10.935510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**通过比较pd_train数据框中的最小日期和最大日期，确定了需要添加的缺失日期范围。然后，创建一个空列表calendar来存储这些日期。\n使用datetime.datetime.strptime函数将最小日期和最大日期转换为datetime类型。之后，计算出日期范围的时间差，并使用循环将每一天的日期添加到calendar列表中。\n最后，将calendar列表转换为数据框并命名为calendar，然后使用merge函数将calendar和oil数据框按照\"date\"列进行左连接（left join）操作，以添加缺失的日期到oil数据框中**。","metadata":{}},{"cell_type":"code","source":"# 计算了每列缺失值的数量\nprint(oil.isnull().sum(), '\\n')\n\n# 使用dtypes属性获得了每列的数据类型\nprint('Type : ', '\\n', oil.dtypes)\n\n# 使用head()函数输出了oil数据框的前5行\noil.head(5)","metadata":{"_uuid":"63a76a6661adefd0230afd7da8bb7c3948b79589","_cell_guid":"e4e9c514-53f2-4aeb-9aa4-9f004d055453","execution":{"iopub.status.busy":"2024-01-02T11:27:14.103285Z","iopub.execute_input":"2024-01-02T11:27:14.103960Z","iopub.status.idle":"2024-01-02T11:27:14.120913Z","shell.execute_reply.started":"2024-01-02T11:27:14.103902Z","shell.execute_reply":"2024-01-02T11:27:14.120143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**oil数据框中的\"date\"列没有缺失值。\noil数据框中的\"dcoilwtico\"列有10个缺失值。\n此外，数据框中的\"date\"列的数据类型是object，即字符串类型。\n\"dcoilwtico\"列的数据类型是float64，即浮点数类型。**","metadata":{}},{"cell_type":"markdown","source":"**我们将使用以下公式来替换缺失值：** \n\n$$\\frac{(dcoilwtico[t-1] + dcoilwtico[t+1])} {2}$$\n**这个公式会使用缺失值前后两个时间点的值的平均数来替代缺失值。**","metadata":{"_uuid":"225e7e516073e3dfb90a0f2a70958a5a0f61d0a6","_cell_guid":"a23fc595-9bcd-4607-8ee8-546284cbd71b"}},{"cell_type":"code","source":"#Check index to apply the formula\nna_index_oil = oil[oil['dcoilwtico'].isnull() == True].index.values\n\n#Define the index to use to apply the formala\nna_index_oil_plus = na_index_oil.copy()\nna_index_oil_minus = np.maximum(0, na_index_oil-1)\n\nfor i in range(len(na_index_oil)):\n    k = 1\n    while (na_index_oil[min(i+k,len(na_index_oil)-1)] == na_index_oil[i]+k):\n        k += 1\n    na_index_oil_plus[i] = min(len(oil)-1, na_index_oil_plus[i] + k )\n\n#Apply the formula\nfor i in range(len(na_index_oil)):\n    if (na_index_oil[i] == 0):\n        oil.loc[na_index_oil[i], 'dcoilwtico'] = oil.loc[na_index_oil_plus[i], 'dcoilwtico']\n    elif (na_index_oil[i] == len(oil)):\n        oil.loc[na_index_oil[i], 'dcoilwtico'] = oil.loc[na_index_oil_minus[i], 'dcoilwtico']\n    else:\n        oil.loc[na_index_oil[i], 'dcoilwtico'] = (oil.loc[na_index_oil_plus[i], 'dcoilwtico'] + oil.loc[na_index_oil_minus[i], 'dcoilwtico'])/ 2    ","metadata":{"_uuid":"860de56c0162249bf8eefe74b9564e5b3f56a9af","_cell_guid":"7e3b8290-07ff-4c83-8147-d24613052cf2","execution":{"iopub.status.busy":"2024-01-02T11:27:26.382405Z","iopub.execute_input":"2024-01-02T11:27:26.383178Z","iopub.status.idle":"2024-01-02T11:27:26.409154Z","shell.execute_reply.started":"2024-01-02T11:27:26.383097Z","shell.execute_reply":"2024-01-02T11:27:26.408400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**根据之前给出的公式来替换缺失值。\n首先，通过oil['dcoilwtico'].isnull() == True找到含有缺失值的行索引，并将其保存在na_index_oil中。\n接下来，定义了两个索引数组na_index_oil_plus和na_index_oil_minus，用于保存需要使用公式的缺失值所在行的前一个和后一个行索引。\n然后，使用一个循环遍历每个缺失值的行索引，找到连续的缺失值所在的范围。如果连续的缺失值在数据框的最后一行，则将索引限制在数据框的长度减1。\n接着，使用另一个循环遍历每个缺失值的行索引，并根据其位置分别使用前一个和后一个非缺失值进行替换。如果缺失值在数据框的第一行，则使用后一个非缺失值进行替换；如果缺失值在数据框的最后一行，则使用前一个非缺失值进行替换；否则，根据公式计算缺失值的替换值。\n最后，通过修改oil数据框的相应位置，将计算得到的替换值赋给缺失值。**","metadata":{}},{"cell_type":"code","source":"# 将替换缺失值后的油价数据绘制成一张图表\noil_plot = oil['dcoilwtico'].copy()\noil_plot.index = oil['date'].copy()\noil_plot.plot()\nplt.show()","metadata":{"_uuid":"6094db980d5666ccfad050fbbe0ad1de284b1a19","_cell_guid":"907fbbac-488a-463f-be3f-d22ee8060d63","execution":{"iopub.status.busy":"2024-01-02T11:27:29.027393Z","iopub.execute_input":"2024-01-02T11:27:29.028028Z","iopub.status.idle":"2024-01-02T11:27:29.219066Z","shell.execute_reply.started":"2024-01-02T11:27:29.027968Z","shell.execute_reply":"2024-01-02T11:27:29.218387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Merge all the database（合并所有数据库）","metadata":{"_uuid":"5d6b4e51a926f2edd2d5ba4c153c98c4acf57d2a","_cell_guid":"1fc07bfb-7b80-462f-a8a6-2cb451eb19a3"}},{"cell_type":"code","source":"# 将训练数据集中的各个表格进行合并\npd_train = pd_train.drop('id', axis = 1)\npd_train = pd_train.merge(stores, left_on='store_nbr', right_on='store_nbr', how='left')\npd_train = pd_train.merge(items, left_on='item_nbr', right_on='item_nbr', how='left')\npd_train = pd_train.merge(holidays, left_on='date', right_on='date', how='left')\npd_train = pd_train.merge(oil, left_on='date', right_on='date', how='left')\npd_train = pd_train.drop(['description', 'state', 'locale_name', 'class'], axis = 1)","metadata":{"_uuid":"efa0e2ab829c7bcab788f2b170c325e778052c6b","_cell_guid":"fb46b57e-dc11-4c7f-ba1a-5e4e0fb8a213","execution":{"iopub.status.busy":"2024-01-02T11:27:31.904522Z","iopub.execute_input":"2024-01-02T11:27:31.905204Z","iopub.status.idle":"2024-01-02T11:27:36.684973Z","shell.execute_reply.started":"2024-01-02T11:27:31.905144Z","shell.execute_reply":"2024-01-02T11:27:36.684317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**首先，通过pd_train.drop('id', axis = 1)删除了训练数据集中的'id'列，并将其保存在变量pd_train中。\n然后，使用merge()方法将训练数据集分别与'stores'、'items'、'holidays'和'oils'四张表格进行左连接（left join）。这里的左连接意味着以训练数据集为主表格，将其他表格按照对应的列进行合并，而不会丢失训练数据集中的任何行。\n其中，'stores'和'items'表格的合并使用了'store_nbr'和'item_nbr'两列作为连接列；'holidays'和'oils'表格的合并则使用了'date'列作为连接列。合并后的结果保存在变量pd_train中。接着，通过drop()方法删除了合并后数据集中的'description'、'state'、'locale_name'和'class'四列，因为这些列对预测销售量没有贡献。\n最终，经过这一系列合并和删除操作，训练数据集中的所有信息都被整合到了一个表格中，并可以方便地进行特征工程和模型训练。**","metadata":{}},{"cell_type":"markdown","source":"#Merge test - here is the code\ntest = test.drop('id', axis = 1)\ntest = test.merge(stores, left_on='store_nbr', right_on='store_nbr', how='left')\ntest = test.merge(items, left_on='item_nbr', right_on='item_nbr', how='left')\ntest = test.merge(oil, left_on='date', right_on='date', how='left')\ntest = test.merge(holidays, left_on='date', right_on='date', how='left')\ntest = test.drop(['description', 'state', 'locale_name', 'class'], axis = 1)","metadata":{"_uuid":"ee8b1dd30d5da60a45a4d38bf8e4e3d1f3ed3d4d","_cell_guid":"e3acd70c-4823-40e4-9092-e75b7e01db3e"}},{"cell_type":"markdown","source":"## 3. Quick look and modification on the data（数据的快速查看和修改）\n\n### **- 新创建的训练数据集**","metadata":{"_uuid":"49c5b0336e486d356fdc953c3edc71f3b9f92804","_cell_guid":"47f87c5a-8580-47ee-9aa8-67aad1b00f44"}},{"cell_type":"code","source":"# 打印了训练数据集的形状（行数和列数）\nprint('Shape : ', pd_train.shape, '\\n')\n\n# 打印了训练数据集中各列的数据类型\nprint('Type : ', '\\n', pd_train.dtypes)\n\n# 生成数据集的统计摘要，包括计数、均值、标准差、最小值、25%分位数、中位数、75%分位数和最大值\npd_train.describe()","metadata":{"_uuid":"bbb603d929d4061fee812264b599a76e8e21b00c","_cell_guid":"dd6f2914-10ed-479e-b6aa-3607ae1fdd86","scrolled":true,"execution":{"iopub.status.busy":"2024-01-02T11:27:42.585600Z","iopub.execute_input":"2024-01-02T11:27:42.586169Z","iopub.status.idle":"2024-01-02T11:27:43.637344Z","shell.execute_reply.started":"2024-01-02T11:27:42.586116Z","shell.execute_reply":"2024-01-02T11:27:43.636682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 从训练数据集中随机抽取了10行数据进行展示\npd_train.sample(10)","metadata":{"_uuid":"9218ef6bb90189b2163f88fa771ac2c349fce125","_cell_guid":"60871ace-5f4e-4f1d-8bb1-7dc267a4624e","execution":{"iopub.status.busy":"2024-01-02T11:27:48.778632Z","iopub.execute_input":"2024-01-02T11:27:48.779294Z","iopub.status.idle":"2024-01-02T11:27:49.401495Z","shell.execute_reply.started":"2024-01-02T11:27:48.779206Z","shell.execute_reply":"2024-01-02T11:27:49.400549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 绘制了一个柱状图，展示了训练数据集中不同店铺编号（store_nbr）的频数统计\nsns.countplot(x='store_nbr', data=pd_train); ","metadata":{"_uuid":"521e692c54808b5a7f62cb73f18d78adede66c5c","_cell_guid":"c0981dee-a736-4040-9cb9-62ed4df4a6a5","execution":{"iopub.status.busy":"2024-01-02T11:27:53.558387Z","iopub.execute_input":"2024-01-02T11:27:53.559085Z","iopub.status.idle":"2024-01-02T11:27:54.297058Z","shell.execute_reply.started":"2024-01-02T11:27:53.559010Z","shell.execute_reply":"2024-01-02T11:27:54.296313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **- Let's extract only the 10 most purchased product（让我们提取出销售量最高的前10个产品）**","metadata":{"_uuid":"ba5a8f4e97590f757a4599f53f945306929ef3cf","_cell_guid":"67fe482c-5a09-4132-94f9-e92570620ee6"}},{"cell_type":"code","source":"#######Get the N most purchased products########\n# 从给定数据集中提取出销售量最高的前 N 种产品，并筛选出包含这些产品的记录\ndef N_most_labels(data, variable , N , all='TRUE'):\n    labels_freq_pd = itemfreq(data[variable])\n    labels_freq_pd = labels_freq_pd[labels_freq_pd[:, 1].argsort()[::-1]] #[::-1] ==> to sort in descending order\n    \n    if all == 'FALSE':\n        main_labels = labels_freq_pd[:,0][0:N]\n    else: \n        main_labels = labels_freq_pd[:,0][:]\n        \n    labels_raw_np = data[variable].as_matrix() #transform in numpy\n    labels_raw_np = labels_raw_np.reshape(labels_raw_np.shape[0],1)\n\n    labels_filtered_index = np.where(labels_raw_np == main_labels)\n    \n    return labels_freq_pd, labels_filtered_index\n\nlabel_freq, labels_filtered_index = N_most_labels(data = pd_train, variable = \"item_nbr\", N = 10, all='FALSE')\nprint(\"labels_filtered_index[0].shape = \", labels_filtered_index[0].shape)\n\npd_train_filtered = pd_train.loc[labels_filtered_index[0],:]\nprint(\"pd_train_filtered.shape = \", pd_train_filtered.shape)","metadata":{"_uuid":"74c49cb6fad24ee35622f19804a2778dfd4da766","_cell_guid":"e6d54d7e-a042-4fae-9a93-cc74d84ba997","execution":{"iopub.status.busy":"2024-01-02T11:27:56.627496Z","iopub.execute_input":"2024-01-02T11:27:56.628130Z","iopub.status.idle":"2024-01-02T11:27:57.143404Z","shell.execute_reply.started":"2024-01-02T11:27:56.628070Z","shell.execute_reply":"2024-01-02T11:27:57.142469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**labels_filtered_index[0].shape =  (17202,) 表示筛选后的数据集包含了 17202 条记录，而 pd_train_filtered.shape =  (17202, 14) 则表示该数据集共有 14 个变量（即 14 列）**","metadata":{}},{"cell_type":"code","source":"# 输出label_freq变量中前 10 行的数据，即销售量最高的前10种产品以及它们在训练数据集中出现的次数\nlabel_freq[0:10]","metadata":{"_uuid":"c0dc38fcd2c85e6be684c4bd72977fc41d3fbb4f","_cell_guid":"1ec08c1c-35bc-4530-aef8-4c63db2646c8","execution":{"iopub.status.busy":"2024-01-02T11:28:01.348520Z","iopub.execute_input":"2024-01-02T11:28:01.349104Z","iopub.status.idle":"2024-01-02T11:28:01.354572Z","shell.execute_reply.started":"2024-01-02T11:28:01.349042Z","shell.execute_reply":"2024-01-02T11:28:01.353876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**其中，第一列是产品编号，第二列是该产品在训练数据集中出现的次数。可以看到，销售量最高的前 10 种产品的编号分别为：\n[2042947, 502331, 314384, 323013, 364606, 222879, 2042941, 414750, 1162382, 1418845]\n它们在训练数据集中出现的次数依次为：\n[1726, 1724, 1723, 1722, 1722, 1720, 1719, 1716, 1715, 1715]\n可以看到，销售量最高的前两种产品的销售量非常接近，而后面几种产品的销售量则略有下降。**","metadata":{}},{"cell_type":"code","source":"# 对筛选后的数据集pd_train_filtered进行随机抽样的操作，返回3条随机选择的记录\npd_train_filtered.sample(3)","metadata":{"_uuid":"efca604818edc41e90ce49c0d5122ecba993dc7b","_cell_guid":"9e7d07ff-8f75-4e04-8c29-e2a9a4480e81","execution":{"iopub.status.busy":"2024-01-02T11:28:03.979214Z","iopub.execute_input":"2024-01-02T11:28:03.979906Z","iopub.status.idle":"2024-01-02T11:28:04.002994Z","shell.execute_reply.started":"2024-01-02T11:28:03.979827Z","shell.execute_reply":"2024-01-02T11:28:04.002319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **- Replace NA for \"holydays\" variables（将“假日”变量中的缺失值替换为某个特定值）**","metadata":{"_uuid":"c59fcbd075c6efae668507613b503524e4650820","_cell_guid":"f32f094b-63de-427c-802b-97239dad8ae0"}},{"cell_type":"code","source":"# 如果没有假日，则填写单元格值:\"no_holyday\"\nna_index_pd_train = pd_train_filtered[pd_train_filtered['type_y'].isnull() == True].index.values\nprint(\"Size of na_index_pd_train : \", len(na_index_pd_train), '\\n')\n\npd_train_filtered.loc[pd_train_filtered['type_y'].isnull(), 'type_y'] = \"no_holyday\"\npd_train_filtered.loc[pd_train_filtered['locale'].isnull(), 'locale'] = \"no_holyday\"\npd_train_filtered.loc[pd_train_filtered['transferred'].isnull(), 'transferred'] = \"no_holyday\"\n    \n#计算数据集 pd_train_filtered中每个列（变量）中的缺失值数量\npd_train_filtered.isnull().sum()","metadata":{"_uuid":"85c099a04b847ce78e3e9c6c02080af03be91d9e","_cell_guid":"86e24dfb-7fef-45ea-8ae2-86def096c04e","execution":{"iopub.status.busy":"2024-01-02T11:28:06.515264Z","iopub.execute_input":"2024-01-02T11:28:06.515959Z","iopub.status.idle":"2024-01-02T11:28:06.558090Z","shell.execute_reply.started":"2024-01-02T11:28:06.515898Z","shell.execute_reply":"2024-01-02T11:28:06.557479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**根据输出结果，变量 na_index_pd_train 的大小为 0，说明在数据集中没有 type_y 变量的缺失值。另外，根据输出结果，数据集 pd_train_filtered 中的各个列（变量）也没有缺失值。每个变量的缺失值数量都为 0**","metadata":{}},{"cell_type":"markdown","source":"### **- Reformat the date（重新格式化日期）**\n\n**我们将从 \"date\" 变量中提取天、月和年。**","metadata":{"_uuid":"51fc57c13f727982884e835e03393e704d60beec","_cell_guid":"e09f4e86-4613-4436-9f59-d52b6c668ae4"}},{"cell_type":"code","source":"# 定义了一个名为 get_month_year 的函数，该函数用于从日期变量中提取月份和年份\ndef get_month_year(df):\n    df['month'] = df.date.apply(lambda x: x.split('-')[1])\n    df['year'] = df.date.apply(lambda x: x.split('-')[0])\n    \n    return df\n\nget_month_year(pd_train_filtered);","metadata":{"_uuid":"ff10325cabb5eba659e1c3b53b40c0971a2e5c8f","_cell_guid":"f619b819-2026-49c0-ad76-12c2f3613eb7","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 使用 Pandas 中的 pd.to_datetime() 方法将 \"date\" 变量转换为日期格式\npd_train_filtered['date'] = pd.to_datetime(pd_train_filtered['date'])\n# 使用 .dt.weekday_name 方法从 \"date\" 变量中提取出星期几，并将结果保存在新的 \"day\" 列中\npd_train_filtered['day'] = pd_train_filtered['date'].dt.weekday_name\n# 使用 .drop() 方法删除原始的 \"date\" 列，并将更新后的数据框返回\npd_train_filtered = pd_train_filtered.drop('date', axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 查看 pd_train_filtered 数据集中的10个随机样本\npd_train_filtered.sample(10)","metadata":{"_uuid":"70640e56a2235cb239a95cc8007343e2e63bbb5a","_cell_guid":"14cfd785-667f-4354-8357-bbc9f4dcabb2","execution":{"iopub.status.busy":"2024-01-02T11:40:00.027721Z","iopub.execute_input":"2024-01-02T11:40:00.028457Z","iopub.status.idle":"2024-01-02T11:40:00.057110Z","shell.execute_reply.started":"2024-01-02T11:40:00.028395Z","shell.execute_reply":"2024-01-02T11:40:00.056308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Dummy variables（虚拟变量）\n\n**我们将创建二元变量**","metadata":{"_uuid":"849b8714c2205f153601e434af90c26bd6e8b87a","_cell_guid":"7a617138-098b-41d5-9a4a-8f9ce800d92b"}},{"cell_type":"code","source":"dummy_variables = ['onpromotion','city','type_x','cluster','store_nbr','item_nbr',\n                'family','perishable','type_y', 'locale', 'transferred', 'month', 'day']\n\nfor var in dummy_variables:\n    dummy = pd.get_dummies(pd_train_filtered[var], prefix = var, drop_first = False)\n    pd_train_filtered = pd.concat([pd_train_filtered, dummy], axis = 1)\n\npd_train_filtered = pd_train_filtered.drop(dummy_variables, axis = 1)\npd_train_filtered = pd_train_filtered.drop(['year'], axis = 1)","metadata":{"_uuid":"1e1cf808f465f54b8dcacb2ad20398c84832202e","_cell_guid":"96a95bbd-aed4-416d-a22c-09d28f4f2426","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**首先，定义了一个名为 dummy_variables 的列表，其中包含多个需要创建虚拟变量的变量名。\n接下来，使用 for 循环遍历 dummy_variables 列表中的每个变量名，并使用 Pandas 中的 pd.get_dummies() 方法为每个变量名创建虚拟变量。具体地，通过 pd.get_dummies(pd_train_filtered[var], prefix = var, drop_first = False) 的操作，对指定的变量名 var 进行独热编码，并设置前缀为该变量名，并将结果保存在名为 dummy 的新数据框中。\n然后，使用 pd.concat() 方法将原始数据框 pd_train_filtered 和新数据框 dummy 进行合并，并将结果重新赋值给 pd_train_filtered 变量。具体地，通过 pd.concat([pd_train_filtered, dummy], axis = 1) 的操作，将两个数据框按列方向进行合并，并将更新后的数据框重新赋值给 pd_train_filtered 变量。\n接下来，使用 .drop() 方法删除原始的变量和不需要的 \"year\" 列，并将更新后的数据框返回。具体地，通过 pd_train_filtered = pd_train_filtered.drop(dummy_variables, axis = 1) 的操作，删除虚拟变量对应的原始变量，并将更新后的数据框重新赋值给 pd_train_filtered 变量。通过 pd_train_filtered = pd_train_filtered.drop(['year'], axis = 1) 的操作，删除 \"year\" 列，并将更新后的数据框重新赋值给 pd_train_filtered 变量。**","metadata":{}},{"cell_type":"code","source":"# 打印 pd_train_filtered 数据集的行数和列数和随机抽样的10行数据\nprint('Shape : ', pd_train_filtered.shape)\npd_train_filtered.sample(10)","metadata":{"_uuid":"6489ebf5ef1d6ee469b8d121253462da52f9af59","_cell_guid":"cef02c82-b32f-4418-83bf-eccec861c97e","execution":{"iopub.status.busy":"2024-01-02T11:48:57.441433Z","iopub.execute_input":"2024-01-02T11:48:57.442236Z","iopub.status.idle":"2024-01-02T11:48:57.473167Z","shell.execute_reply.started":"2024-01-02T11:48:57.442158Z","shell.execute_reply":"2024-01-02T11:48:57.472493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Scale variables(标准化变量)\n\n**我们可以对变量进行缩放，使它们标准化为均值为0，标准差为1的形式**","metadata":{"_uuid":"110bf34feb9f3328d7ad665d4326e2bdfe6ef5b1","_cell_guid":"d6f1c8c1-672f-4f49-95af-5d3f1f9aeab4"}},{"cell_type":"code","source":"#Re-scale\n#We keep this value to re-scale the predicted unit_sales values in the following lines of code.\n# 获取 pd_train_filtered 数据集中 unit_sales 变量的最小值和最大值，以便在后续代码中重新缩放预测值\nmin_train, max_train = pd_train_filtered['unit_sales'].min(), pd_train_filtered['unit_sales'].max()","metadata":{"_uuid":"7457b262971b7a4c749374d52317c3ecf78b7605","_cell_guid":"9011bd16-73f0-4510-80ea-6d11cdb17c20","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scalable_variables = ['unit_sales','dcoilwtico']\n\nfor var in scalable_variables:\n    mini, maxi = pd_train_filtered[var].min(), pd_train_filtered[var].max()\n    pd_train_filtered.loc[:,var] = (pd_train_filtered[var] - mini) / (maxi - mini)","metadata":{"_uuid":"4bc6e479ce8755b8d2de960ecfcc0c17b680bd5a","_cell_guid":"6ef2f234-4edc-4824-89af-361169e0649a","execution":{"iopub.status.busy":"2024-01-02T11:51:55.301089Z","iopub.execute_input":"2024-01-02T11:51:55.301641Z","iopub.status.idle":"2024-01-02T11:51:55.312715Z","shell.execute_reply.started":"2024-01-02T11:51:55.301567Z","shell.execute_reply":"2024-01-02T11:51:55.311992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**用于对 pd_train_filtered 数据集中的可缩放变量进行重新缩放。\n首先，定义了一个列表 scalable_variables，其中包含了需要进行缩放的变量名，包括 'unit_sales' 和 'dcoilwtico'。\n然后，通过循环遍历 scalable_variables 列表中的每个变量，使用 pd_train_filtered[var].min() 和 pd_train_filtered[var].max() 分别获取该变量的最小值和最大值。\n接下来，使用 (pd_train_filtered[var] - mini) / (maxi - mini) 对该变量进行重新缩放。具体地，对变量的每个值减去最小值，再除以最大值和最小值之差，即可将变量的值范围标准化为 0 到 1 之间。\n最后，使用 pd_train_filtered.loc[:,var] 将重新缩放后的值赋值给原始数据集中的相应变量列，完成对该变量的重新缩放。**","metadata":{}},{"cell_type":"code","source":"# 打印重新缩放后的 pd_train_filtered 数据集的行数和列数和随机抽样的10行数据\nprint('Shape : ', pd_train_filtered.shape)\npd_train_filtered.sample(10)","metadata":{"_uuid":"b23d7fab4b6ecabd0dbccab1db0b42bd945c53a7","_cell_guid":"94e1ff53-ea16-4058-8a9e-cb67a8c3d84c","execution":{"iopub.status.busy":"2024-01-02T11:51:58.365985Z","iopub.execute_input":"2024-01-02T11:51:58.366513Z","iopub.status.idle":"2024-01-02T11:51:58.401804Z","shell.execute_reply.started":"2024-01-02T11:51:58.366461Z","shell.execute_reply":"2024-01-02T11:51:58.400873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Split the data into a train and a validation database(将数据拆分为训练集和验证集)**","metadata":{"_uuid":"a13a34f919715664195da0a9d3638a91abd96804","_cell_guid":"13cdfe7a-c056-4a5a-96dc-7be2cb003698"}},{"cell_type":"code","source":"# 将 pd_train_filtered 数据集中的 'unit_sales' 变量单独作为标签，将其余变量作为特征，然后将数据集分成训练集和验证集\n#train database without uni_sales\npd_train_filtered = pd_train_filtered.reset_index(drop=True)  #we reset the index\ny_labels = pd_train_filtered['unit_sales']\nX_train_filtered = pd_train_filtered.drop(['unit_sales'], axis = 1)\n\nprint('Shape X :', X_train_filtered.shape)\nprint('Shape y :', y_labels.shape)","metadata":{"_uuid":"6deacb4d2fc6500f3cebed2e5bd22ae9d4d60702","_cell_guid":"0616dd0f-3996-41bb-b678-a2358b7f5972","execution":{"iopub.status.busy":"2024-01-02T11:56:44.810659Z","iopub.execute_input":"2024-01-02T11:56:44.811023Z","iopub.status.idle":"2024-01-02T11:56:44.826148Z","shell.execute_reply.started":"2024-01-02T11:56:44.810980Z","shell.execute_reply":"2024-01-02T11:56:44.825381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We split the train database with the function train_test_split (very useful and easy to use function).","metadata":{"_uuid":"ff2656986d3973fbf5389b7b31bec25783e31a21","_cell_guid":"fff998fe-b963-45d0-8f4a-d2964d7cba4b"}},{"cell_type":"code","source":"# 使用了 train_test_split 函数将训练集数据拆分为训练集和验证集，并打印出拆分后的数据集形状\nnum_test = 0.20\nX_train, X_validation, y_train, y_validation = train_test_split(X_train_filtered, y_labels, test_size=num_test, random_state=15)\nprint('X_train shape :', X_train.shape)\nprint('y_train shape :', y_train.shape)\nprint('X_validation shape :', X_validation.shape)\nprint('y_validation shape :', y_validation.shape)","metadata":{"_uuid":"a4372c8ed50c25a064fa350d980f71b292327197","_cell_guid":"5aac0db5-4690-41b7-a3a6-bdf334924972","execution":{"iopub.status.busy":"2024-01-02T11:56:49.127931Z","iopub.execute_input":"2024-01-02T11:56:49.128630Z","iopub.status.idle":"2024-01-02T11:56:49.151292Z","shell.execute_reply.started":"2024-01-02T11:56:49.128563Z","shell.execute_reply":"2024-01-02T11:56:49.150555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**结果显示其中，X_train shape : (13761, 135) 表示训练集特征矩阵 X_train 有 13761 行和 135 列；y_train shape : (13761,) 表示训练集标签向量 y_train 有 13761 行和 1 列；X_validation shape : (3441, 135) 表示验证集特征矩阵 X_validation 有 3441 行和 135 列；y_validation shape : (3441,) 表示验证集标签向量 y_validation 有 3441 行和 1 列。**","metadata":{}},{"cell_type":"markdown","source":"# **Random Forest（随机森林算法）**\n\n**接下来使用随机森林算法来预测销售额。在构建神经网络之前，我们尝试使用随机森林算法进行预测。虽然由于无法在 Kaggle 内核中使用所有数据，结果可能并不理想，但比较不同方法仍然具有一定的参考意义。随机森林是一种集成学习方法，它通过构建多个决策树并对其进行组合来进行预测。**","metadata":{"_uuid":"8135eb2ba55de068e0e798f7ae9f2bd09a6add73","_cell_guid":"82849055-8861-49c9-a5cf-8ebdaa589cf3"}},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestRegressor\nfrom sklearn.model_selection import GridSearchCV\n\n# Choose the type of classifier. \nRFR = RandomForestRegressor()\n\n# Choose some parameter combinations to try\n#YOU CAN TRY DIFFERENTS PARAMETERS TO FIND THE BEST MODEL\nparameters = {'n_estimators': [5, 10, 100],\n              #'criterion': ['mse'],\n              #'max_depth': [5, 10, 15], \n              #'min_samples_split': [2, 5, 10],\n              'min_samples_leaf': [1,5]\n             }\n\n# Type of scoring used to compare parameter combinations\n#We have to use RandomForestRegressor's own scorer (which is R^2 score)\n\n# Run the grid search\ngrid_obj = GridSearchCV(RFR, parameters,\n                        cv=5, #Determines the cross-validation splitting strategy /to specify the number of folds in a (Stratified)KFold\n                        n_jobs=-1, #Number of jobs to run in parallel\n                        verbose=1)\ngrid_obj = grid_obj.fit(X_train, y_train)\n\n# Set the clf to the best combination of parameters\nRFR = grid_obj.best_estimator_\n\n# Fit the best algorithm to the data. \nRFR.fit(X_train, y_train)","metadata":{"_uuid":"9b7a0d7264d666884be14ae4ce2f1227c1942e31","_cell_guid":"6644f639-fed5-4eae-af38-161ea74cf20c","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**使用了 sklearn 库中的 RandomForestRegressor 和 GridSearchCV 类来构建和调优随机森林模型。\n首先，使用 RandomForestRegressor() 初始化了一个随机森林回归模型对象 RFR。\n然后，定义了一个参数字典 parameters，其中包含了一些待尝试的参数组合。你可以根据需要修改和尝试不同的参数组合来寻找最佳模型。\n接下来，通过 GridSearchCV 类进行网格搜索。GridSearchCV 会自动遍历所有参数组合，并使用交叉验证对每个组合进行评估。这里指定了交叉验证的折数为 5 折（cv=5），并且使用所有可用的 CPU 核心进行并行计算（n_jobs=-1），verbose=1 则表示打印出详细的输出信息。\n调用 fit 方法，将训练集数据 X_train 和对应的标签 y_train 传入 grid_obj 进行训练和参数搜索。这将得到最佳参数组合，并保存到 grid_obj.best_estimator_ 中。\n最后，使用最佳参数组合初始化的随机森林回归模型 RFR，并再次使用训练集数据进行拟合。**","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import r2_score\nfrom sklearn.metrics import mean_squared_error\n\npredictions = RFR.predict(X_validation)\n\n#if we want to Re-scale, use this lines of code :\n#predictions = predictions * (max_train - min_train) + min_train\n#y_validation_RF = y_validation * (max_train - min_train) + min_train\n\n#if not, keep this one:\ny_validation_RF = y_validation\n\nprint('R2 score = ',r2_score(y_validation_RF, predictions), '/ 1.0')\nprint('MSE score = ',mean_squared_error(y_validation_RF, predictions), '/ 0.0')","metadata":{"_uuid":"df03e65b25c6ba49fd3ed09039d3f89da06ef935","_cell_guid":"1e11b4f1-348b-4421-82e3-7fdf50915eac","execution":{"iopub.status.busy":"2024-01-02T12:04:45.410541Z","iopub.execute_input":"2024-01-02T12:04:45.411375Z","iopub.status.idle":"2024-01-02T12:04:45.550846Z","shell.execute_reply.started":"2024-01-02T12:04:45.411288Z","shell.execute_reply":"2024-01-02T12:04:45.549840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**使用了 sklearn 库中的 r2_score 和 mean_squared_error 方法，对随机森林模型在验证集上的性能进行评估。\n首先，使用训练好的随机森林模型 RFR 对验证集数据 X_validation 进行预测，并将结果保存在变量 predictions 中。\n接着，如果需要对预测结果进行反向缩放（即恢复到原始数据范围），可以使用注释掉的代码行。其中 max_train 和 min_train 分别是训练集数据的最大值和最小值。\n最后，使用 r2_score 方法计算 R2 分数（拟合优度），使用 mean_squared_error 方法计算均方误差（MSE）得分。这两个指标都是用于评估模型性能的常用指标，其中 R2 分数越接近 1，表示模型拟合效果越好；MSE 得分越接近 0，表示模型预测效果越好。\n总之，这段代码使用了 r2_score 和 mean_squared_error 方法对随机森林模型在验证集上的性能进行评估，并输出 R2 分数和 MSE 得分。**","metadata":{}},{"cell_type":"code","source":"# 使用了 matplotlib.pyplot 库来绘制随机森林模型在前50个样本上的预测结果和实际标签\n#Check and plot the 50 first predictions\nplt.plot(y_validation_RF.as_matrix()[0:50], '+', color ='blue', alpha=0.7)\nplt.plot(predictions[0:50], 'ro', color ='red', alpha=0.5)\nplt.show()","metadata":{"_uuid":"83f105b98f2ac3cda3c571d6ab6f0d93506c970d","_cell_guid":"7231350e-0101-461e-966b-c638671cefac","execution":{"iopub.status.busy":"2024-01-02T12:04:55.790030Z","iopub.execute_input":"2024-01-02T12:04:55.790720Z","iopub.status.idle":"2024-01-02T12:04:55.937216Z","shell.execute_reply.started":"2024-01-02T12:04:55.790628Z","shell.execute_reply":"2024-01-02T12:04:55.936488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**通过这段代码，你可以直观地比较模型的预测结果与真实标签值之间的差异。蓝色加号代表真实标签值，红色圆点代表模型预测结果。如果两者重合得越好，则说明模型的预测效果越好。结果很不错！如果使用更多的观测数据，我们可以进一步提高预测效果。**","metadata":{"_uuid":"5222997fa072781925041d67f3ac293c0f6d862f","_cell_guid":"a8ebfd78-f1e8-4ab7-96a4-4e75c5713a61"}},{"cell_type":"markdown","source":"# **Neural Network with Keras**\n\n## 使用 Keras 的神经网络进行回归任务","metadata":{"_uuid":"8d4f3f7eaba1a37f6c858d44609bd5f0475e1957","_cell_guid":"6575fe9b-4b86-471f-90e4-611eb4b73ead"}},{"cell_type":"code","source":"import keras\n\n# Convert data as np.array\nfeatures = np.array(X_train)\ntargets = np.array(y_train.reshape(y_train.shape[0],1))\nfeatures_validation= np.array(X_validation)\ntargets_validation = np.array(y_validation.reshape(y_validation.shape[0],1))\n\nprint(features[:10])\nprint(targets[:10])","metadata":{"_uuid":"e30928e25e887cc5e29150fe5625fb9a6eac8374","_cell_guid":"b5065fe5-263a-4fe8-a951-cf0d0fe41ab4","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**将数据转换为 NumPy 数组，并输出前10个转换后的特征和目标变量。\n首先，使用 np.array() 函数将训练集中的特征数据 X_train 转换为 NumPy 数组，并将目标变量 y_train 通过 reshape 方法转换为二维数组，然后也转换为 NumPy 数组。同样地，验证集中的特征数据 X_validation 和目标变量 y_validation 也被转换为 NumPy 数组。\n接着，使用 print() 函数输出转换后的特征和目标变量的前10个数据点，以便检查转换是否正确。**","metadata":{}},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers.core import Dense, Dropout, Activation\n\n# Building the model\nmodel = Sequential()\nmodel.add(Dense(32, activation='relu', input_shape=(X_train.shape[1],)))\nmodel.add(Dropout(.2))\nmodel.add(Dense(16, activation='relu'))\nmodel.add(Dropout(.1))\nmodel.add(Dense(1))\n\n# Compiling the model\nmodel.compile(loss = 'mse', optimizer='adam', metrics=['mse']) #mse: mean_square_error\nmodel.summary()","metadata":{"_uuid":"48dbec21f160c18ba6e75786d482ac3d51bdac9a","_cell_guid":"d83f314b-8f40-4e38-9d89-e1bc86e94469","execution":{"iopub.status.busy":"2024-01-02T12:07:11.005798Z","iopub.execute_input":"2024-01-02T12:07:11.006627Z","iopub.status.idle":"2024-01-02T12:07:11.130239Z","shell.execute_reply.started":"2024-01-02T12:07:11.006548Z","shell.execute_reply":"2024-01-02T12:07:11.129003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**使用 Keras 构建了一个神经网络模型，并编译了该模型。\n首先，导入必要的库。Sequential 是一个线性层堆叠模型，Dense 是一个全连接层，Dropout 是用于防止过拟合的一种正则化技术，Activation 是激活函数。\n接下来，使用 model = Sequential() 创建了一个空的神经网络模型。\n然后，通过 model.add() 方法逐层添加神经网络的层。首先添加了一个具有32个神经元和ReLU激活函数的全连接层，输入形状由训练集的特征维度 X_train.shape[1] 决定。然后添加了一个 Dropout 层，丢弃率为0.2，用于减少过拟合的影响。接着添加了一个具有16个神经元和ReLU激活函数的全连接层，再次添加了一个 Dropout 层，丢弃率为0.1。最后添加了一个具有1个神经元的输出层，该层没有指定激活函数。\n完成层的添加后，使用 model.compile() 方法对模型进行编译。loss='mse' 表示使用均方误差作为损失函数，optimizer='adam' 表示使用 Adam 优化器进行参数优化，metrics=['mse'] 表示评估指标为均方误差。\n最后，使用 model.summary() 方法打印出模型的概述信息，包括每一层的名称、输出形状和参数数量等。\n总之，这段代码构建了一个具有多层全连接层的神经网络模型，并编译了该模型，以便进行后续的训练和评估。**","metadata":{}},{"cell_type":"code","source":"# Training the model\nepochs_tot = 1000\nepochs_step = 250\nepochs_ratio = int(epochs_tot / epochs_step)\nhist =np.array([])\n\nfor i in range(epochs_ratio):\n    history = model.fit(features, targets, epochs=epochs_step, batch_size=100, verbose=0)\n    \n    # Evaluating the model on the training and testing set\n    print(\"Step : \" , i * epochs_step, \"/\", epochs_tot)\n    score = model.evaluate(features, targets)\n    print(\"Training MSE:\", score[1])\n    score = model.evaluate(features_validation, targets_validation)\n    print(\"Validation MSE:\", score[1], \"\\n\")\n    hist = np.concatenate((hist, np.array(history.history['mean_squared_error'])), axis = 0)\n    \n# plot metrics\nplt.plot(hist)\nplt.show()","metadata":{"_uuid":"819151431dd610ae0a107fe4e92d0a96caf72894","_cell_guid":"940f9d4c-aefb-4cbd-a1e9-23f9d24d632e","execution":{"iopub.status.busy":"2024-01-02T12:08:36.215808Z","iopub.execute_input":"2024-01-02T12:08:36.216182Z","iopub.status.idle":"2024-01-02T12:13:19.114381Z","shell.execute_reply.started":"2024-01-02T12:08:36.216137Z","shell.execute_reply":"2024-01-02T12:13:19.113436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**对神经网络模型进行训练：\n首先，定义了总共的训练轮数 epochs_tot，每个步骤的训练轮数 epochs_step 和步骤数量 epochs_ratio。其中，epochs_ratio 是将总轮数 epochs_tot 分成多少个步骤。\n然后，在一个 for 循环中，进行了多个步骤的训练。在每个步骤中，使用 model.fit() 方法对模型进行训练，传入特征数据 features 和目标数据 targets，并设置每个步骤的训练轮数为 epochs_step，批次大小为 100。通过 verbose=0 参数可以控制训练过程中是否输出日志信息。\n在每个步骤完成训练后，通过 model.evaluate() 方法评估模型在训练集和验证集上的均方误差（MSE）。打印出当前步骤的训练轮数和对应的训练集和验证集的 MSE 值。\n同时，将每个步骤的历史训练误差（mean_squared_error）保存在 hist 数组中，以便后续可视化。\n最后，使用 plt.plot() 方法将训练误差随训练步骤的变化绘制出来，以便观察模型的训练进展情况。\n总之，这段代码展示了对神经网络模型进行多步骤训练的过程，并输出每个步骤的训练误差，并将历史训练误差可视化。**","metadata":{}},{"cell_type":"code","source":"predictions = model.predict(features_validation, verbose=0)\n\nprint('R2 score = ',r2_score(y_validation, predictions), '/ 1.0')\nprint('MSE score = ',mean_squared_error(y_validation_RF, predictions), '/ 0.0')","metadata":{"_uuid":"ee52c011057118bf70b516d7ffa37d2c6fbb16bd","_cell_guid":"e06066d1-0fa7-4d00-a31f-86fcde3074a6","execution":{"iopub.status.busy":"2024-01-02T12:13:26.640608Z","iopub.execute_input":"2024-01-02T12:13:26.641060Z","iopub.status.idle":"2024-01-02T12:13:26.728223Z","shell.execute_reply.started":"2024-01-02T12:13:26.640935Z","shell.execute_reply":"2024-01-02T12:13:26.727304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**这段代码是使用训练好的模型对验证集数据进行预测，并计算预测结果与真实结果之间的 R2 分数和 MSE 分数。\n首先，通过 model.predict() 方法使用训练好的模型对验证集特征数据 features_validation 进行预测，并得到一个预测结果数组 predictions。\n然后，使用 r2_score() 方法计算预测结果与验证集目标值 y_validation 之间的 R2 分数，并打印出结果。\n接着，使用 mean_squared_error() 方法计算预测结果与验证集目标值之间的 MSE 分数，并打印出结果。\n其中，R2 分数用于评估回归模型的预测能力，其取值范围为 [0, 1]，分数越接近 1 表示模型的预测能力越好。MSE 分数用于评估模型预测结果的准确度，其取值范围为 [0, ∞)，分数越小表示模型预测结果越准确。**\n\n**R2分数为0.861，接近于1.0，表示模型的预测能力相对较好。MSE分数为0.000172，接近于0.0，表示模型的预测结果相对准确。这两个指标都表明模型在验证集上的表现良好。**","metadata":{}},{"cell_type":"code","source":"#Check and plot the 50 first predictions\nplt.plot(y_validation.as_matrix()[0:50], '+', color ='blue', alpha=0.7)\nplt.plot(predictions[0:50], 'ro', color ='red', alpha=0.5)\nplt.show()","metadata":{"_uuid":"a95623376509cc3b79ecc0fdbe94dbaf1bedf1ed","_cell_guid":"68ecf414-19b0-4c33-817d-abc864610fbd","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**这段代码用于检查并绘制前 50 个预测结果的对比图。\n首先，使用 plt.plot() 方法绘制了验证集中前 50 个目标值（真实数值）的散点图，使用蓝色加号（'+'）表示，并设置透明度为0.7。\n然后，使用 plt.plot() 方法再次绘制了模型对这 50 个样本的预测结果，使用红色圆圈（'ro'）表示，并设置透明度为0.5。\n最后，使用 plt.show() 方法显示绘制出的对比图。\n通过这段代码，可以直观地比较模型的前 50 个预测结果与真实目标值之间的差异，以便对模型的预测效果有一个直观的了解。**","metadata":{}},{"cell_type":"markdown","source":"**预测结果还算满意，即使我们没有使用大量的数据。如果从数据库中收集所有的数据，我们可能会得到更准确的结果**","metadata":{}}]}