슬코생

[kaggle] Bike Sharing Demand 공공자전거 수요 예측 모델 #1 본문

Data/Project

[kaggle] Bike Sharing Demand 공공자전거 수요 예측 모델 #1

ashbeen 2020. 1. 29. 21:24

타이타닉 캐글 생존자 예측모델

fig, (ax1, ax2) =plt.subplots(nrows=1,ncols=2)
fig.set_size_inches(18,4)

sns.barplot(data=train, x="year",y="count",ax=ax1)
sns.barplot(data=train, x="month",y="count",ax=ax2)

fig, ax3 = plt.subplots(nrows=1, ncols=1)
fig.set_size_inches(18,4)

sns.barplot(data=train, x="year_month",y="count",ax=ax3)

해당 대회는 캐글의 워싱턴 공공 자전거 데이터를 바탕으로 수요를 예측하는 모델을 만드는 것이다.

대회링크는 http://www.kaggle.com/c/bike-sharing-demand

 

Bike Sharing Demand

Forecast use of a city bikeshare system

www.kaggle.com

내 커널은 https://www.kaggle.com/onetwojab/bike-sharing-demand-practice

 

Bike Sharing Demand practice

Explore and run machine learning code with Kaggle Notebooks | Using data from Bike Sharing Demand

www.kaggle.com


*순서는 커널 코드 리뷰로 진행된다! *

✔ Step1. 데이터 불러오기

먼저 이 대회는 classification과 regression 중 자전거 대여량을 예측하는 문제이므로 regression에 해당된다.

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# 노트북 안에 그래프를 그리기 위해
%matplotlib inline 

# 그래프에서 격자로 숫자 범위가 눈에 잘 띄도록 ggplot 스타일 사용
plt.style.use('ggplot')

# 그래프에서 마이너스 폰트 깨지는 문제에 대한 대처
mpl.rcParams['axes.unicode_minus']= False
train = pd.read_csv("../input/bike-sharing-demand/train.csv", parse_dates = ["datetime"])
train.shape

데이터는 이 정도!

모든 kaggle의 문제에서 제공되는 데이터는 학습 데이터(train)과 예측 데이터(test)가 있다. test data에는 'casual','registered','count'가 빠져 있다. 우리가 예측해야 할 대상은 'count'로 수요 대수이다. 이는 casual과 registered의 을 더한 값이다. 또한 이 데이터 셋에는 null data가 없다.

train["year"]=train["datetime"].dt.year
train["month"]=train["datetime"].dt.month
train["day"]=train["datetime"].dt.day
train["hour"]=train["datetime"].dt.hour
train["minute"]=train["datetime"].dt.minute
train["second"]=train["datetime"].dt.second

위 코드는 datetime을 연도/월/일/시간/분/초로 나눠주는 코드로, 후에 계절별로 데이터셋의 연관성을 알고 싶을 때 사용하기 위하여 미리 분리하였다.

figure, ((ax1, ax2, ax3),(ax4, ax5,ax6))=plt.subplots(nrows=2,ncols=3)
figure.set_size_inches(18,8)

sns.barplot(data=train, x="year", y="count", ax=ax1)
sns.barplot(data=train, x="month", y="count", ax=ax2)
sns.barplot(data=train, x="day", y="count", ax=ax3)
sns.barplot(data=train, x="hour", y="count", ax=ax4)
sns.barplot(data=train, x="minute", y="count", ax=ax5)
sns.barplot(data=train, x="second", y="count", ax=ax6)

ax1.set(ylabel='Count', title ="Year rental amount")
ax2.set(ylabel='month', title ="Month rental amount")
ax3.set(ylabel='day', title ="Day rental amount")
ax4.set(ylabel='hour', title ="Hour rental amount")

깨끗하게 잘나옴. 헤헤 이제 한 번 상관성에 대해 알아보자

