👩‍💻LEARN : ML&Data/Book Study

[모두의 딥러닝] #4-15. 실제 데이터로 만들어보는 모델 (선형회귀)

쟈니유 2023. 2. 20. 16:44
728x90

이번 데이터는 삼각지대의 한 축을 담당하는 부동산 데이터다!

 

이제는 실전이다 !

그동안은 y가 모두 범주형이라 binary, categorical을 썼지만

이번엔 집값예측이라 선형회귀로 모델을 구성해야한다. 

 

지금까지 배운 내용의 총 집합이라 코드를 아래에 서술하고 필요한 내용만 별도로 맨 밑에 빼서 서술해놓겠다. 

 

#데이터 전처리

import pandas as pd


df = pd.read_csv("./data/house_train.csv")

df.isnull().sum().sort_values(ascending=False).head(20)         #컬럼 별 null 개수를 합하고 큰 수 부터 위로 올렸다 

PoolQC 1453

MiscFeature 1406

Alley 1369

...

Electrical 1

Id 0 dtype: int64

 

 

이 상태면 아무것도 안된다..! null 값을 전처리하고 범주형 변수를 원핫코딩해보자 

 

df = pd.get_dummies(df)     #범주형 하나하나 안 넣어줘도 되는거 완전 좋다..일단 더미즈에 넣으면 알아서 원핫인코딩 해줌 
df= df.fillna(df.mean())         #이것도 완전 좋다... 하나하나 지정 안해줘도 되고 그냥 각 행의 mean으로 넣어줌 ㅠ          

df

깔꼬롬

 

 

#속성 별 상관관계 확인하기

df_corr = df.corr()
df_corr_sort = df_corr.sort_values('SalePrice',ascending=False). # dataframe에서 sort_values 한 다음에 파라미터를 특정 변수로 넣는 것 -> 해당 열을 기준으로 오름차순/내림차순 정렬

df_corr_sort['SalePrice'].head(10) #SalePrice 칼럼을 가져온 것

SalePrice 1.000000

OverallQual 0.790982

GrLivArea 0.708624

GarageCars 0.640409 ...

BsmtQual_Ex 0.553105

TotRmsAbvGrd 0.533723

Name: SalePrice, dtype: float64

import seaborn as sns
import matplotlib.pyplot as plt

cols = ['SalePrice', 'OverallQual','GrLivArea', 'GarageCars', 'GarageArea', 'TotalBsmtSF'] #타겟과 연관 높은 애들만 넣어주기

sns.pairplot(df[cols])
plt.show()

 

 

--- 여기까지가 데이터 전처리 및 파악하기 --- 

 

우선 데이터에서 na 값을 처리해주고 범주형을 모델 학습에 용이하게 바꿔준 다음 

Y값과 상관이 높은 애들만 발라내서 모델에 사용할 수 있도록 준비해줘야 한다. 

 

--- 이제부터 모델 만들기 ---

 

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 numpy as np


# 데이터셋 지정하기

cols_train = ['OverallQual','GrLivArea', 'GarageCars', 'GarageArea', 'TotalBsmtSF']

y = df['SalePrice'].values #array로 반환하게 됨
X_train_pre = df[cols_train]
#학습셋-테스트셋 지정

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_pre.shape[1], activation = 'relu')) #x변수 개수를 정수로 넣지 않고 자동으로 업데이트 되게 함
model.add(Dense(30, activation = 'relu'))
model.add(Dense(40, activation = 'relu'))
model.add(Dense(1))    #선형회귀엔 활성함수 사용하지 않는다! 변환을 주지 않기 때문 

model.summary()

Model: "sequential"

_________________________________________________________________

Layer (type) Output Shape Param # =================================================================

dense (Dense) (None, 10) 60

dense_1 (Dense) (None, 30) 330

dense_2 (Dense) (None, 40) 1240

dense_3 (Dense) (None, 1) 41

=================================================================

Total params: 1,671 Trainable params: 1,671 Non-trainable params: 0

 

model.compile(optimizer = 'adam', loss='mean_squared_error')

early_stopping_callback = EarlyStopping(monitor = 'val_loss', patience = 20) #자동중단

modelpath = './data/model/Ch15-house.hdf5'

checkpointer = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose = 0 , save_best_only = True) #최적화모델 저장용

history = model.fit(X_train, y_train, validation_split = 0.25, epochs = 2000, batch_size = 32, callbacks = [early_stopping_callback, checkpointer])

Epoch 153/2000 28/28 [==============================] - 0s 3ms/step - loss: 1690978560.0000 - val_loss: 1929210368.0000

Epoch 154/2000 28/28 [==============================] - 0s 4ms/step - loss: 1698007424.0000 - val_loss: 1927592832.0000

 

 

154번째에서 멈췄다! 

 

#학습결과 시각화

real_prices = []
pred_prices = []
X_num = []

n_iter = 0
Y_prediction = model.predict(X_test).flatten() #model이 X_test로 예측한 y 값. 값을 배열로 만들어주기 위해 flatten 사용


for i in range(25):
  real = y_test[i]
  prediction = Y_prediction[i]

  print("실제가격 : {:.2f}, 예상가격 : {:.2f}, X_num : {}".format(real, prediction, X_num))
  real_prices.append(real)
  pred_prices.append(prediction)
  n_iter = n_iter+1
  X_num.append(n_iter)

10/10 [==============================] - 0s 2ms/step

실제가격 : 165000.00, 예상가격 : 165383.69, X_num : []

실제가격 : 290000.00, 예상가격 : 281735.56, X_num : [1]

실제가격 : 168500.00, 예상가격 : 143048.53, X_num : [1, 2]

실제가격 : 184000.00, 예상가격 : 162128.38, X_num : [1, 2, 3]

 

이런식으로 총 25개의 샘플이 나온다. X_num은 어케 나오는지 궁금해서 추가해봄... 

 

plt.plot(X_num, pred_prices, label = 'prediction price')
plt.plot(X_num, real_prices, label = 'real price')

plt.legend()
plt.show()