*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*
1. bike 데이터셋
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
bike_df = pd.read_csv('/content/drive/MyDrive/KDT/6. 머신러닝과 딥러닝/Data/bike.csv')
bike_df
bike_df.info()
- datetime: 날짜
- count: 대여 개수
- holiday: 휴일
- workingday: 근무일
- temp: 기온
- feels_like: 체감온도
- temp_min: 최저온도
- temp_max: 최고온도
- pressure: 기압
- humidity: 습도
- wind_speed: 풍속
- wind_deg: 풍향
- rain_1h: 1시간당 내리는 비의 양
- snow_1h: 1시간당 내리는 눈의 양
- clouds_all: 구름의 양
- weather_main: 날씨
# 각 column 통계치
bike_df.describe()
sns.displot(bike_df['count'])
sns.boxplot(y=bike_df['count'])
sns.scatterplot(x='feels_like', y='count', data=bike_df, alpha=0.3)
# alpha=0.3은 점의 투명도를 나타내며, 0에 가까울수록 투명하고 1에 가까울수록 불투명
데이터가 밀집된 지역을 시각적으로 파악
sns.scatterplot(x='pressure', y='count', data=bike_df, alpha=0.3)
sns.scatterplot(x='wind_speed', y='count', data=bike_df, alpha=0.3)
sns.scatterplot(x='wind_deg', y='count', data=bike_df, alpha=0.3)
bike_df.isna().sum()
# null값 확인
bike_df = bike_df.fillna(0)
bike_df.isna().sum()
# null값 0 채우기 처리
bike_df.info()
bike_df['datetime'] = pd.to_datetime(bike_df['datetime'])
# datetime으로 바꾸기
bike_df.info()
bike_df
# datetime을 이용해서 year, month, hour 파생변수 생성
bike_df['year'] = bike_df['datetime'].dt.year
bike_df['month'] = bike_df['datetime'].dt.month
bike_df['hour'] = bike_df['datetime'].dt.hour
bike_df.head()
bike_df['date'] = bike_df['datetime'].dt.date
plt.figure(figsize=(14,4))
sns.lineplot(x='date', y='count', data=bike_df)
plt.xticks(rotation=45)
plt.show()
# 2019년 월별 자전거 대여 갯수
bike_df[bike_df['year'] == 2019].groupby('month')['count'].mean()
# 2020년 월별 자전거 대여 갯수
bike_df[bike_df['year'] == 2020].groupby('month')['count'].mean()
# covid
# 2020-04-01 이전: precovid
# 2020-04-01 이후 ~ 2021-04-01 이전: covid
# 2021-04-01 이후: postcovid
# 파생변수 covid
def covid(date):
if str(date) < '2020-04-01':
return 'precovid'
elif str(date) < '2021-04-01':
return 'covid'
else:
return 'postcovid'
# 콜백함수 사용
bike_df['date'].apply(covid)
bike_df['covid'] = bike_df['date'].apply(lambda date: 'precovid' if str(date) < '2020-04-01' else 'covid' if str(date) < '2021-04-01' else 'postcovid')
bike_df
# season
# 12월 ~ 2월: winter
# 3월 ~ 5월: spring
# 6월 ~ 8월: summer
# 9월 ~ 11월: fall
bike_df['season'] = bike_df['month'].apply(lambda x: 'winter' if x==12
else 'fall' if x>=9
else 'summer' if x>=6
else 'spring' if x >=3
else 'winter')
bike_df[['month' , 'season']]
# day_night
# 21시 이후: nighjt
# 19시 이후: late evening
# 17시 이후: early evening
# 15시 이후: late afternoon
# 13시 이후: early afternoon
# 11시 이후: late morning
# 6시 이후: early morning
bike_df['day_night'] = bike_df['hour'].apply(lambda x: 'night' if x>=21
else 'late evening' if x>=19
else 'early evening' if x>=17
else 'late afternoon' if x>=15
else 'early afternoon' if x>=13
else 'late morning' if x>=11
else 'early morning' if x>=6
else 'night')
bike_df.head()
bike_df.drop(['datetime', 'month', 'date', 'hour'], axis=1, inplace=True)
bike_df.head()
bike_df.info()
for i in ['weather_main', 'covid', 'season', 'day_night']:
print(i, bike_df[i].nunique())
bike_df['weather_main'].unique()
bike_df = pd.get_dummies(bike_df, columns=['weather_main', 'covid', 'season', 'day_night'])
pd.set_option('display.max_columns', 40)
bike_df.head()
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(bike_df.drop('count', axis=1), bike_df['count'], test_size=0.2, random_state=2024)
X_train.shape, y_train.shape
X_test.shape, y_test.shape
2. 의사결정나무(Decision Tree)
- 데이터를 분석하고 패턴을 파악하여 결정 규칙을 나무 구조로 나타낸 기계학습 알고리즘
- 간단하고 강력한 모델 중 하나로, 분류와 회귀 문제에 모두 사용
- 지니계수(지니 불순도, Gini Impurity): 분류 문제에서 특정 노드의 불순도를 나타내는데, 노드가 포함하는 클래스들이 혼잡되어 있는 정도를 나타냄
- 0에서 1까지의 값을 가지며, 0에 가까울수록 노드의 값이 불순도가 없음을 의미
- 로그 연산이 없어 계산이 상대적으로 빠름
- 엔트로피: 어떤 집합이나 데이터의 불확실성, 혼잡도를 나타내는데, 노드의 불순도를 측정하는데 활용
- 0에서 무한대까지의 값을 가지며, 0에 가까울수록 노드의 값이 불순도가 없음을 의미
- 로그 연산이 포함되어 있어 계산이 복잡
- 오버피팅(과적합): 학습데이터에서는 정확하나 테스트데이터에서는 성과가 나쁜 현상을 말함. 의사 결정 나무는 오버피팅이 매우 잘 일어남
- 오버피팅을 방지하는 방법
- 사전 가지치기: 나무가 다 자라기전에 알고리즘을 멈추는 방법
- 사후 가지치기: 나무를 끝까지 다 돌린 후 밑에서부터 가지를 쳐나가는 방법
- 오버피팅을 방지하는 방법
from sklearn.tree import DecisionTreeRegressor
# random_state는 어떤 특정한 시드값으로 고정
dtr = DecisionTreeRegressor(random_state =2024) # 결정트리 모델 가져오기
dtr.fit(X_train, y_train) # 결정트리 학습
pred1 = dtr.predict(X_test)
pred1
sns.scatterplot(x=y_test, y=pred1) # 학습된 실제값, 예측값
from sklearn.metrics import mean_squared_error
참고 : metrics - 평가지표 뜻
mean_squared_error(y_test, pred1, squared=False)
squared = false : 제곱하지 않는다는 뜻으로 루트 씌운 MSE = RMSE와 같음. -> RMSE 출력
mse를 뽑을 때, mse함수(y_test, x_test)
3. 선형 회귀 vs 의사 결정 나무
from sklearn.linear_model import LinearRegression
lr = LinearRegression() #선형회귀 모델 가져오기
lr.fit(X_train, y_train) # lr모델 학습
pred2 = lr.predict(X_test)
sns.scatterplot(x=y_test, y=pred2)
mean_squared_error(y_test, pred2, squared=False)
# RMSE
# 의사 결정 나무: 210.74186203651976
# 선형 회귀: 221.1987722244733
210.74186203651976 - 221.1987722244733
# 하이퍼 파라미터 적용
# max_depth = 결정 트리 최대 깊이 제한
# min_samples_leaf = 데이터 쪼개지는 크기 이하 제한
dtr = DecisionTreeRegressor(random_state=2024, max_depth=50, min_samples_leaf=30)
# 결정트리 최대깊이 50개, 쪼개는 크기 30개로 제한
하이퍼 파라미터(Hyperparameter) : 머신러닝에서 모델 훈련을 할 때, 모델에 설정하는 변수들(학습률, 에포크, 가중치W)의 갯수를 최적화하여 사용할 수 있게 사용자가 설정하는 것.
모델학습은 train으로, 예측값은 test로
dtr.fit(X_train, y_train)
pred3 = dtr.predict(X_test)
mean_squared_error(y_test, pred3, squared=False)
# 의사 결정 나무: 210.74186203651976
# 선형 회귀: 221.1987722244733
# 의사 결정 나무(하이퍼 파라미터 적용): 181.29247853838177
181.29247853838177 - 221.1987722244733
from sklearn.tree import plot_tree
# 결정트리 시각화 모듈
plt.figure(figsize=(24,12))
plot_tree(dtr, max_depth=5, fontsize=10)
plt.show()
plt.figure(figsize=(24,12))
plot_tree(dtr, max_depth=5, fontsize=10, feature_names=X_train.columns)
plt.show()
# 아래와 같이 무수한 질문으로 데이터를 파악해가는 과정
# 이 과정은 5단계로 이루어짐.
'Python > 머신러닝(ML)' 카테고리의 다른 글
Python(23)- 서포트 벡터 머신(SVM) (0) | 2024.06.19 |
---|---|
Python(22)- 로지스틱 회귀(Losistic Regression), 혼돈행렬 (0) | 2024.06.18 |
Python(20)- 선형회귀(Linear Regression) (0) | 2024.06.18 |
Python(19)- 타이타닉 DataSet (1) | 2024.06.11 |
Python(18)- Iris Dataset (0) | 2024.06.11 |