Be Brave, Be Humble

빅데이터 분석기사 실기 Part5. 파이썬으로 초보 분석가 탈출하기_3 (프리렉) 본문

Statistics/Data Science

빅데이터 분석기사 실기 Part5. 파이썬으로 초보 분석가 탈출하기_3 (프리렉)

해쨔니 2022. 10. 25. 17:38

Open in Colab 누르면 코랩으로 이동 가능

 

프리렉 교재 마지막 포스팅입니다. 가독성 제로 스파이더로 작성된 코드 읽으시느라 고생 많으셨습니다.

In [ ]:

 

# -*- coding: utf-8 -*-
"""
Created on Thu Jun 23 22:37:56 2022

@author: FullSun

"""

###############################################
###   Part5. 파이썬으로 초보 분석가 탈출하기   ###
###############################################

#---------------------------------------------
#             3. 예측 모델 수행하기
#---------------------------------------------

#--------- <3-1> 데이터 탐색하기 ---------#

## 데이터 가져오기
import pandas as pd

X_train = pd.read_csv("C:/Users/bike_x_train.csv", encoding='cp949')
X_test = pd.read_csv("C:/Users/bike_x_test.csv", encoding='cp949')
y_train = pd.read_csv("C:/Users/bike_y_train.csv", encoding='cp949')

print(X_train.head(3).T)
print(y_train.head(3).T)

## 행/열 확인하기
print(X_train.shape, X_test.shape, y_train.shape)

## 요약정보 확인하기
print(X_train.info())
# datetime obj, 계절/공휴일/근무일/날씨: 범주지만 숫자로 코딩
print(X_train['계절'].unique()) # [1 2 3 4]
print(X_train['공휴일'].unique()) # [0 1]
print(X_train['근무일'].unique()) # [0 1]
print(X_train['날씨'].unique()) # [1 2 3 4]

## 기초통계량 확인하기
print(X_train.describe().T)

## 독립변수와 종속변수 관계 확인하기
# 데이터 통합
data = pd.concat([X_train, y_train], axis=1)
# 계절에 따른 count 합계
print(data.groupby(['계절'])['count'].sum()) # 가을이 봄에 비해 두배 -> 관련있음
# 공휴일에 따른 count 합계
print(data.groupby(['공휴일'])['count'].sum()) # 관련있음
# 근무일에 따른 count 합계
print(data.groupby(['근무일'])['count'].sum()) # 관련있음
# 날씨에 따른 count 합계
print(data.groupby(['날씨'])['count'].sum()) # 관련있음

# 연속형변수 상관분석 => 책엔 없음
print(data[['온도', '체감온도', '습도', '풍속','count']].corr()) 
# 체감온도, 풍속 제외


#--------- <3-2> 전처리하기 ---------#

## 파생변수 만들기
''' ** datetime 칼럼은 자전거를 대여한 년/월/일/시간대로 이루어짐 '''
# **datetime 칼럼의 데이터 타입을 날짜 타입으로 변환하기
X_train['datetime'] = pd.to_datetime(X_train['datetime'])

# [1] dt.year 키워드로 연도 추출
X_train['year'] = X_train['datetime'].dt.year
print(X_train['year'].unique()) # 2011, 2012 

# [2] dt.month로 월 추출
X_train['month'] = X_train['datetime'].dt.month
print(X_train['month'].unique()) # 1~12

# [3] dt.day로 일 추출
X_train['day'] = X_train['datetime'].dt.day
print(X_train['day'].unique()) # 1~19

# [4] dt.hour로 시간 추출
X_train['hour'] = X_train['datetime'].dt.hour
print(X_train['hour'].unique) # 1~23

# [5] dt.dayofweek로 요일 추출
X_train['dayofweek'] = X_train['datetime'].dt.dayofweek
print(X_train['dayofweek'].unique()) # 0~6

# 파생변수가 포함되도록 data업데이트
data2 = pd.concat([X_train, y_train], axis=1)
# 추가변수 칼럼별 count 추세 확인
print(data2.groupby(['year'])['count'].sum()) # 2012년도가 두배
print(data2.groupby(['month'])['count'].sum()) # 1,2월에 적지만 특정 달이 두드러지게 많진 않음 -> 제외
print(data2.groupby(['day'])['count'].sum()) # 제외
print(data2.groupby(['hour'])['count'].sum()) # 출퇴근 시간에 높음
print(data2.groupby(['dayofweek'])['count'].sum()) # 큰 차이 없음
X_train = X_train.drop(columns = (['month', 'day', 'dayofweek']))

# 테스트셋에도 적용하기
X_test['datetime'] = pd.to_datetime(X_test['datetime'])
X_test['year'] = X_test['datetime'].dt.year
X_test['hour'] = X_test['datetime'].dt.hour

## 불필요한 칼럼 삭제하기
X_test_datetime = X_test['datetime']
X_train = X_train.drop(columns = ['datetime'])
X_test = X_test.drop(columns = ['datetime'])
y_train = y_train.drop(columns = ['癤풼atetime'])

X_train_del = X_train.drop(columns=['체감온도', '풍속'])
X_test_del = X_test.drop(columns=['체감온도', '풍속'])

X_train_backup = X_train
X_test_backup = X_test


#--------- <3-3> 학습하고 평가하기 ---------#

## 데이터 분리하기
from sklearn.model_selection import train_test_split
X_train1, X_val1, y_train1, y_val1 = train_test_split(X_train, y_train,
                                                      test_size=0.2, random_state=66)
X_train2, X_val2, y_train2, y_val2 = train_test_split(X_train_del, y_train,
                                                      test_size=0.2, random_state=66)
