Kaggle (2) :Bike Sharing Demand 共享单车需求预测

news2024/11/18 0:37:44

Kaggle (2) :Bike Sharing Demand 共享单车需求预测

题目链接:https://www.kaggle.com/competitions/bike-sharing-demand

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")

reference:https://www.kaggle.com/code/maquej/bike-sharing-demand0714

读入数据并预处理

对因变量取对数,检查缺失值

train = pd.read_csv('/kaggle/input/bike-sharing-demand/train.csv')
test = pd.read_csv('/kaggle/input/bike-sharing-demand/test.csv')
#train = pd.read_csv('train.csv')
#test = pd.read_csv('test.csv')
train.head()
datetimeseasonholidayworkingdayweathertempatemphumiditywindspeedcasualregisteredcount
02011-01-01 00:00:0010019.8414.395810.031316
12011-01-01 01:00:0010019.0213.635800.083240
22011-01-01 02:00:0010019.0213.635800.052732
32011-01-01 03:00:0010019.8414.395750.031013
42011-01-01 04:00:0010019.8414.395750.0011
#取对数:+1防止出现log0的情况
for col in ['casual', 'registered', 'count']:
    train['%s_log' % col] = np.log(train[col] + 1)

train.head()
datetimeseasonholidayworkingdayweathertempatemphumiditywindspeedcasualregisteredcountcasual_logregistered_logcount_log
02011-01-01 00:00:0010019.8414.395810.0313161.3862942.6390572.833213
12011-01-01 01:00:0010019.0213.635800.0832402.1972253.4965083.713572
22011-01-01 02:00:0010019.0213.635800.0527321.7917593.3322053.496508
32011-01-01 03:00:0010019.8414.395750.0310131.3862942.3978952.639057
42011-01-01 04:00:0010019.8414.395750.00110.0000000.6931470.693147
train.isna().sum()#没有缺失值,不需要填补
datetime          0
season            0
holiday           0
workingday        0
weather           0
temp              0
atemp             0
humidity          0
windspeed         0
casual            0
registered        0
count             0
casual_log        0
registered_log    0
count_log         0
dtype: int64

处理日期

从日期中提取月份、日期等信息,并将休假和工作日分开

dt = pd.DatetimeIndex(train['datetime'])
train.set_index(dt, inplace=True)
dtt = pd.DatetimeIndex(test['datetime'])
test.set_index(dtt, inplace=True)
def get_day(day_start):
    day_end = day_start + pd.offsets.DateOffset(hours=23)
    return pd.date_range(day_start, day_end, freq="H")

# 纳税日需要工作
train.loc[get_day(pd.datetime(2011, 4, 15)), "workingday"] = 1
train.loc[get_day(pd.datetime(2012, 4, 16)), "workingday"] = 1
# 感恩节不需要工作
test.loc[get_day(pd.datetime(2011, 11, 25)), "workingday"] = 0
test.loc[get_day(pd.datetime(2012, 11, 23)), "workingday"] = 0
# 圣诞节不需要工作
test.loc[get_day(pd.datetime(2011, 12, 24)), "workingday"] = 0
test.loc[get_day(pd.datetime(2011, 12, 31)), "workingday"] = 0
test.loc[get_day(pd.datetime(2012, 12, 26)), "workingday"] = 0
test.loc[get_day(pd.datetime(2012, 12, 31)), "workingday"] = 0

#暴雨
test.loc[get_day(pd.datetime(2012, 5, 21)), "holiday"] = 1
#海啸
train.loc[get_day(pd.datetime(2012, 6, 1)), "holiday"] = 1
#提取年份、月份、日期等信息
from datetime import datetime

def time_process(df):
    df['year'] = pd.DatetimeIndex(df.index).year
    df['month'] = pd.DatetimeIndex(df.index).month
    df['day'] = pd.DatetimeIndex(df.index).day
    df['hour'] = pd.DatetimeIndex(df.index).hour
    df['week'] = pd.DatetimeIndex(df.index).weekofyear
    df['weekday'] = pd.DatetimeIndex(df.index).dayofweek
    return df

