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파일을 생성하여 캐글에 제출해 줍니다.
'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 |