Boostcamp AI Tech (Day 005)
1. assingment#3 풀이
저작권 문제를 피할 수 있도록 제가 수정한 코드입니다. 코드의 구조와 기능은 동일하게 유지하면서, 변수명과 함수명을 조금 변경하고, 설명을 추가해 주석을 수정했습니다.
먼저 “Cars - Purchase Decision” 데이터셋을 불러오고 전처리합니다.
User ID
: 각 사용자를 고유하게 식별하는 IDGender
: 성별 (Male 또는 Female)Age
: 사용자의 나이EstimatedSalary
: 예상 연봉Purchased
: 구매 여부 (1: 구매, 0: 미구매)
이 데이터를 모델에 적합하게 변환해야 합니다. 특히, Gender
는 숫자로 변환하고, Age
와 EstimatedSalary
는 정규화를 해야 합니다.
1단계: 데이터셋 이해 및 전처리
import pandas as pd
import torch
from torch.utils.data import Dataset
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
class CarPurchaseDataset(Dataset):
def __init__(self, file_path="car_data.csv", mode="train"):
# CSV 파일을 읽어들여 DataFrame으로 변환
data = pd.read_csv(file_path)
# 특성과 레이블을 분리하고 필요 없는 열 제거
X = data.drop(columns=['User ID', 'Purchased'])
y = data['Purchased']
# 성별 데이터를 숫자로 변환 (Male=0, Female=1)
X['Gender'] = X['Gender'].apply(lambda x: 0 if x == "Male" else 1)
# 나이와 예상 연봉 데이터를 정규화
scaler = StandardScaler()
X[['Age', 'EstimatedSalary']] = scaler.fit_transform(X[['Age', 'EstimatedSalary']])
# 학습과 평가용 데이터로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 모드에 따라 데이터 선택
if mode == "train":
self.X = torch.tensor(X_train.values, dtype=torch.float32)
self.y = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)
else:
self.X = torch.tensor(X_test.values, dtype=torch.float32)
self.y = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1)
def __len__(self):
# 데이터셋의 크기를 반환
return len(self.X)
def __getitem__(self, idx):
# 주어진 인덱스의 데이터를 반환
return self.X[idx], self.y[idx]
2단계: 로지스틱 회귀 모델 구현 및 학습
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
class LogisticRegressor(nn.Module):
def __init__(self, input_dim):
super(LogisticRegressor, self).__init__()
# 선형 변환 레이어 정의
self.linear = nn.Linear(input_dim, 1)
def forward(self, x):
# 모델의 출력값 계산 및 활성화 함수 적용
return torch.sigmoid(self.linear(x))
# 데이터 로더 정의
train_dataset = CarPurchaseDataset(mode="train")
test_dataset = CarPurchaseDataset(mode="test")
train_loader = DataLoader(dataset=train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)
# 모델, 손실 함수, 옵티마이저 정의
input_dim = 3 # 성별, 나이, 예상 연봉 3개의 입력 특성
model = LogisticRegressor(input_dim)
loss_function = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 학습 함수 정의
def train_model(model, loss_function, optimizer, dataloader, device, epochs=100):
model.to(device)
for epoch in range(epochs):
model.train()
total_loss = 0.0
for inputs, labels in dataloader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
predictions = model(inputs)
loss = loss_function(predictions, labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}/{epochs}, Loss: {total_loss/len(dataloader):.4f}")
# GPU 또는 CPU 장치 선택
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 모델 학습
train_model(model, loss_function, optimizer, train_loader, device, epochs=100)
3단계: 통계적 방법을 통한 모델 학습 및 비교
import statsmodels.api as sm
# 데이터 준비 및 변환
data = pd.read_csv("car_data.csv")
X = data[['Gender', 'Age', 'EstimatedSalary']]
X['Gender'] = X['Gender'].apply(lambda x: 0 if x == "Male" else 1)
y = data['Purchased']
# 상수항 추가 (절편 항목 추가)
X = sm.add_constant(X)
# 통계적 로지스틱 회귀 모델 학습
logit_model = sm.Logit(y, X)
result = logit_model.fit()
# 모델 요약 출력
print(result.summary())
4단계: 모델 평가 및 비교
def evaluate_model(model, dataloader, device):
model.eval()
correct_predictions = 0
total_samples = 0
with torch.no_grad():
for inputs, labels in dataloader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
predicted_classes = (outputs >= 0.5).float()
correct_predictions += (predicted_classes == labels).sum().item()
total_samples += labels.size(0)
print(f"Accuracy: {correct_predictions / total_samples:.4f}")
evaluate_model(model, test_loader, device)
# statsmodels를 사용한 모델 평가
y_pred_stats = result.predict(X)
y_pred_class_stats = (y_pred_stats >= 0.5).astype(int)
accuracy_stats = (y_pred_class_stats == y).mean()
print(f"Statsmodels accuracy: {accuracy_stats:.4f}")
회고
PyTorch와 statsmodels
를 사용하여 각각 로지스틱 회귀 모델을 학습하고, 두 모델의 성능을 비교했다.