train = time_process(train)
test = time_process(test)
train.head(2)
datetimeseasonholidayworkingdayweathertempatemphumiditywindspeedcasual...countcasual_logregistered_logcount_logyearmonthdayhourweekweekday
datetime
2011-01-01 00:00:002011-01-01 00:00:0010019.8414.395810.03...161.3862942.6390572.8332132011110525
2011-01-01 01:00:002011-01-01 01:00:0010019.0213.635800.08...402.1972253.4965083.7135722011111525

2 rows × 21 columns

可视化分析

1.一天中不同时间段的影响

#工作日
sns.boxplot(x='hour',y='count',data=train[train['workingday'] == 1])
<AxesSubplot:xlabel='hour', ylabel='count'>

在这里插入图片描述

#非工作日
sns.boxplot(x='hour',y='count',data=train[train['workingday'] == 0])
<AxesSubplot:xlabel='hour', ylabel='count'>

在这里插入图片描述

可以发现,在工作日中的高峰期是早上8点和下午17点、18点;在非工作日中的高峰期是10点到19点。将这些时间段标记为高峰期。

#星期几对应的使用量。可以明显发现非工作日和工作日的使用曲线分别高度重合,具有普遍规律
sns.pointplot(x='hour',y='count',hue='weekday',join=True,data=train)
<AxesSubplot:xlabel='hour', ylabel='count'>

在这里插入图片描述

train['peak'] = train[['hour', 'workingday']].apply(lambda x: (0, 1)[(x['workingday'] == 1 and  ( x['hour'] == 8 or 17 <= x['hour'] <= 18  or 12 <= x['hour'] <= 13)) or (x['workingday'] == 0 and  10 <= x['hour'] <= 19)], axis = 1)
test['peak'] = test[['hour', 'workingday']].apply(lambda x: (0, 1)[(x['workingday'] == 1 and  ( x['hour'] == 8 or 17 <= x['hour'] <= 18  or 12 <= x['hour'] <= 13)) or (x['workingday'] == 0 and  10 <= x['hour'] <= 19)], axis = 1)

2. 不同月份对使用量的影响

可以发现集中在夏季

sns.boxplot(x='month',y='count',data=train)
<AxesSubplot:xlabel='month', ylabel='count'>

在这里插入图片描述

3.不同天气

可见天气情况对使用量有明显影响

sns.boxplot(x='weather',y='count',data=train)
<AxesSubplot:xlabel='weather', ylabel='count'>

在这里插入图片描述

4.星期几对使用量的影响

可见工作日和非工作日有明显的差距;工作日之间没有显著的差距

sns.boxplot(x='weekday',y='count',data=train)
<AxesSubplot:xlabel='weekday', ylabel='count'>

在这里插入图片描述

是否是工作日:可见工作日使用量明显高于非工作日

sns.boxplot(x='workingday',y='count',data=train)
<AxesSubplot:xlabel='workingday', ylabel='count'>

在这里插入图片描述

5.是否注册用户

可见注册用户具有和【工作日中的时间-使用量】相似的使用曲线;而非注册用户则具有和【非工作日中的时间-使用量】相似的使用曲线

sns.pointplot(x='hour',y='registered',hue=None,join=True,data=train)
sns.pointplot(x='hour',y='casual',hue=None,join=True,data=train)
<AxesSubplot:xlabel='hour', ylabel='casual'>

在这里插入图片描述

进一步分析可以发现,和注册用户相比,非注册用户更倾向于在非工作日中使用自行车

#注册用户
sns.pointplot(x='hour',y='registered',hue='workingday',join=True,data=train)
<AxesSubplot:xlabel='hour', ylabel='registered'>

在这里插入图片描述

#非注册用户
sns.pointplot(x='hour',y='casual',hue='workingday',join=True,data=train)
<AxesSubplot:xlabel='hour', ylabel='casual'>

在这里插入图片描述

6.环境对使用量的影响

