실제 데이터(보스턴 주택 데이터셋)를 가지고 모델을 만들어보는 실습입니다.
실제 데이터를 가지고 할 때 진행해야하는 몇가지 과제가 있는데
• 결측치 처리하기: 데이터에서누락된 값을 찾아 적절히대체하거나제거하는과정(전처리)
• 관련된속성 파악하기: 데이터의중요한특징과 속성을 이해하고분석하는과정
• 검증 가능한 모델 만들기: 모델의 성능을 신뢰할 수 있게 평가하고검증하는 과정
순서는
1. 데이터 파악하기
# import os
# os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
# 집 값 데이터를 불러옵니다.
df = pd.read_csv("data/house_train.csv")
# 데이터를 미리 살펴보겠습니다.
print(df)
print(df.dtypes)
2. 결측치, 카테고리 변수 처리하기
# 속성별로 결측치가 몇 개인지 확인합니다.
print(df.isnull().sum().sort_values(ascending=False).head(20))
# 카테고리형 변수를 0과 1로 이루어진 변수로 바꾸어 줍니다.(원핫 인코딩)
df = pd.get_dummies(df)
# 결측치를 전체 칼럼의 평균으로 대체하여 채워줍니다.
df = df.fillna(df.mean())
# 업데이트된 데이터 프레임을 출력해봅니다.
print(df)
3. 속성별 관련도 추출하기
# 데이터 사이의 상관 관계를 저장합니다.
df_corr = df.corr()
# 집 값과 관련이 큰 것부터 순서대로 저장합니다.
df_corr_sort = df_corr.sort_values('SalePrice', ascending=False)
# 집 값과 관련도가 가장 큰 10개의 속성들을 출력합니다.
print(df_corr_sort['SalePrice'].head(10))
# 집 값과 관련도가 가장 높은 속성들을 추출해서 상관도 그래프를 그려봅니다.
cols = ['SalePrice', 'OverallQual', 'GrLivArea', 'GarageCars', 'TotalBsmtSF', 'FullBath', 'YearBuilt']
sns.pairplot(df[cols])
plt.show()
상관도 그래프(Pairplot) 해석
이 그래프는 집 값(SalePrice)과 가장 관련이 높은 6개 변수들 간의 관계를 모두 보여주는 행렬 형태의 그래프입니다. 각 변수 쌍에 대한 산점도와 대각선에는 각 변수의 분포를 보여줍니다.
그래프 해석:
1. 대각선 그래프: 각 변수의 분포를 보여줍니다.
• SalePrice: 오른쪽으로 치우친 분포로, 대부분의 집 값이 낮은 가격대에 몰려있고 일부 고가 주택이 있음을 보여줍니다.
• OverallQual: 주택 품질 점수로, 막대그래프 형태로 표시되며 중간 품질(5-7점)의 주택이 많습니다.
• GrLivArea: 주거 면적의 분포로, 대체로 정규분포에 가깝지만 일부 큰 면적 주택이 있습니다.
• GarageCars: 차고에 주차 가능한 차량 수로, 2대 주차 가능한 집이 가장 많습니다.
• TotalBsmtSF: 지하실 면적으로, 다양한 크기의 지하실이 있습니다.
• YearBuilt: 건축 연도로, 최근에 지어진 집들이 많습니다.
2. 산점도(대각선 외 그래프):
• SalePrice와 OverallQual: 강한 양의 상관관계(0.79)를 보여줍니다. 주택 품질이 높을수록 가격이 높아지는 경향이 뚜렷합니다.
• SalePrice와 GrLivArea: 강한 양의 상관관계(0.71)로, 주거 면적이 클수록 가격이 높아집니다.
• SalePrice와 GarageCars: 양의 상관관계(0.64)로, 주차 공간이 많을수록 가격이 높아집니다.
• SalePrice와 TotalBsmtSF: 양의 상관관계(0.61)로, 지하실 면적이 클수록 가격이 높아집니다.
• SalePrice와 YearBuilt: 양의 상관관계로, 최근에 지어진 집일수록 가격이 높은 경향이 있습니다.
3. 변수 간 관계:
• OverallQual과 GrLivArea: 양의 상관관계로, 주택 품질이 좋을수록 주거 면적이 넓은 경향이 있습니다.
• GarageCars와 OverallQual: 양의 상관관계로, 품질이 좋은 집일수록 차고 공간이 더 큽니다.
• TotalBsmtSF와 GrLivArea: 양의 상관관계로, 주거 면적이 넓은 집일수록 지하실도 넓은 경향이 있습니다.
주요 인사이트:
1. 집 값에 가장 큰 영향을 미치는 요소:
• 전체적인 품질(OverallQual)이 가장 중요한 요소입니다(상관계수 0.79).
• 그 다음으로 주거 면적(GrLivArea)이 중요합니다(상관계수 0.71).
2. 변수 간 관계:
• 대부분의 변수들이 서로 양의 상관관계를 가집니다. 즉, 좋은 품질의 집은 대체로 면적이 넓고, 차고가 크며, 지하실도 넓은 경향이 있습니다.
• 이는 고급 주택일수록 여러 좋은 특성을 함께 갖추는 경향이 있음을 보여줍니다.
3. 이상치(Outliers):
• 일부 그래프에서 주요 패턴에서 벗어난 점들(이상치)이 보입니다. 예를 들어, 넓은 면적에도 가격이 낮은 집이나, 품질이 낮은데도 가격이 높은 집 등이 있습니다.
이 그래프를 통해 집 값 예측 모델을 만들 때 어떤 변수들이 중요한지 파악할 수 있으며, 특히 전체적인 품질과 주거 면적이 가장 중요한 요소임을 알 수 있습니다.
- Claude 3.7 Sonnet 해석
4. 주택 가격 예측 모델
# 집 값을 제외한 나머지 열을 저장합니다.
cols_train = ['OverallQual', 'GrLivArea', 'GarageCars', 'TotalBsmtSF', 'FullBath', 'YearBuilt']
X_train_pre = df[cols_train]
# 집 값을 저장합니다.
y = df['SalePrice'].values
# 전체의 80%를 학습셋으로, 20%를 테스트셋으로 지정합니다.
X_train, X_test, y_train, y_test = train_test_split(X_train_pre, y, test_size=0.2)
# 모델의 구조를 설정합니다.
model = Sequential()
model.add(Dense(10, input_dim=X_train.shape[1], activation='relu'))
model.add(Dense(30, activation='relu'))
model.add(Dense(40, activation='relu'))
model.add(Dense(1))
model.summary()
# 모델을 실행합니다.
model.compile(optimizer='adam', loss='mean_squared_error')
# 20회 이상 결과가 향상되지 않으면 자동으로 중단되게끔 합니다.
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=20)
# 모델의 이름을 정합니다.
model_path = 'data/model/house_train_boston_model.keras'
# 최적화 모델을 업데이트하고 저장합니다.
checkpointer = ModelCheckpoint(filepath=model_path, monitor='val_loss', verbose=0, save_best_only=True)
# 실행 관련 설정을 하는 부분입니다. 전체의 20%를 검증셋으로 설정합니다.
history = model.fit(X_train, y_train, validation_split=0.25, epochs=2000, batch_size=32, callbacks=[early_stopping_callback, checkpointer])
# 예측 값과 실제 값, 실행 번호가 들어갈 빈 리스트를 만듭니다.
real_price = []
pred_price = []
X_num = []
# 25개의 샘플을 뽑아 실제 값, 예측 값을 출력해 봅니다.
n_iter = 0
Y_prediction = model.predict(X_test).flatten()
for i in range(25):
real = y_test[i]
prediction = Y_prediction[i]
print("실제가격: {:.2f}, 예상가격: {:.2f}".format(real, prediction))
real_price.append(real)
pred_price.append(prediction)
n_iter += 1
X_num.append(n_iter)
# 그래프를 통해 샘플로 뽑은 25개의 값을 비교해 봅니다.
plt.figure(figsize=(10, 6))
plt.plot(X_num, pred_price, label='predicted price')
plt.plot(X_num, real_price, label='real price')
plt.legend()
plt.show()
주택 가격 예측 모델 결과 그래프 해석
이 그래프는 딥러닝 모델이 예측한 주택 가격(파란색 선)과 실제 주택 가격(주황색 선)을 비교한 것입니다. 25개의 테스트 샘플에 대한 결과를 보여주고 있습니다.
그래프 분석
1. 예측 정확도:
• 대부분의 경우 예측 가격이 실제 가격과 유사한 패턴을 따르고 있습니다.
• 그래프의 두 선이 대체로 비슷한 방향으로 움직이는 것을 볼 수 있는데, 이는 모델이 가격 변동 패턴을 잘 학습했음을 의미합니다.
2. 예측 오차:
• 일부 샘플(예: 7번, 14번, 24번)에서는 예측 가격과 실제 가격 사이에 상당한 차이가 있습니다.
• 특히 24번 샘플(345,000원 실제 가격)에서는 모델이 약 256,000원으로 예측하여 약 89,000원의 큰 오차가 발생했습니다.
• 7번 샘플에서는 실제 가격보다 낮게 예측했습니다(116,000원 대비 68,000원 예측).
3. 가격대별 성능:
• 중간 가격대(150,000~200,000원)에서는 모델이 비교적 안정적으로 예측하는 경향이 있습니다.
• 고가 주택(250,000원 이상)에서는 모델이 실제 가격보다 낮게 예측하는 경향이 있습니다.
• 이는 고가 주택의 특성이 데이터셋에 충분히 반영되지 않았거나, 모델이 극단적인 값을 예측하는 데 한계가 있을 수 있음을 시사합니다.
4. 전체적인 성능:
• 모델은 대체로 실제 가격의 추세를 잘 따라가고 있으며, 많은 경우 10% 이내의 오차로 예측하고 있습니다.
• 132번의 에포크(학습 반복) 후에 학습이 중단되었는데, 이는 검증 손실이 20번의 에포크 동안 개선되지 않았기 때문입니다(EarlyStopping 콜백).
개선 가능성
1. 더 많은 특성 추가: 현재 모델은 6개의 특성만 사용하고 있습니다. 더 많은 관련 특성을 추가하면 예측 정확도가 향상될 수 있습니다.
2. 모델 복잡도 조정: 현재 모델은 3개의 은닉층을 가진 간단한 구조입니다. 더 복잡한 모델이나 다른 구조(예: 드롭아웃 추가)를 시도해볼 수 있습니다.
3. 데이터 전처리 개선: 특성 스케일링이나 정규화를 적용하면 모델 성능이 향상될 수 있습니다.
4. 이상치 처리: 일부 극단적인 가격을 가진 주택 데이터가 모델 학습에 영향을 줄 수 있으므로, 이상치를 처리하는 방법을 고려해볼 수 있습니다.
전반적으로 이 모델은 주택 가격 예측에 있어 합리적인 성능을 보여주고 있으며, 실제 가격의 추세를 잘 따라가고 있습니다. 하지만 일부 특정 사례에서는 개선의 여지가 있습니다.
- Claude 3.7 Sonnet 해석
오늘 공부한 내용입니다.
딥러닝을 공부하면서 이전에 시험준비했던 데이터분석준전문가에서 공부한 내용들이 나와서 다시 찾아보고 내용을 다시 익혀가고 있습니다.
딥러닝을 활용한 AI 의료 진단
'AI 공부' 카테고리의 다른 글
자연어 처리2 - LSTM (0) | 2025.06.06 |
---|---|
자연어 처리1 - Tokenizer (1) | 2025.06.04 |
CNN(컨볼루션 신경망) 딥러닝 모델 2 (3) | 2025.06.02 |
CNN(컨볼루션 신경망) 딥러닝 모델 1 (4) | 2025.06.02 |
산점도를 이용한 결과 (0) | 2025.05.31 |