Machine learning
[Python 지도학습 실습 RETURN 1]
100.nam
2024. 12. 26. 21:48
더보기
💡 주제
주택 가격 예측 모델 구축
🎯 목표 주어진 주택 데이터셋을 사용하여 주택 가격을 예측하는 회귀 모델을 구축합니다.
📖 학습 내용 - 지도 학습의 기본 개념과 회귀 분석을 이해하고, 실제 데이터에 적용하는 능력
- 데이터 전처리 및 탐색: 데이터의 품질을 높이는 방법과 특징 선택의 중요성
- 여러 회귀 모델의 이해: 다양한 회귀 기법의 원리와 적용 방법
- 모델 성능 평가: 성능 지표의 이해 및 비교 분석을 통해 최적의 모델 선택
- 과제한게 뭔가 마음에 안들기도 하고 놓친게 있어서 차근차근 다시 해보기로 했다.
1. 데이터 불러오기
# CSV 파일 불러오기
df = pd.read_csv('housingdata.csv')
# 데이터 로드 (5행만)
df.head()
2. 데이터 확인(결측치, 정규성 등)
1) 데이터 정보 확인
#데이터 정보 확인(타입, 결측값 등)
df.info()
import seaborn as sns
import matplotlib.pyplot as plt
# 결측치 시각화
sns.heatmap(df.isnull(), cbar=False, cmap='viridis')
plt.title('Missing Values Heatmap')
plt.show()
- 데이터 정보를 확인해보니 506개의 열이 존재
- CRIM, ZN, INDUS, CHAS, AGE, LSTAT 총 6개 행에 결측값 20개 존재
2) 이상치 확인
# Boxplot으로 이상치 시각화
for col in df.columns:
plt.figure(figsize=(8, 4))
sns.boxplot(data=df[col])
plt.title(f'Boxplot of {col}')
plt.show()
# IQR 기반 이상치 탐지
Q1 = df.quantile(0.25) # 1사분위수
Q3 = df.quantile(0.75) # 3사분위수
IQR = Q3 - Q1
# 이상치 경계
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 이상치 탐지
outliers = (df < lower_bound) | (df > upper_bound)
print(outliers.sum()) # 각 열에서 이상치 개수 출력
from scipy.stats import zscore
# Z-Score 계산
z_scores = df.apply(zscore)
# Z-Score 기준 이상치 탐지 (절댓값이 3을 초과하는 경우 이상치로 간주)
outliers_z = (z_scores.abs() > 3)
print(outliers_z.sum()) # 각 열에서 이상치 개수 출력
- Boxplot으로 시각화하면 아래처럼 나온다
- 왼쪽 CRIM에는 동그라미들이 이상치이다. INDUS처럼 나오면 이상치 없는 것이다
- 왼쪽 IQR 기반 이상치 탐지하면 나오는 것이다. CRIM 이상치가 63개나 나온다
- 오른쪽은 Z-Score로 계산한것이다. 3초과부터 이상치이다
3) 데이터 정규성 확인
import scipy.stats as stats
import matplotlib.pyplot as plt
# 모든 특성 변수에 대해
# 히스토그램은 정규성을 따르면 종 모양을 하고 있음
for column in df.columns:
# 히스토그램
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
df[column].hist(bins=30)
plt.title(f'{column} Histogram')
# Q-Q 플롯
# 정규분포를 따르면 데이터들이 직선 모양으로 분포
plt.subplot(1, 2, 2)
stats.probplot(df[column], dist="norm", plot=plt)
plt.title(f'{column} Q-Q Plot')
plt.show()
# RM, LSTAT, MEDV 열이 정규분포를 따름
# 의사결정나무, 랜덤 포레스트의 경우 분포에 민감하지 않으므로 데이터 변환이 없어도 괜찮다.
# 선형 회귀, 로지스틱 회귀는 데이터가 정규분포에 가까울 수록 예측 성능과 해석력이 좋아진다.
3. 데이터 전처리
1) 이상치 처리
- 처리 방법에는 제거, 대체, 완화, 모델기반 처리가 있다
- 이상치가 적은 경우( <5% 정도) = 제거
- 이상치가 중간 정도 경우 (5~15%) = 대체
- 이상치가 많거나 극단적인 경우 (>15%) = 완화
- 약 500개의 데이터에서 각 열의 이상치 비율은 아래와 같다.
- CRIM: 65개 (13%)
- ZN: 63개 (12.6%)
- CHAS: 34개 (6.8%)
- RM: 30개 (6%)
- DIS: 5개 (1%)
- PTRATIO: 15개 (3%)
- B: 77개 (15.4%)
- LSTAT: 7개 (1.4%)
- MEDV: 40개 (8%) -> 종속변수이기에 이상치는 처리하지 않음. 성능에 영향을 미치기 때문
# 이상치 비율 5% 이하: 제거
# IQR 기준 이상치 제거
for column in ['DIS', 'LSTAT', 'PTRATIO','NOX']:
df = df[~((df[column] < lower_bound[column]) | (df[column] > upper_bound[column]))]
# 이상치 비율 5%~15%: 대체
# 중앙값으로 이상치 대체
for column in ['CRIM', 'ZN', 'CHAS', 'RM']:
median_value = df[column].median()
df[column] = df[column].where((df[column] >= lower_bound[column]) & (df[column] <= upper_bound[column]), median_value)
# 0과 100 사이로 클리핑
# B는 아프리카계 미국인 비율을 나타내므로, 0~100% 범위 내에서 값이 유지되어야 한다. 그래서 0,100사이로 지정
df['B'] = df['B'].clip(0, 100)
# Boxplot으로 확인
print(outliers.sum())
- 이상치는 어느정도 걸러진 것 같다.
결측치 처리랑 모델 선택은 다음 시간에 계속 해보자