#温度--使用量
fig = plt.subplots(figsize=(16,4))
sns.pointplot(x='temp',y='count',join=True,data=train)
plt.xticks([0,10,20,30,40])
([<matplotlib.axis.XTick at 0x7f8bdd8b8a10>,
  <matplotlib.axis.XTick at 0x7f8bdd8b8690>,
  <matplotlib.axis.XTick at 0x7f8bdd8b8650>,
  <matplotlib.axis.XTick at 0x7f8bdd82c5d0>,
  <matplotlib.axis.XTick at 0x7f8bdd82c990>],
 [Text(0, 0, '0.82'),
  Text(1, 0, '1.64'),
  Text(2, 0, '2.46'),
  Text(3, 0, '3.28'),
  Text(4, 0, '4.1')])

在这里插入图片描述

#体感温度--使用量
fig = plt.subplots(figsize=(16,4))
sns.pointplot(x='atemp',y='count',join=True,data=train)
plt.xticks([0,10,20,30,40])
([<matplotlib.axis.XTick at 0x7f8bdda3ef50>,
  <matplotlib.axis.XTick at 0x7f8bdd763590>,
  <matplotlib.axis.XTick at 0x7f8bdd75ca90>,
  <matplotlib.axis.XTick at 0x7f8bdd665e50>,
  <matplotlib.axis.XTick at 0x7f8bdd6746d0>],
 [Text(0, 0, '0.76'),
  Text(1, 0, '1.515'),
  Text(2, 0, '2.275'),
  Text(3, 0, '3.03'),
  Text(4, 0, '3.79')])

在这里插入图片描述

#湿度-使用量
fig = plt.subplots(figsize=(16,4))
sns.pointplot(x='humidity',y='count',join=True,data=train)
plt.xticks([0,10,20,30,40,50,60,70,80,90])
([<matplotlib.axis.XTick at 0x7f8bdd7882d0>,
  <matplotlib.axis.XTick at 0x7f8bdd547490>,
  <matplotlib.axis.XTick at 0x7f8bdd5ab710>,
  <matplotlib.axis.XTick at 0x7f8bdd420bd0>,
  <matplotlib.axis.XTick at 0x7f8bdd42d5d0>,
  <matplotlib.axis.XTick at 0x7f8bdd42d510>,
  <matplotlib.axis.XTick at 0x7f8bdd3b5450>,
  <matplotlib.axis.XTick at 0x7f8bdd3b5390>,
  <matplotlib.axis.XTick at 0x7f8bdd3be290>,
  <matplotlib.axis.XTick at 0x7f8bdd3b5a50>],
 [Text(0, 0, '0'),
  Text(1, 0, '8'),
  Text(2, 0, '10'),
  Text(3, 0, '12'),
  Text(4, 0, '13'),
  Text(5, 0, '14'),
  Text(6, 0, '15'),
  Text(7, 0, '16'),
  Text(8, 0, '17'),
  Text(9, 0, '18')])

在这里插入图片描述

#风速-使用量
fig = plt.subplots(figsize=(16,4))
sns.pointplot(x='windspeed',y='count',join=True,data=train)
plt.xticks([0,5,10,15,20,25])
([<matplotlib.axis.XTick at 0x7f8bdd2bac50>,
  <matplotlib.axis.XTick at 0x7f8bdd2ba8d0>,
  <matplotlib.axis.XTick at 0x7f8bdd2ba890>,
  <matplotlib.axis.XTick at 0x7f8bdd25b110>,
  <matplotlib.axis.XTick at 0x7f8bdd25b4d0>,
  <matplotlib.axis.XTick at 0x7f8bdd25b190>],
 [Text(0, 0, '0.0'),
  Text(1, 0, '6.0032'),
  Text(2, 0, '7.0015'),
  Text(3, 0, '8.9981'),
  Text(4, 0, '11.0014'),
  Text(5, 0, '12.998')])

在这里插入图片描述

相关性分析

对连续型变量分析其相关性,可见体感温度和温度有极大的相关性。事实上,体感温度取决于温度和湿度,因而可以直接去除体感温度。

corr = train[['count','temp','atemp','humidity','windspeed']].corr()
mask = np.array(corr)
mask[np.tril_indices_from(mask)] = False
fig,ax = plt.subplots()
fig.set_size_inches(15,8)
sns.heatmap(corr,mask=mask,vmax=.8,square=True,annot=True)
<AxesSubplot:>

