{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import 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":"2022-07-11T09:44:19.806303Z","iopub.execute_input":"2022-07-11T09:44:19.806769Z","iopub.status.idle":"2022-07-11T09:44:19.821126Z","shell.execute_reply.started":"2022-07-11T09:44:19.80673Z","shell.execute_reply":"2022-07-11T09:44:19.819909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1 问题定义\n该问题来源于kaggle.这是一个关于共享单车租赁预测的题目，通过对数据的观察，可以预测出共享单车在某个时间段的租赁数量。如果预测值和实际租赁值存在很大差异，就可以做出调查并采取措施从而保证共享单车的正常运营。训练集提供了2011与2012年每个月的前19天的数据和使用情况，提供的数据集包括日期、季节、节假日、工作日、天气、实际温度、体感温度、湿度、注册人数、未注册人数、租赁数目。测试集提供了每个月20日及以后的数据，我们主要的任务就是预测这些天的使用情况。","metadata":{}},{"cell_type":"markdown","source":"## 导包","metadata":{}},{"cell_type":"code","source":"# 导入必要包\nimport pandas as pd\nimport numpy as np\nimport pylab\nimport calendar\nimport seaborn as sns #matplotlib更高级封装的库\nfrom scipy import stats\nfrom datetime import datetime\nimport matplotlib.pyplot as plt\nimport warnings\nfrom sklearn.model_selection import GridSearchCV\n\npd.options.mode.chained＿assignment = None #避免pandas报错\nwarnings.filterwarnings(\"ignore\") #忽略警告\n\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:19.823187Z","iopub.execute_input":"2022-07-11T09:44:19.823775Z","iopub.status.idle":"2022-07-11T09:44:19.834613Z","shell.execute_reply.started":"2022-07-11T09:44:19.823739Z","shell.execute_reply":"2022-07-11T09:44:19.83292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2 获取并导入数据","metadata":{}},{"cell_type":"code","source":"# 导入训练集与数据集\ntrain = pd.read_csv('/kaggle/input/bike-sharing-demand/train.csv', parse_dates=True)\ntest = pd.read_csv('/kaggle/input/bike-sharing-demand/test.csv', parse_dates=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:19.836931Z","iopub.execute_input":"2022-07-11T09:44:19.837586Z","iopub.status.idle":"2022-07-11T09:44:19.913397Z","shell.execute_reply.started":"2022-07-11T09:44:19.837547Z","shell.execute_reply":"2022-07-11T09:44:19.91219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3 探索性数据分析(EDA)与数据预处理\n\n## 3.1 描述性数据分析\n\n首先观察数据集中包含哪些特征","metadata":{}},{"cell_type":"code","source":"# 显示数据文件的相关信息\ntrain.info()\ntest.info()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:19.916658Z","iopub.execute_input":"2022-07-11T09:44:19.917566Z","iopub.status.idle":"2022-07-11T09:44:19.963063Z","shell.execute_reply.started":"2022-07-11T09:44:19.9175Z","shell.execute_reply":"2022-07-11T09:44:19.961943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出数据集中包含如下特征：\n\nseason：表示季节。1=春 2=夏 3=秋 4=冬\n\nholiday：表示是否是节假日。1=节假日 0=非节假日\n\nworkingday：表示是否是工作日。1=工作日 0=周末\n\nweather：表示天气。1=晴天多云 2=雾天阴天 3=小雪小雨 4=大雨大雪大雾\n\ntemp：气温（摄氏度）\n\natemp：体感温度（摄氏度）\n\nhumidity：湿度\n\nwindspeed：风速\n\ncasual：非注册用户个数\n\nregistered：注册用户个数\n\ncount：给定日期时间（每小时）总租车人数\n\n其中分类型特征有：season、holiday、workingday、weather（均为标称型）；\n\n数值型特征有：temp、atemp、humidity、windspeed（连续型），casual、registered、count（离散型）。\n\n经过观察我们可知，数据集中只有一个特征datetime是字符串，其他均为整型或浮点型；数据集是完整的，没有缺失信息，测试集数据比训练集数据少了三列：count、registered、casual，count是后面要预测的数据。","metadata":{}},{"cell_type":"code","source":"# 预览训练集\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:19.964812Z","iopub.execute_input":"2022-07-11T09:44:19.965687Z","iopub.status.idle":"2022-07-11T09:44:19.992098Z","shell.execute_reply.started":"2022-07-11T09:44:19.96564Z","shell.execute_reply":"2022-07-11T09:44:19.990848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出，用车量count是casual和registered的总和，所以之后可以删除casual和registered这两个没有用的信息。\n\n随后查看数据集的经验分布以更好地观察和分析数据集：","metadata":{}},{"cell_type":"code","source":"# 查看数据分布状态，以对数据进行更好的分析。mean-均值，std-方差\ntrain.describe()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:19.99371Z","iopub.execute_input":"2022-07-11T09:44:19.994983Z","iopub.status.idle":"2022-07-11T09:44:20.054112Z","shell.execute_reply.started":"2022-07-11T09:44:19.99493Z","shell.execute_reply":"2022-07-11T09:44:20.053089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"经过以上分析，对数据的处理方案有了简单的设想：首先可以将训练集中casual和registered两个信息删去，只保留count这一有用的目标信息；此外可以将datetime拆分成多个新的整型特征，以方便下一步利用模型进行分析。","metadata":{}},{"cell_type":"markdown","source":"首先在datatime中提取出月份、日期、时间、星期，将季节、天气、工作日转换成对应的字符串，便于后面的可视化分析：","metadata":{}},{"cell_type":"code","source":"# 处理数据\ntrain[\"year\"] = train[\"datetime\"].map(lambda s:s.split(\"-\")[0]).astype(int)\ntrain[\"month\"] = train[\"datetime\"].map(lambda s:s.split(\"-\")[1]).astype(int)\ntrain[\"date\"] = train[\"datetime\"].map(lambda s:s.split(\"-\")[2].split()[0]).astype(int)\ntrain[\"weekday\"] = train[\"datetime\"].map(lambda s:datetime.strptime(s.split()[0],\"%Y-%m-%d\").weekday())\ntrain[\"hour\"] = train[\"datetime\"].map(lambda s:s.split()[1].split(\":\")[0]).astype(int)\ntrain.drop(\"datetime\",axis=1,inplace=True)\n\ntrain[\"season\"] = train[\"season\"].map({1:\"spring\",2:\"summer\",3:\"autumn\",4:\"winter\"})\ntrain[\"weather\"] = train[\"weather\"].map({1:\"sunny\",2:\"cloudy\",3:\"light rain\",4:\"heavy rain\"})\ntrain[\"weekday\"] = train[\"weekday\"].map(lambda s:calendar.day_name[s])\n\n# reference:blog.csdn.net/qq_44047943/article/details/111993932","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:20.055785Z","iopub.execute_input":"2022-07-11T09:44:20.056448Z","iopub.status.idle":"2022-07-11T09:44:20.306286Z","shell.execute_reply.started":"2022-07-11T09:44:20.056412Z","shell.execute_reply":"2022-07-11T09:44:20.305004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"预览处理过的数据集，并查看数据类型与缺失信息：","metadata":{}},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:20.307809Z","iopub.execute_input":"2022-07-11T09:44:20.308235Z","iopub.status.idle":"2022-07-11T09:44:20.329636Z","shell.execute_reply.started":"2022-07-11T09:44:20.3082Z","shell.execute_reply":"2022-07-11T09:44:20.328838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()\ntest.info()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:20.331055Z","iopub.execute_input":"2022-07-11T09:44:20.331397Z","iopub.status.idle":"2022-07-11T09:44:20.361483Z","shell.execute_reply.started":"2022-07-11T09:44:20.331366Z","shell.execute_reply":"2022-07-11T09:44:20.359925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"下面对数据特征进行可视化分析。首先观察不同时间段对使用量的影响：","metadata":{}},{"cell_type":"code","source":"sns.boxplot(x=\"hour\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:20.366975Z","iopub.execute_input":"2022-07-11T09:44:20.367405Z","iopub.status.idle":"2022-07-11T09:44:20.905079Z","shell.execute_reply.started":"2022-07-11T09:44:20.367372Z","shell.execute_reply":"2022-07-11T09:44:20.90359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"由上图可见，在一天中不同时间段，共享单车使用量差异明显。在8时和16-19时明显多于其他时间点，可能是因为这是上下班的高峰期；在0-6时、22-23时明显低于其他时间点，可能是因为这是睡眠时间。","metadata":{}},{"cell_type":"markdown","source":"接下来观察不同月份对使用量的影响：","metadata":{}},{"cell_type":"code","source":"sns.boxplot(x=\"month\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:20.906694Z","iopub.execute_input":"2022-07-11T09:44:20.907099Z","iopub.status.idle":"2022-07-11T09:44:21.211676Z","shell.execute_reply.started":"2022-07-11T09:44:20.907063Z","shell.execute_reply":"2022-07-11T09:44:21.210432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"由上图可知，11月至4月的共享单车使用量相比其他6个月份略低，考虑是由于季节和天气原因，因为冬季和春季太冷而导致使用量有所下降。为验证以上猜测，进一步观察季节对使用量的影响：","metadata":{}},{"cell_type":"code","source":"sns.boxplot(x=\"season\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:21.213613Z","iopub.execute_input":"2022-07-11T09:44:21.214405Z","iopub.status.idle":"2022-07-11T09:44:21.43948Z","shell.execute_reply.started":"2022-07-11T09:44:21.214342Z","shell.execute_reply":"2022-07-11T09:44:21.438607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看到冬春两季相对夏秋两季使用量确实相对较少，进一步印证了上一步的猜测。","metadata":{}},{"cell_type":"markdown","source":"再观察不同天气对使用量的影响：","metadata":{}},{"cell_type":"code","source":"sns.boxplot(x=\"weather\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:21.44089Z","iopub.execute_input":"2022-07-11T09:44:21.441416Z","iopub.status.idle":"2022-07-11T09:44:21.671725Z","shell.execute_reply.started":"2022-07-11T09:44:21.441382Z","shell.execute_reply":"2022-07-11T09:44:21.670043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出天气情况对单车使用量的影响基本符合我们的生活常识。下雨下雪天单车使用量减少，天气恶劣时基本没有人使用共享单车。","metadata":{}},{"cell_type":"markdown","source":"再观察星期与工作日各自对使用量的影响：","metadata":{}},{"cell_type":"code","source":"sns.boxplot(x=\"weekday\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:21.675712Z","iopub.execute_input":"2022-07-11T09:44:21.676167Z","iopub.status.idle":"2022-07-11T09:44:21.962027Z","shell.execute_reply.started":"2022-07-11T09:44:21.676127Z","shell.execute_reply":"2022-07-11T09:44:21.960782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.boxplot(x=\"workingday\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:21.963866Z","iopub.execute_input":"2022-07-11T09:44:21.964218Z","iopub.status.idle":"2022-07-11T09:44:22.145555Z","shell.execute_reply.started":"2022-07-11T09:44:21.964184Z","shell.execute_reply":"2022-07-11T09:44:22.143352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出星期与工作日单独对单车日总使用量的影响并不明显，可能需要结合其他因素的共同影响来考虑。","metadata":{}},{"cell_type":"markdown","source":"再来关注温度与体感温度对单车使用量的影响：","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nsns.regplot(x=\"temp\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:22.147241Z","iopub.execute_input":"2022-07-11T09:44:22.147588Z","iopub.status.idle":"2022-07-11T09:44:23.11863Z","shell.execute_reply.started":"2022-07-11T09:44:22.147558Z","shell.execute_reply":"2022-07-11T09:44:23.117384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nsns.regplot(x=\"atemp\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:23.120273Z","iopub.execute_input":"2022-07-11T09:44:23.121258Z","iopub.status.idle":"2022-07-11T09:44:24.077128Z","shell.execute_reply.started":"2022-07-11T09:44:23.121219Z","shell.execute_reply":"2022-07-11T09:44:24.076078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出温度与体感温度对单车使用量的影响是一致的。当体感温度较低（低于10度）或较高（高于40度）时，单车使用量明显减少；当温度较为正常时，温度变化对单车使用量的影响不大。","metadata":{}},{"cell_type":"markdown","source":"再看湿度对单车使用量的影响：","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nsns.regplot(x=\"humidity\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:24.078484Z","iopub.execute_input":"2022-07-11T09:44:24.078875Z","iopub.status.idle":"2022-07-11T09:44:25.210621Z","shell.execute_reply.started":"2022-07-11T09:44:24.078815Z","shell.execute_reply":"2022-07-11T09:44:25.209158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出整体影响较小。","metadata":{}},{"cell_type":"markdown","source":"风速对单车使用量的影响：","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nsns.regplot(x=\"windspeed\",y=\"count\",data=train)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:25.212123Z","iopub.execute_input":"2022-07-11T09:44:25.212539Z","iopub.status.idle":"2022-07-11T09:44:26.150706Z","shell.execute_reply.started":"2022-07-11T09:44:25.212503Z","shell.execute_reply":"2022-07-11T09:44:26.149132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"由图可知，风速在超过20m/s时，单车的使用量有所减少；超过30m/s时，使用量的减少尤为明显。由图中也可以看出风速为0的时候有较多组数据，可能是由于数据缺失，也可能是由于当时环境确实无风。在接下来将对风速的数据进行进一步预处理。","metadata":{}},{"cell_type":"markdown","source":"下面看看以上因素中的几个共同作用下对单车使用量的影响。首先看看季节对一天中不同时段单车使用量趋势的影响(特征season+hour)：","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\ndf1 = pd.DataFrame(train.groupby([\"hour\",\"season\"])[\"count\"].mean()).reset_index()\nsns.pointplot(x=\"hour\",y=\"count\",hue=\"season\",join=True,data=df1)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:26.152594Z","iopub.execute_input":"2022-07-11T09:44:26.153021Z","iopub.status.idle":"2022-07-11T09:44:26.751782Z","shell.execute_reply.started":"2022-07-11T09:44:26.152985Z","shell.execute_reply":"2022-07-11T09:44:26.750498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出，共享单车在一天中不同时段的使用量趋势，出现了两个明显的高峰，对应于上下班高峰期，符合“早高峰”、“晚高峰”的认识；四个季节中的使用量趋势基本一致，只是春季使用量相比其他三个季节较少一点。","metadata":{}},{"cell_type":"markdown","source":"再看看星期对一天中不同时段单车使用量的影响(特征weekday+hour)：","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\ndf1 = pd.DataFrame(train.groupby([\"hour\",\"weekday\"])[\"count\"].mean()).reset_index()\nsns.pointplot(x=\"hour\",y=\"count\",hue=\"weekday\",join=True,data=df1)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:26.75342Z","iopub.execute_input":"2022-07-11T09:44:26.753792Z","iopub.status.idle":"2022-07-11T09:44:27.588574Z","shell.execute_reply.started":"2022-07-11T09:44:26.753757Z","shell.execute_reply":"2022-07-11T09:44:27.587356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出周一到周五使用量的两个高峰非常明显且使用量趋势相近。而在周末，使用量的趋势与工作日完全不同，由双峰变成了平缓的单峰，且使用高峰时段集中在10-18时，考虑可能是由于人们周末使用共享单车作为代步工具外出游玩。","metadata":{}},{"cell_type":"markdown","source":"此处对训练集与测试集再作处理，以方便下一步利用模型进行分析。为方便可视化分析而做出的将季节、天气、工作日转换成对应的字符串的操作，在此处不再执行。","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/bike-sharing-demand/train.csv', parse_dates=True)\n\ntrain[\"year\"] = train[\"datetime\"].map(lambda s:s.split(\"-\")[0]).astype(int)\ntrain[\"month\"] = train[\"datetime\"].map(lambda s:s.split(\"-\")[1]).astype(int)\ntrain[\"date\"] = train[\"datetime\"].map(lambda s:s.split(\"-\")[2].split()[0]).astype(int)\ntrain[\"weekday\"] = train[\"datetime\"].map(lambda s:datetime.strptime(s.split()[0],\"%Y-%m-%d\").weekday())\ntrain[\"hour\"] = train[\"datetime\"].map(lambda s:s.split()[1].split(\":\")[0]).astype(int)\ntrain.drop(\"datetime\",axis=1,inplace=True)\n\ntest[\"year\"] = test[\"datetime\"].map(lambda s:s.split(\"-\")[0]).astype(int)\ntest[\"month\"] = test[\"datetime\"].map(lambda s:s.split(\"-\")[1]).astype(int)\ntest[\"date\"] = test[\"datetime\"].map(lambda s:s.split(\"-\")[2].split()[0]).astype(int)\ntest[\"weekday\"] = test[\"datetime\"].map(lambda s:datetime.strptime(s.split()[0],\"%Y-%m-%d\").weekday())\ntest[\"hour\"] = test[\"datetime\"].map(lambda s:s.split()[1].split(\":\")[0]).astype(int)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:27.590223Z","iopub.execute_input":"2022-07-11T09:44:27.591239Z","iopub.status.idle":"2022-07-11T09:44:27.924061Z","shell.execute_reply.started":"2022-07-11T09:44:27.591198Z","shell.execute_reply":"2022-07-11T09:44:27.92294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:27.925345Z","iopub.execute_input":"2022-07-11T09:44:27.925939Z","iopub.status.idle":"2022-07-11T09:44:27.944405Z","shell.execute_reply.started":"2022-07-11T09:44:27.925904Z","shell.execute_reply":"2022-07-11T09:44:27.943068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:27.945927Z","iopub.execute_input":"2022-07-11T09:44:27.946295Z","iopub.status.idle":"2022-07-11T09:44:27.968546Z","shell.execute_reply.started":"2022-07-11T09:44:27.946252Z","shell.execute_reply":"2022-07-11T09:44:27.967325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"使用xgboost，对缺失的风速数据作进一步填充：","metadata":{}},{"cell_type":"code","source":"train['windspeed_xgbr'] = train['windspeed']\n#将数据分为有风和没有风两部分\ndataWind0 = train[train['windspeed_xgbr']==0]\ndataWindNot0 = train[train['windspeed_xgbr']!=0]\n\n#选取特征\nwindColumns = ['year','month','hour','weekday','season','weather','humidity','temp','atemp','holiday','workingday']\n\n#使用xgboost填充风速\nimport xgboost as xgb\nxgbr = xgb.XGBRegressor()\n\nxgbr.fit(dataWindNot0[windColumns],dataWindNot0['windspeed_xgbr'])\nwind0Values = xgbr.predict(dataWind0[windColumns])\n#将预测的风速填充到风速为0的数据中\ndataWind0.loc[:,'windspeed_xgbr'] = wind0Values\n#连接两部分数据\ntrain = dataWindNot0.append(dataWind0)\n\n#reference:github.com/pengaoao/Bike-sharing-demand","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:27.970134Z","iopub.execute_input":"2022-07-11T09:44:27.971267Z","iopub.status.idle":"2022-07-11T09:44:28.762019Z","shell.execute_reply.started":"2022-07-11T09:44:27.971229Z","shell.execute_reply":"2022-07-11T09:44:28.760914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['windspeed_xgbr'] = test['windspeed']\n#将数据分为有风和没有风两部分\ndataWind0 = test[test['windspeed_xgbr']==0]\ndataWindNot0 = test[test['windspeed_xgbr']!=0]\n\nxgbr.fit(dataWindNot0[windColumns],dataWindNot0['windspeed_xgbr'])\nwind0Values = xgbr.predict(dataWind0[windColumns])\n#将预测的风速填充到风速为0的数据中\ndataWind0.loc[:,'windspeed_xgbr'] = wind0Values\n#连接两部分数据\ntest = dataWindNot0.append(dataWind0)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:28.76393Z","iopub.execute_input":"2022-07-11T09:44:28.764855Z","iopub.status.idle":"2022-07-11T09:44:29.300231Z","shell.execute_reply.started":"2022-07-11T09:44:28.764783Z","shell.execute_reply":"2022-07-11T09:44:29.299159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"将训练数据中的使用量提取出来，并作对数变换：","metadata":{}},{"cell_type":"code","source":"train_y=train.loc[:,'count']\ntrain_y_log = np.log(train_y)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.302222Z","iopub.execute_input":"2022-07-11T09:44:29.303133Z","iopub.status.idle":"2022-07-11T09:44:29.31077Z","shell.execute_reply.started":"2022-07-11T09:44:29.303083Z","shell.execute_reply":"2022-07-11T09:44:29.309578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"根据前面的观察，决定将时段（hour）、温度（temp）、湿度（humidity）、年份（year）、月份（month）、季节（season）、天气等级（weather）、风速（windspeed_xgbr）、星期几（weekday）、是否工作日（workingday）、是否假日（holiday）等11项作为特征值。\n\n接下来对数据作进一步处理，使用get_dummies进行one-hot编码：","metadata":{}},{"cell_type":"code","source":"#pandas使用get_dummies进行one-hot编码\ndummies_month = pd.get_dummies(train['month'], prefix= 'month')\ndummies_season=pd.get_dummies(train['season'],prefix='season')\ndummies_weather=pd.get_dummies(train['weather'],prefix='weather')\ndummies_year=pd.get_dummies(train['year'],prefix='year')\n#把5个新的DF和原来的表连接起来\ntrain=pd.concat([train,dummies_month,dummies_season,dummies_weather,dummies_year],axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.318764Z","iopub.execute_input":"2022-07-11T09:44:29.319908Z","iopub.status.idle":"2022-07-11T09:44:29.335311Z","shell.execute_reply.started":"2022-07-11T09:44:29.319847Z","shell.execute_reply":"2022-07-11T09:44:29.3338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#对测试集做相同处理\ndummies_month = pd.get_dummies(test['month'], prefix= 'month')\ndummies_season=pd.get_dummies(test['season'],prefix='season')\ndummies_weather=pd.get_dummies(test['weather'],prefix='weather')\ndummies_year=pd.get_dummies(test['year'],prefix='year')\ntest=pd.concat([test,dummies_month,dummies_season,dummies_weather,dummies_year],axis=1)\ntest= test.sort_values(by=['datetime'])","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.337187Z","iopub.execute_input":"2022-07-11T09:44:29.338179Z","iopub.status.idle":"2022-07-11T09:44:29.363561Z","shell.execute_reply.started":"2022-07-11T09:44:29.338134Z","shell.execute_reply":"2022-07-11T09:44:29.362178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"把不要的列丢弃。此时风速已经用windspeed_xgbr代替了,month、season、weather、year已经使用one-hot编码的变量代替了：","metadata":{}},{"cell_type":"code","source":"dropFeatures1 = ['casual' , 'count' ,  'date' , 'registered' ,\n                 'month','season','weather','windspeed', 'year' ]\ndropFeatures2 = ['date' , 'month','datetime','season','weather','windspeed', 'year' ]\n\ntrain.drop(dropFeatures1,axis=1,inplace=True)\ntest.drop(dropFeatures2,axis=1,inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.365156Z","iopub.execute_input":"2022-07-11T09:44:29.36555Z","iopub.status.idle":"2022-07-11T09:44:29.381439Z","shell.execute_reply.started":"2022-07-11T09:44:29.365517Z","shell.execute_reply":"2022-07-11T09:44:29.380375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4 建立模型，预测求解","metadata":{}},{"cell_type":"markdown","source":"此处预计供选择的模型有如下几个：\n\nRandomForestRegressor，LGBMRegressor，ExtraTreesRegressor，BaggingRegressor，XGBRegressor，GradientBoostingRegressor。","metadata":{}},{"cell_type":"markdown","source":"首先分割训练集与测试集：","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nX_train, X_test, y_train, y_test = train_test_split(train,train_y,test_size=0.3, random_state=0)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.382881Z","iopub.execute_input":"2022-07-11T09:44:29.38349Z","iopub.status.idle":"2022-07-11T09:44:29.395512Z","shell.execute_reply.started":"2022-07-11T09:44:29.383452Z","shell.execute_reply":"2022-07-11T09:44:29.394372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"题目要求的评价标准为：均方根对数误差RMSLE","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import mean_squared_error\ndef rmsle(y_true, y_pred):\n    ret= mean_squared_error(np.log(y_true+1),np.log(np.clip(y_pred,0,None)+1))\n    return np.sqrt(ret)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.397658Z","iopub.execute_input":"2022-07-11T09:44:29.398605Z","iopub.status.idle":"2022-07-11T09:44:29.406559Z","shell.execute_reply.started":"2022-07-11T09:44:29.398555Z","shell.execute_reply":"2022-07-11T09:44:29.405663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"分别测试了它们在训练集上的训练损失，测试集上的损失，测试集上的精确度。","metadata":{}},{"cell_type":"code","source":"def model_research(model):\n    print(\"###\",model.__class__.__name__,\"###\")\n    model.fit(X_train,y_train)\n    print(\"训练集RMSLE:\",rmsle(y_train.astype(int),model.predict(X_train)))\n    print(\"测试集RMSLE:\",rmsle(y_test.astype(int),model.predict(X_test)))\n    result = model.score(X_test,y_test)\n    print(\"精度:\",result)\n    ","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.408238Z","iopub.execute_input":"2022-07-11T09:44:29.409059Z","iopub.status.idle":"2022-07-11T09:44:29.420435Z","shell.execute_reply.started":"2022-07-11T09:44:29.409009Z","shell.execute_reply":"2022-07-11T09:44:29.419089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import xgboost as xgb\nmodelx = xgb.XGBRegressor()\nmodel_research(modelx)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:29.422159Z","iopub.execute_input":"2022-07-11T09:44:29.422531Z","iopub.status.idle":"2022-07-11T09:44:30.399807Z","shell.execute_reply.started":"2022-07-11T09:44:29.422501Z","shell.execute_reply":"2022-07-11T09:44:30.39831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, ExtraTreesRegressor, BaggingRegressor\nimport xgboost as xgb\nfrom lightgbm import LGBMRegressor\n\nrf_reg = RandomForestRegressor()\ngbm_reg= GradientBoostingRegressor()\nlgbm_reg = LGBMRegressor()\next_reg = ExtraTreesRegressor()\nbag_reg = BaggingRegressor()\nfor model in [rf_reg,gbm_reg,lgbm_reg,ext_reg,bag_reg]:\n    model_research(model)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:30.40581Z","iopub.execute_input":"2022-07-11T09:44:30.407197Z","iopub.status.idle":"2022-07-11T09:44:40.782448Z","shell.execute_reply.started":"2022-07-11T09:44:30.407134Z","shell.execute_reply":"2022-07-11T09:44:40.781493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"最后使用集成模型，将表现最好的几个模型组合起来：","metadata":{}},{"cell_type":"code","source":"estimators = [('lgbm',LGBMRegressor()),\n            ('ext',ExtraTreesRegressor()),\n             ('bag',BaggingRegressor()),\n             ('xgbm',xgb.XGBRegressor()),\n             ]","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:40.783569Z","iopub.execute_input":"2022-07-11T09:44:40.784643Z","iopub.status.idle":"2022-07-11T09:44:40.790214Z","shell.execute_reply.started":"2022-07-11T09:44:40.784604Z","shell.execute_reply":"2022-07-11T09:44:40.789038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.ensemble import StackingRegressor\n\nreg = StackingRegressor(estimators=estimators,final_estimator=GradientBoostingRegressor())\nmodel_research(reg)\n\n# reference:blog.csdn.net/qq_44047943/article/details/111993932","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:44:40.791968Z","iopub.execute_input":"2022-07-11T09:44:40.792591Z","iopub.status.idle":"2022-07-11T09:45:06.69574Z","shell.execute_reply.started":"2022-07-11T09:44:40.792545Z","shell.execute_reply":"2022-07-11T09:45:06.694623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"可以看出融合之后的效果超过了任何一个单个模型。","metadata":{}},{"cell_type":"markdown","source":"# 5 提交结果","metadata":{}},{"cell_type":"code","source":"reg.fit(train, train_y_log)\nreg_y_predict = reg.predict(test)\n\n\n# 输出结果\ntest1 = pd.read_csv('/kaggle/input/bike-sharing-demand/test.csv', parse_dates=True)\nreg_submission = pd.DataFrame({'datetime': test1['datetime'], 'count': [max(0,x) for x in np.exp(reg_y_predict)]})\nreg_submission.to_csv('reg_submission7.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-11T09:45:06.700523Z","iopub.execute_input":"2022-07-11T09:45:06.700962Z","iopub.status.idle":"2022-07-11T09:45:47.658875Z","shell.execute_reply.started":"2022-07-11T09:45:06.700923Z","shell.execute_reply":"2022-07-11T09:45:47.657681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"最终得分为0.39092","metadata":{}},{"cell_type":"markdown","source":"此次实验在过程中借鉴了一些优秀经验，做出了诸多改进。最开始的数据没有进行取自然对数、获得one-hot编码、填充风速等处理，且最后使用单一的随机森林模型进行处理，得分仅在0.48左右；后来改用集成模型，得分上升至0.44左右；之后添加了上述的多种预处理方法，提交的最终结果得分在0.39左右。","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}