본문 바로가기

Study/AI

House Prices - Advanced Regression Techniques

728x90

https://www.kaggle.com/competitions/house-prices-advanced-regression-techniques/overview

 

House Prices - Advanced Regression Techniques | Kaggle

 

www.kaggle.com

오늘은 캐글에서 집값을 예측하는 House Prices를 공부해 보겠습니다.

import pandas as pd

# Load the data
train_data = pd.read_csv('train.csv')
test_data = pd.read_csv('test.csv')

# Pre-processing
features = ['OverallQual','GrLivArea','GarageCars','TotalBsmtSF', 'Neighborhood']

train_data = train_data[features + ['SalePrice']]
X_train = train_data.drop('SalePrice', axis=1)
y_train = train_data['SalePrice']

X_test = test_data[features]

먼저 판다스를 이용해서 train데이터과 test데이터를 넣어줍니다.

 

피쳐는 공통적으로 'OverallQual','GrLivArea','GarageCars','TotalBsmtSF', 'Neighborhood' 를 사용하게 됩니다.

이후 트레인 데이터셋에만 SalePrice를 추가해줍니다

 

X_train에는 SalePrice를 제외한 열들의 특성이 저장됩니다.

y_train에는 SalePrice열만 저장됩니다.

from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder

# Perform label encoding on string features
label_encoder = LabelEncoder()
for column in X_train.select_dtypes(include='object'):
    X_train[column] = label_encoder.fit_transform(X_train[column])
    X_test[column] = label_encoder.transform(X_test[column])
    
# Standardize the features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

위의 코드는 레이블 인코딩과 표준화를 위한 코드입니다.

 

LabelEncoder()는 문자열 특성을 숫자로 변환하기 위해 사용됩니다.

StandardScaler()는 특성의 평균을 0, 분산을 1로 변환하여 특성들을 표준화하는 데 사용됩니다.

 

문자열 특성에 대해 반복문을 사용하여 각 특성을 레이블 인코딩합니다.

fit_transform()메서드를 사용하여 학습하고, 테스트 데이터에 대해서는 이미 학습된 인코더를 사용하여 변환합니다.

자 특성에 대해서는 fit_transform()메서드를 사용하여 훈련 데이터에 대해 표준화를 수행하고 테스트 데이터에 대해서는 훈련된 스케일러를 사용하여 변환합니다.

import torch

# Convert the data to PyTorch tensors
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)
X_test = torch.tensor(X_test, dtype=torch.float32)

print(X_train.shape, y_train.shape, X_test.shape)

데이터를 PyTorch 텐서로 변환하는 코드입니다.

torch.tensor()함수를 사용하여 데이터를 PyTorch 텐서로 변환합니다. 데이터 타입은 dtype = torch.float32로 설정됩니다.

변환된 텐서의 크기는 shape 속성을 사용하여 출력됩니다.

from torch.utils.data import TensorDataset, DataLoader

# Create a TensorDataset for train and test data
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test)

# Create a DataLoader for train and testdata
train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)

훈련 데이터셋과 테스트 데이터셋을 생성하는 부분입니다.

batch_size를 통하여 미니배치의 크기를 지정하고 shuffle을 통하여 데이터를 섞을지 여부를 결정합니다.

import torch.nn as nn

# Define the neural network model
class RegressionModel(nn.Module):
    def __init__(self, input_size):
        super(RegressionModel, self).__init__()
        self.fc1 = nn.Linear(input_size, 64)
        self.fc2 = nn.Linear(64, 32)
        self.fc3 = nn.Linear(32, 1)
        
    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

회귀 모델을 정의하는 부분입니다.

__init__(self, input_size)함수를 통하여 입력 크기에 따라 선형 변환 레이어를 초기화합니다.

먼저 입력층에서 은닉층으로 선형 변환을 거친 후 첫 번째 은닉층에서 두 번째 은닉층으로 선형 변환 합니다. 이후

두 번째 은닉층에서 출력층으로 선형변환을 진행합니다.

 

forward(self, x)함수는 순전파 연산을 정의합니다. 먼저 첫 번째 은닉층의 출력을 ReLU 활성화 함수를 통과 시키고 두 번째 은닉층의 출력을 ReLU 활성화 함수를 통과시킵니다. 이후 출력층의 출력을 계산합니다.

import torch.optim as optim

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# Create an instance of the model
model = RegressionModel(X_train.shape[1])
model = model.to(device)

# Define the loss function and optimizer
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

모델 인스턴스를 생성하고 손실 함수 및 옵티마이저를 정의하는 부분입니다.

 

torch.device()함수를 사용하여 CUDA가 사용 가능한 경우 GPU, 그렇지 않은경우 CPU를 사용합니다.

 

RegressionModel(X_train.shape[1])을 사용하여 모델의 인스턴스를 생성합니다. 입력 데이터의 특성 수에 해당하는 input_size를 인자로 사용하여 모델 인스턴스를 생성합니다. 이후 모델을 지정한 장치로 이동합니다.

 

손실 함수로는 평균 제곱 오차(MSE)를 사용합니다. 옵티마이저로는 Adam옵티마이저를 사용합니다.

# Training loop
num_epochs = 200
losses = []
for epoch in range(num_epochs):
    epoch_loss = 0
    for inputs, targets in train_dataloader:
        inputs, targets = inputs.to(device), targets.to(device)
        
        # Forward pass
        outputs = model(inputs)
        loss = criterion(outputs, targets)
        epoch_loss += loss.item()
        
        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
    losses.append(epoch_loss)
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}')

위의 코드는 모델을 학습하는 반복문입니다.

 

주어진 에폭 수 만큼 반복을 진행합니다.

 

먼저 입력 데이터를 모델에 입력하여 예측값을 계산하고 손실 함수를 사용하여 손실을 계산합니다. 에폭별 손실을 누적해줍니다.

 

이후 역전파 및 최적화를 수행하여 에폭별 손실을 기록합니다.

import matplotlib.pyplot as plt
import numpy as np

losses = np.array(losses)
plt.plot(losses)
plt.show()

 

손실률을 시각화 해보았습니다.

import pandas as pd

# Inference
outputs = []
with torch.no_grad():
    model.eval()
    for inputs in test_dataloader:
        inputs = inputs[0].to(device)
        pred = model(inputs)
        pred = torch.where(torch.isnan(pred), torch.mean(y_train), pred)
        
        outputs += pred.tolist()

위의 코드는 테스트 데이터에 대한 추론을 수행하는 부분입니다.

# Convert the tensor of predictions to a numpy array
outputs = np.array(outputs)

# Create a DataFrame with the Id and SalePrice columns
submission_df = pd.DataFrame({'Id': test_data['Id'], 'SalePrice': outputs.flatten()})

# Save the DataFrame as a CSV file
submission_df.to_csv('submission.csv', index=False)

이후 csv파일을 생성하여 캐글에 제출해 줍니다.

728x90

'Study > AI' 카테고리의 다른 글

Spaceship Titanic  (0) 2024.04.13
Digit Recognizer  (0) 2024.04.13
Titanic Survival Prediction  (1) 2024.04.10
넘파이(Numpy) - 비교 연산과 데이터 추출  (0) 2023.04.09
넘파이(Numpy) - 배열 연산  (0) 2023.04.09