在这里插入图片描述

train.columns
Index(['datetime', 'season', 'holiday', 'workingday', 'weather', 'temp',
       'atemp', 'humidity', 'windspeed', 'casual', 'registered', 'count',
       'casual_log', 'registered_log', 'count_log', 'year', 'month', 'day',
       'hour', 'week', 'weekday', 'peak'],
      dtype='object')

训练

由于注册用户与未注册用户在特征上明显不同,所以分开预测casual和registered,结果再将两者合并即可。casual + registered = count。

采用xgboost+random forest,虽然包括random forest在内的模型在cross validation上表现很不错,但实际上还是存在过拟合,且使用随机交换特征等数据增强的效果也不怎么好。由于这两种模型都是tree-based的方法,它们不适合使用包括one-hot以及异常值去除等数据处理方式,甚至也不需要归一化,只需要将数据处理得尽可能接近正态分布即可(取log)

rf_columns = [
    'weather', 'temp', 'windspeed',
    'workingday', 'season', 'holiday',
    'hour', 'weekday', 'week', 'peak',
]
gb_columns =[
    'weather', 'temp', 'humidity', 'windspeed',
    'holiday', 'workingday', 'season',
    'hour', 'weekday', 'year', 
]
#训练数据
rf_x_train=train[rf_columns].values
rf_x_test=test[rf_columns].values

gb_x_train=train[gb_columns].values
gb_x_test=test[gb_columns].values

y_casual=train['casual_log'].values
y_registered=train['registered_log'].values
y=train['count_log'].values

x_date=test['datetime'].values
#random forest
from sklearn.ensemble import RandomForestRegressor
params = {'n_estimators': 1000, 
          'max_depth': 15, 
          'random_state': 0, 
          'min_samples_split' : 2, #为什么设为2:(1)因为存在0-1变量(2)存在过拟合
          'n_jobs': -1}

rf_c = RandomForestRegressor(**params)
rf_c.fit(rf_x_train,y_casual)
print('casual:',rf_c.score(rf_x_train,y_casual))

rf_r = RandomForestRegressor(**params)
rf_r.fit(rf_x_train,y_registered)
print('registered:',rf_r.score(rf_x_train,y_registered))
casual: 0.9726067525351507
registered: 0.9808557797583348
#xgb
import xgboost as xgb
xgb_c = xgb.XGBRegressor(max_depth=5, learning_rate=0.1, random_state = 0,n_estimators=200)
xgb_c.fit(gb_x_train, y_casual)
print('casual:',xgb_c.score(gb_x_train,y_casual))

xgb_r = xgb.XGBRegressor(max_depth=5, learning_rate=0.1, random_state = 0,n_estimators=200)
xgb_r.fit(gb_x_train, y_registered)
print('registered:',xgb_r.score(gb_x_train,y_registered))
casual: 0.9235170841306428
registered: 0.9712917213282761
#GB(没有xgb的效果好,弃之)
from sklearn.ensemble import GradientBoostingRegressor

params2 = {'n_estimators': 150, 
           'max_depth': 5, 
           'random_state': 0, 
           'min_samples_leaf' : 10, 
           'learning_rate': 0.1, 
           'subsample': 0.7, 
           'loss': 'ls'}

gb_c = GradientBoostingRegressor(**params2)
gb_c.fit(gb_x_train,y_casual)
print('casual:',gb_c.score(gb_x_train,y_casual))

gb_r = GradientBoostingRegressor(**params2)
gb_r.fit(gb_x_train,y_registered)
print('registered:',gb_r.score(gb_x_train,y_registered))
casual: 0.9195514835772132
registered: 0.968499680058303
rf_pre_count = np.exp(xgb_c.predict(gb_x_test))+np.exp(rf_r.predict(rf_x_test))-2
xgb_pre_count = np.exp(xgb_c.predict(gb_x_test))+np.exp(xgb_r.predict(gb_x_test))-2