print(X_train1.shape, X_val1.shape, y_train1.shape, y_val1.shape)

## 데이터 학습 및 파라미터 튜닝
from xgboost import XGBRegressor
# 일반적으로 많이 쓰는 파라미터
model1 = XGBRegressor(n_estimtors=100, max_depth=3, random_state=66)
model1.fit(X_train1, y_train1)
model1_del = XGBRegressor(n_estimators=100, max_depth=3, random_state=66)
model1_del.fit(X_train2, y_train2)

# 하이퍼 파라미터 튜닝
model2 = XGBRegressor(n_estimators=200, max_depth=5, random_state=66)
model2.fit(X_train1, y_train1)
model2_del = XGBRegressor(n_estimators=200, max_depth=5, random_state=66)
model2_del.fit(X_train2, y_train2)

# 예측하기
# !!!!!!!!!! ** 예측된 결과에 음수가 있을 수 있음. 하지만 count는 양수이므로 모두 전환!!!!!!!!!!
y_val1_predicted = pd.DataFrame(model1.predict(X_val1)).rename(columns={0:'count'})
y_val1_predicted_del = pd.DataFrame(model1_del.predict(X_val2)).rename(columns={0:'count'})
y_val2_predicted = pd.DataFrame(model2.predict(X_val1)).rename(columns={0:'count'})
y_val2_predicted_del = pd.DataFrame(model2_del.predict(X_val2)).rename(columns={0:'count'})

## 평가하기
# print(dir(sklearn.metrics))
from sklearn.metrics import r2_score, roc_auc_score
print(r2_score(y_val1, y_val1_predicted), '\n',
      r2_score(y_val1, y_val1_predicted_del), '\n',
      r2_score(y_val1, y_val2_predicted), '\n', # => best
      r2_score(y_val1, y_val2_predicted_del))

## 최종 결과 예측하기
y_test_predicted = pd.DataFrame(model2.predict(X_test)).rename(columns={0:'count'})
# !!!!!!!!!! ** 예측된 결과에 음수가 있을 수 있음. 하지만 count는 양수이므로 모두 전환!!!!!!!!!!
y_test_predicted[y_test_predicted['count'] < 0] = 0

## 결과 제출하기
final = pd.concat([X_test_datetime, y_test_predicted], axis=1)
final.to_csv('C:/Users/bike_fin.csv', index=False)
final = pd.read_csv('C:/Users/bike_fin.csv')


#---------------------------------------------
#                 최종 제출 코드
#---------------------------------------------
# 데이터 가져오기
import pandas as pd
X_train = pd.read_csv("C:/Users/bike_x_train.csv", encoding='cp949')
X_test = pd.read_csv("C:/Users/bike_x_test.csv", encoding='cp949')
y_train = pd.read_csv("C:/Users/bike_y_train.csv", encoding='cp949')

print(X_train.info()) # datetime, 계절, 공휴일, 근무일, 날씨 범주형
print(X_train.describe().T ) # 결측치 없음
# 전처리하기
data = pd.concat([X_train, y_train], axis=1)
print(data.groupby(['계절'])['count'].sum(),'\n', 
      data.groupby(['공휴일'])['count'].sum(),'\n', 
      data.groupby(['근무일'])['count'].sum(),'\n', 
      data.groupby(['날씨'])['count'].sum(),'\n')
# 전부 포함
print(X_train['계절'].unique(),'\n', 
      X_train['공휴일'].unique(),'\n', 
      X_train['근무일'].unique(),'\n', 
      X_train['날씨'].unique(),'\n', )

X_train['datetime'] = pd.to_datetime(X_train['datetime'])
X_train['year'] = X_train['datetime'].dt.year
X_train['hour'] = X_train['datetime'].dt.hour
X_train = X_train.drop(columns = ['datetime'])

X_test['datetime'] = pd.to_datetime(X_test['datetime'])
X_test_datetime = X_test['datetime']
X_test['year'] = X_test['datetime'].dt.year
X_test['hour'] = X_test['datetime'].dt.hour
X_test = X_test.drop(columns = ['datetime'])

y_train = y_train.drop(columns = ['癤풼atetime'])

# 데이터 분리
from sklearn.model_selection import train_test_split
X_train1, X_val1, y_train1, y_val1 = train_test_split(X_train, y_train,
                                                      test_size=0.2, random_state=66)

# 모델 학습 및 평가
from xgboost import XGBRegressor
model1 = XGBRegressor(n_estimators=100, max_depth=3, random_state=66)
model2 = XGBRegressor(n_estimators=200, max_depth=5, random_state=66)

model1.fit(X_train1, y_train1)
y_val1_pred = pd.DataFrame(model1.predict(X_val1)).rename(columns = {0:'count'})
model2.fit(X_train1, y_train1)
y_val2_pred = pd.DataFrame(model2.predict(X_val1)).rename(columns = {0:'count'})

y_val1_pred[y_val1_pred['count'] < 0] = 0 
y_val2_pred[y_val2_pred['count'] < 0] = 0 

from sklearn.metrics import r2_score
print(r2_score(y_val1, y_val1_pred), '\n',
      r2_score(y_val1, y_val2_pred))

# 최종 모형 피팅 및 저장
y_test_pred = pd.DataFrame(model2.predict(X_test)).rename(columns = {0:'count'})
y_test_pred[y_test_pred['count'] < 0 ] = 0
final = pd.concat([X_test_datetime, y_test_pred], axis=1)
final.to_csv('C:/Users/bike_fin2.csv', index=False)
final = pd.read_csv('C:/Users/bike_fin2.csv')
print(final.head(10))
Comments