지난 포스팅에서 코드를 분석해봤다.
예측 정확도를 높이려면 "정제된 데이터" 로 "올바른 모델" 을 사용하면 되는데, 지난 포스팅에서는
"주어진 데이터" 에 "Random forest" 모델을 사용하여 예측하였다.
데이터를 정제하기에 앞서, 어떤 데이터가 어떻게 사용되는지 보자.
우선 datetime 을 파싱하여 연, 월, 일, 시, 분, 초 요일 로 변경해준다.
1 2 3 4 5 6 7 | 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 train["dayofweek"] = train["datetime"].dt.dayofweek | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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="Box Plot On Count") axes[0][1].set(xlabel='Season', ylabel='Count',title="Box Plot On Count Across Season") axes[1][0].set(xlabel='Hour Of The Day', ylabel='Count',title="Box Plot On Count Across Hour Of The Day") axes[1][1].set(xlabel='Working Day', ylabel='Count',title="Box Plot On Count Across Working Day") corrMatt = train[["temp","atemp","casual","registered","humidity","windspeed","count"]].corr() 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) | cs |
아래 그래프는 각 행/열 들의 관련성(correlation) 을 보여주는데, temp 와 atemp 의 관련성은 98% 이다.
대각선을 따라서 1로 표기된 것은 모든 피쳐들이 자신과의 관련성이 100%이기 때문이다.
이 밖에 아래 코드를 이용하면 시간별, 요일별, 날씨별, 계절별 대여량도 분석할 수 있으니, 한 번 해보자.
1 2 3 4 5 6 7 8 9 10 11 12 | fig,(ax1,ax2,ax3,ax4,ax5)= plt.subplots(nrows=5) fig.set_size_inches(18,25) 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) | cs |
아래는 온도, 풍속, 습도에 따른 대여량을 보여주는 코드이다.
1 2 3 4 5 | 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) | cs |
가운데 풍속 그래프가 이상하게 나온다. 풍속이 0일 때 대여량이 분포돼있고, 중간에 끊긴 후 다시 대여량이 보인다.
이건 풍속이 5 정도일 때는 대여를 하지 않는다기보다는, 몇몇 풍속값이 0으로 잘못 기재되었다고 해석하는 편이 합리적이다.
풍속이 0 인 값들을 고쳐줘보자.
로직은 앞에서 대여량을 예측한 것과 동일하다.
1. 풍속에 영향을 줄만한 피쳐들을 고르고
2. 모델을 정한다. (이전 포스팅에서와 마찬가지로, 랜덤포레스트 사용)
3. 그리고 피팅을 시켜주면 끝.
(유투브 강좌 에서 코드를 얻었다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | from sklearn.ensemble import RandomForestClassifier def predict_windspeed(data): # 풍속이 0인것과 아닌 것을 나누어 준다. dataWind0 = data.loc[data['windspeed'] == 0] dataWindNot0 = data.loc[data['windspeed'] != 0] # 풍속을 예측할 피처를 선택한다. wCol = ["season", "weather", "humidity", "month", "temp", "year", "atemp"] # 풍속이 0이 아닌 데이터들의 타입을 스트링으로 바꿔준다. dataWindNot0["windspeed"] = dataWindNot0["windspeed"].astype("str") # 랜덤포레스트 분류기를 사용한다. rfModel_wind = RandomForestClassifier() # wCol에 있는 피처의 값을 바탕으로 풍속을 학습시킨다. rfModel_wind.fit(dataWindNot0[wCol], dataWindNot0["windspeed"]) # 학습한 값을 바탕으로 풍속이 0으로 기록된 데이터의 풍속을 예측한다. wind0Values = rfModel_wind.predict(X = dataWind0[wCol]) # 값을 다 예측 후 비교해 보기 위해 # 예측한 값을 넣어 줄 데이터 프레임을 새로 만든다. predictWind0 = dataWind0 predictWindNot0 = dataWindNot0 # 값이 0으로 기록된 풍속에 대해 예측한 값을 넣어준다. predictWind0["windspeed"] = wind0Values # dataWindNot0 0이 아닌 풍속이 있는 데이터프레임에 예측한 값이 있는 데이터프레임을 합쳐준다. data = predictWindNot0.append(predictWind0) # 풍속의 데이터 타입을 float으로 지정해 준다. data["windspeed"] = data["windspeed"].astype("float") data.reset_index(inplace=True) data.drop('index', inplace=True, axis=1) return data | cs |
위 코드를 적용해서 풍속을 시각화해보면,
위와 같이 풍속 0에 분포되어 있던 값들이 아래 그래프를 보면 사라지고 다른 값을 갖는다.
이제 새로운 풍속값을 얻었으니, 정제된 데이터로 다시 모델링을 하면, 더 좋은 값을 얻을 수 있을 것이다.
다음 포스팅은 새로운 데이터와 캐글 문제를 다뤄보고자 한다.