pre_count=np.round(0.2*rf_pre_count+0.8*xgb_pre_count,0)#最后记得round一下
submit = pd.DataFrame({'datetime':x_date,'count':pre_count})
submit.to_csv('/kaggle/working/submisssion.csv',index=False)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/804072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Selenium自动化元素定位方式与浏览器测试脚本

Selenium八大元素定位方法 Selenium可以驱动浏览器完成各种操作&#xff0c;比如模拟点击等。要想操作一个元素&#xff0c;首先应该识别这个元素。人有各种的特征&#xff08;属性&#xff09;&#xff0c;我们可以通过其特征找到人&#xff0c;如通过身份证号、姓名、家庭住…

力扣 738. 单调递增的数字

题目来源&#xff1a;https://leetcode.cn/problems/monotone-increasing-digits/description/ C题解&#xff1a;像1234就可以直接返回1234&#xff0c;像120需要从个位往高位遍历&#xff0c;2比0大&#xff0c;那么2减一成为1&#xff0c;0变成9&#xff0c;变成119。 clas…

商品分类中如何调整商品的顺序

为了更好的展示效果&#xff0c;商家可能经常需要在商品分类中&#xff0c;重新移动产品的顺序&#xff0c;比如将某个商品上移、下移、移动到顶部等。那么&#xff0c;在商品分类中如何进行这样的调整设置呢&#xff1f; 步骤一&#xff1a;查询分类下面的商品 在商品管理中…

计算机视觉(四)神经网络与典型的机器学习步骤

文章目录 神经网络生物神经元人工神经元激活函数导数 人工神经网络“层”的通俗理解 前馈神经网络Delta学习规则前馈神经网络的目标函数梯度下降输出层权重改变量 误差方向传播算法误差传播迭代公式简单的BP算例随机梯度下降&#xff08;SGD&#xff09;Mini-batch Gradient De…

随笔03 考研笔记整理

图源&#xff1a;文心一言 上半年的博文整理&#xff0c;下半年依然会更新考研类的文章&#xff0c;有需要的小伙伴看向这里~~&#x1f9e9;&#x1f9e9; 另外&#xff0c;这篇文章可能是我上半年的努力成果之一&#xff0c;因此仅关注博主的小伙伴能够查看它~~&#x1f9e…

Hum Brain Mapp:脑电图中的性别相关模式及其在机器学习分类器中的相关性

导读 深度学习越来越多地用于从脑电图(EEG)数据中检测神经和精神疾病&#xff0c;但该方法容易无意中纳入训练数据的偏差并利用不合理的模式。最近的研究表明&#xff0c;深度学习可以通过EEG检测性别&#xff0c;这意味着在基于深度学习的疾病检测器中可能存在与性别相关的偏…

【Three.js】Three.js中的纹理—图像应用和属性调整

写在前面&#xff1a; Three.js是一种强大的JavaScript库&#xff0c;用于创建基于Web的交互式3D图形和动画。在Three.js中&#xff0c;纹理是一项重要的功能&#xff0c;它允许我们将图像应用到几何体对象上&#xff0c;并通过调整纹理的属性来实现更丰富的视觉效果。 本文将介…

使用PyGWalker可视化分析表格型数据

大家好&#xff0c;可以想象一下在Jupyter Notebook中拥有大量数据&#xff0c;想要对其进行分析和可视化。PyGWalker就像一个神奇的工具&#xff0c;能让这项工作变得超级简单。它能获取用户的数据&#xff0c;并将其转化为一种特殊的表格&#xff0c;可以与之交互&#xff0c…

PostgreSQL中如何配置Huge page的数量

在了解如在PG中如何配置大页之前&#xff0c;我们先要对大页进行一定的了解&#xff0c;为什么要配置大页&#xff0c;配置大页的好处有哪些。 我们日常的操作系统中&#xff0c;程序不直接使用内存&#xff0c;而是使用虚拟内存地址来处理内存分配&#xff0c;避免计算的复杂…

C++数据结构笔记(11)二叉树的#号创建法及计算叶子节点数

