서울시의 공공자전거 대여 서비스인 ‘따릉이’의 대여 수요를 예측하는 문제에 사용되는 데이터셋입니다. 특정 시간대와 날씨, 요일, 공휴일 여부, 기온, 습도 등 다양한 데이터를 활용하여 자전거 대여 수요를 예측합니다.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
bike_df = pd.read_csv('/본인의 구글드라이브 경로/SeoulBikeData.csv', encoding='CP949')
bike_df
※ CP949
bike_df.info()
bike_df.describe()
bike_df.columns
bike_df.columns = ['Date', 'Rented Bike Count', 'Hour', 'Temperature', 'Humidity',
'Wind speed', 'Visibility', 'Dew point temperature',
'Solar Radiation', 'Rainfall', 'Snowfall', 'Seasons',
'Holiday', 'Functioning Day']
bike_df.head()
sns.scatterplot(x='Temperature', y='Rented Bike Count', data=bike_df, alpha=0.3)
sns.scatterplot(x='Wind speed', y='Rented Bike Count', data=bike_df, alpha=0.3)
sns.scatterplot(x='Visibility', y='Rented Bike Count', data=bike_df, alpha=0.3)
sns.scatterplot(x='Hour', y='Rented Bike Count', data=bike_df, alpha=0.3)
bike_df.isna().sum()
bike_df.info()
bike_df['Date'] = pd.to_datetime(bike_df['Date'], format='%d/%m/%Y')
bike_df.info()
bike_df['year'] = bike_df['Date'].dt.year
bike_df['month'] = bike_df['Date'].dt.month
bike_df['day'] = bike_df['Date'].dt.day
bike_df.head()
plt.figure(figsize=(14, 4))
sns.lineplot(x='Date', y='Rented Bike Count', data=bike_df)
plt.xticks(rotation=45)
plt.show()
bike_df[bike_df['year'] == 2017].groupby('month')['Rented Bike Count'].mean()
bike_df[bike_df['year'] == 2018].groupby('month')['Rented Bike Count'].mean()
bike_df['TimeOfDay'] = pd.cut(bike_df['Hour'],
bins=[0, 5, 11, 17, 23],
labels=['Dawn', 'Morning', 'Afternoon', 'Evening'],
include_lowest=True)
※ pd.cut()
pd.cut()은 숫자 데이터를 구간(bins)으로 나누어 범주형 데이터로 변환하는 데 사용됩니다. 주로 연속형 데이터를 특정 범주로 분류할 때 활용됩니다.
0 ≤ Hour ≤ 5 | Dawn (새벽) |
5 < Hour ≤ 11 | Morning (아침) |
11 < Hour ≤ 17 | Afternoon (오후) |
17 < Hour ≤ 23 | Evening (저녁) |
bike_df.head()
sns.barplot(x='Functioning Day', y='Rented Bike Count', data=bike_df)
※ barplot의 bar의 역할
bike_df['Functioning Day'].value_counts()
bike_df[bike_df['Functioning Day'] == 'Yes']
bike_df[bike_df['Functioning Day'] == 'No']
bike_df.info()
bike_df = bike_df.drop('Date', axis=1)
bike_df.head()
bike_df.select_dtypes(exclude=['number']).columns.tolist()
for i in bike_df.select_dtypes(exclude=['number']).columns.tolist():
print(i, bike_df[i].nunique())
bike_df = pd.get_dummies(bike_df, columns=bike_df.select_dtypes(exclude=['number']).columns.tolist(), drop_first=True)
bike_df.head()
# 모든 컬럼 간 상관관계 분석
correlation_matrix = bike_df.corr()
# 목표 변수와의 상관관계만 확인
target_corr = correlation_matrix['Rented Bike Count'].sort_values(ascending=False)
print(target_corr)
※ corr() 함수
corr() 함수는 데이터프레임의 숫자형 열 간의 상관관계를 계산하는 데 사용됩니다. 상관관계는 두 변수 간의 선형 관계를 나타내며, 주로 -1에서 1 사이의 값으로 표현됩니다.
corr()를 사용하여 높은 상관관계를 가진 컬럼을 식별하고 제거할지 여부를 판단할 수 있습니다. 특히, 다중공선성(multicollinearity) 문제가 발생할 경우 머신러닝 모델의 성능이 저하될 수 있으므로, 상관관계가 높은 컬럼을 적절히 제거하는 것이 중요합니다.
※ 다중공선성
다중공선성(Multicollinearity)은 회귀 분석에서 독립 변수들(설명 변수) 간에 강한 상관관계가 존재하는 현상을 의미합니다. 이러한 상관관계가 높으면 각 독립 변수가 종속 변수에 미치는 개별적인 영향을 정확하게 추정하기 어려워지며, 회귀 계수의 추정치가 불안정해져 작은 데이터 변화에도 크게 변할 수 있습니다. 이는 모델의 예측 성능 저하와 해석의 신뢰성 감소로 이어질 수 있으므로, 다중공선성이 높은 변수를 식별하고 제거하거나 조정하는 것이 중요합니다.
plt.figure(figsize=(16, 12))
sns.heatmap(correlation_matrix, annot=True, fmt='.2f', cmap='coolwarm')
plt.title('Feature Correlation Heatmap')
plt.show()
bike_df = bike_df.drop(['Dew point temperature'], axis=1)
bike_df.head()
bike_df.info()
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(bike_df.drop('Rented Bike Count', axis=1), bike_df['Rented Bike Count'], test_size=0.3, random_state=2025)
X_train.shape, y_train.shape
X_test.shape, y_test.shape
결정 트리(Decision Tree)는 데이터를 기반으로 의사결정을 수행하는 트리 구조의 예측 모델입니다. 루트 노드(root node)에서 시작해 각 노드는 특정 특성(feature)의 조건에 따라 가지(branch)로 분기되며, 최종적으로 리프 노드(leaf node)에 도달해 예측 결과(클래스나 값)를 도출합니다. 주로 분류(Classification)와 회귀(Regression) 문제에 사용되며, 데이터의 패턴을 직관적으로 시각화할 수 있어 해석이 용이합니다. 하지만 트리가 너무 깊어지면 과적합(overfitting) 문제가 발생할 수 있으므로 가지치기(pruning)나 최대 깊이 설정 등으로 제어해야 합니다.
※ Gini 불순도 (Gini Impurity)
※ 엔트로피 (Entropy)
from sklearn.tree import DecisionTreeRegressor
dtr = DecisionTreeRegressor(random_state=2025)
dtr.fit(X_train, y_train)
pred1 = dtr.predict(X_test)
sns.scatterplot(x=y_test, y=pred1)
※ DecisionTreeRegressor
DecisionTreeRegressor는 주어진 데이터를 반복적으로 분할하여 예측을 수행합니다. 각 분할은 데이터의 목표 변수 값을 예측하는 데 가장 적합한 값을 찾기 위해 이루어집니다. 이를 통해 데이터를 점차 더 작은 부분으로 나누고, 각 부분에서 평균값을 예측값으로 사용하는 방식입니다. DecisionTreeRegressor 데이터를 두 가지 그룹으로 분할합니다. 각 분할에서 목표는 두 그룹의 MSE가 가능한 한 낮도록 만드는 것입니다. 즉, 각 분할에서의 MSE가 최소화되도록 분할점을 찾습니다.
from sklearn.metrics import root_mean_squared_error
root_mean_squared_error(y_test, pred1)
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)
root_mean_squared_error(y_test, pred2)
# 하이퍼 파라미터 적용
dtr = DecisionTreeRegressor(random_state=2025, max_depth=50, min_samples_leaf=30)
dtr.fit(X_train, y_train)
pred3 = dtr.predict(X_test)
root_mean_squared_error(y_test, pred3)
from sklearn.tree import plot_tree
plt.figure(figsize=(24, 12))
plot_tree(dtr, max_depth=5, fontsize=10, feature_names=X_train.columns)
plt.show()
from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor(random_state=2025)
rf.fit(X_train, y_train)
pred4 = rf.predict(X_test)
root_mean_squared_error(y_test, pred4)
rf.feature_importances_
feature_imp = pd.DataFrame({
'features': X_train.columns,
'importances': rf.feature_importances_
})
feature_imp
top10 = feature_imp.sort_values('importances', ascending=False).head(10)
top10
plt.figure(figsize=(5, 10))
sns.barplot(x='importances', y='features', data=top10)
슈퍼스토어 마케팅 캠페인 데이터셋 (1) | 2025.01.10 |
---|---|
호텔 예약 수요 데이터셋 (1) | 2025.01.09 |
주택 임대료 예측 데이터셋 (2) | 2025.01.03 |
사이킷런 (0) | 2024.12.31 |
머신러닝 (3) | 2024.12.23 |