📄 예제에 사용한 파일
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/Python/4.머신러닝 딥러닝/bike.csv')
bike_df
bike_df.info()
✅ bike_df의 컬럼 정보 알아보기
✅ 수치형 데이터의 정보 알아보기
bike_df.describe()
✅ bike_df의 대여개수(Count)의 데이터 수를 시각화하여 알아보기
sns.displot(x=bike_df['count'])
📍 대여수가 0 쪽으로 데이터가 몰려있음
✅ boxplot을 통해 count에 대한 데이터 분포 알아보기
sns.boxplot(y=bike_df['count'])
✅ 체감온도(feels_like)에 대한 자전거 대여 개수 분포를 scatterplot을 통해 알아보기
sns.scatterplot(x='feels_like', y='count', data=bike_df, alpha=0.3)
✅ 기압(pressure)에 따른 자전거대여 개수의 분포를 scatterplot으로 알아보기
sns.scatterplot(x='pressure', y='count', data=bike_df, alpha=0.3)
✅ 바람속도(wind_speed)에 따른 자전거대여 개수의 분포를 scatterplot으로 알아보기
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)
✅ 풍향(wind_deg) 따른 자전거대여 개수의 분포를 scatterplot으로 알아보기
✅ 결측치 알아보기
bike_df.isna().sum()
bike_df.isna().mean() # 결측치에 대한 비율
✅ 결측지에 대한 비율이 높고 1시간당 비와 눈의 여부이기 때문에 오지않은 경우로 판단 ➡ 0으로 결측지 채움
bike_df = bike_df.fillna(0)
bike_df.isna().mean()
✅ 날짜를 계절과 같은 범주형 데이터로 변환
(학습 시 계절별로 영향을 미치는가에 대한 특징을 잡을 수 있음)
bike_df['datetime'] = pd.to_datetime(bike_df['datetime'])
bike_df.info()
✅ 날짜데이터를 연도, 월, 시간, 날짜별로 데이터를 알아보기 위해 새로운 파생변수로 저장
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['date'] = bike_df['datetime'].dt.date
bike_df.head()
✅ 시계열 데이터(날짜)를 lineplot을 통해 알아보기
plt.figure(figsize=(14,4)) # 그래프 크기 조정
sns.lineplot(x='date', y='count', data=bike_df)
plt.xticks(rotation=45) # x축 데이터를 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()
✅ bike_df에 'covid'라는 새로운 파생변수를 만듦
- 날짜를 계절과 같은 범주형 데이터로 바꿈(# 2020-04-01 이전: precovid
- 2021-04-01 이전 : covid
- 그 이후 : postcovid
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.tail()
✅ 'month' 컬럼으로 'season'이라는 새로운 파생변수를 만들기
- 3~5월 : spring
- 6~8 : summer
- 9~11 : fall
- 12~2 : winter
bike_df['season'] = bike_df['month'].apply(lambda month: 'winter' if month == 12 else 'fall' if month >= 9 else 'summer' if month >=6 else 'spring' if month >=3 else 'winter')
bike_df.head()
✅ 'hour'컬럼으로 'day_night'라는 새로운 파생변수 만들기
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>=16 else 'early afternoon' if x>= 13 else 'late morning' if x>=11 else 'early morning' if x>=5 else 'night')
bike_df['day_night']
✅ 모델 학습 시 필요없는 컬럼 삭제하고 저장하기
bike_df.drop(['datetime', 'month', 'date', 'hour'], axis=1, inplace=True)
bike_df.head()
✅ dtype이 object형인 컬럼 알아보기
✅ dtype이 object형인 컬럼들의 중복값을 제외한 데이터 종류와 개수 알아보기
for i in ['weather_main', 'covid', 'season', 'day_night']:
print(i, bike_df[i].nunique())
✅ weather_main의 종류를 알아보기
bike_df['weather_main'].unique()
>>> array(['Clouds', 'Clear', 'Snow', 'Mist', 'Rain', 'Fog', 'Drizzle',
'Haze', 'Thunderstorm', 'Smoke', 'Squall'], dtype=object)
✅ weather_main의 종류와 데이터 수를 boxplot으로 확인하기
plt.figure(figsize=(10,5))
sns.boxplot(x='weather_main', y='count', data=bike_df)
✅ dtype이 object형인 컬럼 원핫인코딩 하기
bike_df = pd.get_dummies(bike_df, columns=['weather_main','covid','season','day_night'])
bike_df.head()
✅ train데이터와 test데이터 나누기
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=10)
2. 의사 결정 나무(Decision Tree)
- 데이터를 분석하여 그 사이에 존재하는 패턴을 예측 가능한 규칙들의 조합으로 나타내며 그 모양이 나무와 같다고 하여 의사결정나무 라고 부름
- 회귀(Regression), 분류(Classification) 모두 가능
- 지니계수(Gini Index): 0에 가까울수록 클래스에 속한 불순도가 낮음
- 엔트로피(Entropy): 결정을 내릴만한 충분한 정보가 데이터에 없다고 보는 것. (0에 가까울수록 결정을 내릴만한 충분한 정보가 있다)
📍 지니계수와 엔트로피는 반비례 관계 - 오버피팅(과적합): 훈련데이터에서는 정확하나 테스트데이터에서는 성과가 나쁜 현상을 말함. 훈련 데이터가 적거나 노이즈가 있을 때 또는 알고리즘 자체가 나쁠 때 발생. 의사 결정 나무에서는 나무의 가지가 너무 많거나 크기가 클 때 발생
- 의사 결정 나무에서 오버피팅을 피하는 방법
- 사전 가지치기: 나무가 다 자라기 전에 알고리즘을 멈추는 방법
- 사후 가지치기: 의사 결정 나무를 끝까지 돌린 후 밑에서부터 가지를 쳐나가는 방법
from sklearn.tree import DecisionTreeRegressor
# 하이퍼 파라미터: 모델에 옵션을 주는 파라미터
# random_state: 랜덤한 값을 유지
dt = DecisionTreeRegressor(random_state=10)
# 학습
dt.fit(X_train, y_train)
# 예측
pred1 = dt.predict(X_test)
# 검증데이터와 예측값을 그래프로 표시
sns.scatterplot(x=y_test, y=pred1) # 모델이 잘 맞출수록 선형으로 나타남
2-1. 평가지표 적용하기
from sklearn.metrics import mean_squared_error
mean_squared_error(y_test, pred1, squared=False) # RMSE
>>> 228.42843328100884
3. 선형회귀 vs 의사결정나무
3-1. 선형회귀 모델로 예측하기
# 선형회귀
from sklearn.linear_model import LinearRegression
# 선형회귀 객체 생성
lr = LinearRegression()
# 학습
lr.fit(X_train, y_train)
# 테스트 데이터로 예측
pred2 = lr.predict(X_test)
# 검증데이터와 예측값 그래프로 시각화
sns.scatterplot(x=y_test, y=pred2)
# RMSE
mean_squared_error(y_test, pred2, squared=False) # RMSE
선형회귀 RMSE: 228.26128192004947
의사결정나무 RMSE: 228.42843328100884
3-2. 하이퍼파라미터 튜닝
# max_depth: 트리의 최대 깊이를 제한
# min_samples_leaf: 데이터가 나뉘어 최소 30개로 분류되었을때 가지치기를 끝냄
dt = DecisionTreeRegressor(random_state=10, max_depth=5, min_samples_leaf=30)
# 학습
dt.fit(X_train, y_train)
# 예측
pred3 = dt.predict(X_test)
# RMSE
mean_squared_error(y_test, pred3, squared=False)
>>> 187.3015148952268
선형회귀 RMSE: 228.26128192004947
의사결정나무 RMSE: 228.42843328100884
의사결정나무 파라미터 튜닝: 187.3015148952268 (성능이 정말 달라질 수 있음!!)
3-3. 의사결정나무 모델의 그래프
from sklearn.tree import plot_tree
plt.figure(figsize=(24,12))
plot_tree(dt, max_depth=5, fontsize=12)
plt.show()
plt.figure(figsize=(24,12))
plot_tree(dt, max_depth=5, fontsize=12, feature_names=X_train.columns)
plt.show()
✅ 하이퍼파라미터로 피쳐의 이름이 나오도록 표시하기
'Python > ML&DL' 카테고리의 다른 글
[파이썬, Python] 머신러닝 - 4️⃣ 서포트 벡터 머신(Support Vector Machine) (0) | 2023.06.18 |
---|---|
[파이썬, Python] 머신러닝 - 3️⃣ 로지스틱 회귀(Logistic Regression) (0) | 2023.06.15 |
[파이썬, Python] 머신러닝 - 1️⃣ 선형 회귀(Linear Regression) (0) | 2023.06.14 |
[파이썬, Python] 머신러닝을 위한 데이터 전처리 연습하기! (0) | 2023.06.14 |
[파이썬, Python] 머신러닝(Machine Learning)과 사이킷런(Scikit-learn) 모듈 (0) | 2023.06.14 |