首先分享一段计算叶子节点数目的代码&#xff0c;如下图&#xff1a; 不难发现&#xff0c;上面的二叉树叶子节点数目为4。我们可以采用递归的方式&#xff0c;每当一个结点既没有左结点又没有右节点时&#xff0c;即可算为一个叶子结点。 int num0; //全局变量&#xff0c;代…

Linux--多个源文件编译成同一个可执行文件

写法一&#xff1a;不推荐 写法二、推荐 $&#xff1a;代表目标文件 $^&#xff1a;代表生成目标文件的所有源文件

收藏这11个插画网站,插画师必备!

无论是在哪种设计工作中&#xff0c;插画素材都是比较常用的素材。今天本文整理了11个好用的插画工具&#xff0c;能帮助设计师轻松绘制出插画&#xff0c;一起来看看吧&#xff01; 1、即时设计 即时设计是一款国产的&#xff0c;省心省力的插画工具。它为设计师提供了简单易…

【Git】Git的概念安装工作区-暂存区-版本库

文章目录 Git概念-版本控制器Git安装Centos平台&ubuntu Git基本操作创建Git本地仓库配置Git 认识⼯作区、暂存区、版本库添加文件查看.git文件总结添加文件场景2 Git概念-版本控制器 引入 我们在编写各种⽂档时&#xff0c;为了防⽌⽂档丢失&#xff0c;更改失误&#xff0…

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作 基础半导体器件领域的高产能生产专家Nexperia&#xff08;安世半导体&#xff09;近日宣布与国际著名的为汽车行业提供先进电子器件的供应商 KYOCERA AVX Components (Salzburg) GmbH 建立合作关系&am…

【弹力设计篇】聊聊隔离设计

为什么需要隔离设计 隔离其实就是Bulkheads&#xff0c;隔板。在生活中隔板的应用主要在船舱中进行设计&#xff0c;目的是为了避免因一处漏水导致整个船都沉下去。可以将故障减少在一定的范围内&#xff0c;而不是整个船体。 从架构演变来说的话&#xff0c;大多数系统都是从…

兵兵数码:网络机顶盒哪个好?2023最新网络机顶盒排名

网络机顶盒让电视机重生&#xff0c;解决卡顿、资源少、广告多等问题&#xff0c;我们每年都会进行网络机顶盒测评&#xff0c;今年已经测评过17款&#xff0c;通过多角度对比筛选了五款表现最佳的产品整理成网络机顶盒排名&#xff0c;近期想买网络机顶盒不知道网络机顶盒哪个…

工具篇-Mysql 性能优化

文章目录 前言一、Mysql 性能问题&#xff1a;1.1 一条sql 的执行流程&#xff1a;1.2 MySQL 可能出现的性能问题&#xff1a; 二、优化&#xff1a;2.1 硬件层面&#xff1a;2.2 软件层面&#xff1a;2.2 .1 mysql 参数配置优化&#xff1a;2.2.1.1 mysql 服务端连接优化&…

【Golang】Golang进阶系列教程--为什么 Go 语言 struct 要使用 tags

文章目录 前言struct tags 的使用使用反引号避免使用空格避免重复使用标准化的 tag 名称多个 tag 值 struct tags 的原理struct tags 的优势常用的 struct tags参考文章&#xff1a; 前言 在 Go 语言中&#xff0c;struct 是一种常见的数据类型&#xff0c;它可以用来表示复杂…

【MMdetection3d】Step1:环境搭建

Step1:环境搭建 1.创建并激活虚拟环境1.1 用官方Pytorch指令安装&#xff01;1.2 用官方mmcv指令安装&#xff01; 2 安装MMDetection3 克隆编译mmdetection3d4 环境测试5 测试demo 在Conda虚拟环境中搭建MMdetection3d环境 1.创建并激活虚拟环境 conda create -n mm3d python…

JavaEE简单示例——在使用Tomcat的时候可能出现的一些报错

简单介绍&#xff1a; 在我们之前使用Tomcat的时候&#xff0c;经常会出现在启动的时候因为一些报错导致项目无法正常的启动&#xff0c;我们就对一些比较常见的报错来看一下可能导致的原因&#xff0c;以及出现报错之后如何去解决。 严重: Failed to initialize end point a…