가장 흥미로웠던 점은 Month rental amount에 해당하는 부분이었는데, 겨울로 분리되는 12월의 경우 초봄인 3~4월의 대여량과 비슷하다는 점이었다. 워싱턴의 날씨 변화는 우리나라의 사계절과 비슷하다.

또한 hour 파트에서 아침7시와 저녁 6~7시의 수요량이 다른 시간대들과 비교했을 때 굉장히 높은 것을 알 수 있다. 이는 출퇴근길에 자전거를 많이 이용하는 사람들이 많다고 예측해 볼 수 있다. (주말과 나눠서 보는 것이 필요하다.)

일별 대여량은 1일부터 19일까지만 있고 나머지 날짜의 경우는 test데이터에 들어가있다. 따라서 이 변수는 피쳐로 사용하면 안 된다!

fig, axes = plt.subplots(nrows=2, ncols=2)
fig.set_size_inches(12,10)
sns.boxplot(data=train, y="count", orient= "v", ax=axes[0][0])
sns.boxplot(data=train, y="count", x = "season",orient= "v", ax=axes[0][1])
sns.boxplot(data=train, y="count", x="hour",orient= "v", ax=axes[1][0])
sns.boxplot(data=train, y="count", x="workingday",orient= "v", ax=axes[1][1])

axes[0][0].set(ylabel='Count',title="Rental amount")
axes[0][1].set(xlabel='Season',ylabel='Count',title="Seasonal Rental amount")
axes[1][0].set(xlabel='Hour of The Day',ylabel='Count',title="Hour Rental amount")
axes[1][1].set(xlabel='Working Day',ylabel='Count',title="Working or not Rental amount")

위 그래프를 분석해보면, 대여량은 특정 기간에 머물러 있고 특히 근무일이 아닐 때 대여량이 더 많은 것을 알 수 있다.

fig, (ax1,ax2,ax3,ax4,ax5)=plt.subplots(nrows=5)
fig.set_size_inches(18,25)

# 시간대별 대여량을 hue에 따라 보는거!
sns.pointplot(data=train, x="hour",y="count",ax=ax1)

sns.pointplot(data=train, x="hour",y="count", hue="workingday",ax=ax2)

sns.pointplot(data=train, x="hour",y="count", hue="dayofweek",ax=ax3)

sns.pointplot(data=train, x="hour",y="count", hue="weather",ax=ax4)

sns.pointplot(data=train, x="hour",y="count", hue="season",ax=ax5)

pointplot을 사용하면 시간대별, 일별 분석 시 많은 도움이 된다.

히트맵을 그려보기 위해 변수들을 최소화 해야한다.

corrMatt = train[["temp","atemp","casual","registered","humidity","windspeed","count"]]
corrMatt = corrMatt.corr()
print(corrMatt)
mask =np.array(corrMatt)
mask[np.tril_indices_from(mask)]=False
fig,ax = plt.subplots()
fig.set_size_inches(20,10)
sns.heatmap(corrMatt, mask=mask,vmax=.8,square= True, annot=True)

Heatmap Output

temp, humidity, windspeed는 상관관계가 거의 없다.

registered, casual는 상관관계가 높다!

atemp와 temp는 0.98로 상관관계가 높지만 온도와 체감온도로 피쳐로 사용하기에 적합하지 않을 수 있다.

✔ Regplot 산점도 plot

fig,(ax1,ax2,ax3) = plt.subplots(ncols=3)
fig.set_size_inches(12,5)
sns.regplot(x="temp",y="count",data=train, ax=ax1)
sns.regplot(x="windspeed",y="count",data=train, ax=ax2)
sns.regplot(x="humidity",y="count",data=train, ax=ax3)

windspeed의 경우 0에 숫자가 몰려 있는 것으로 보아, 아마도 관측되지 않은 수치에 대해 0으로 기록된 것이 아닐까 추측한다. 

2탄에서 진행하겠슴다

Comments