

import pandas as pd
# 데이터 불러오기 (PetalLengthCm과 Species 열만 선택)
df = pd.read_csv("Iris.csv", sep=",", header=0)[["PetalLengthCm", "Species"]]
# Iris-setosa와 Iris-versicolor만 필터링
filtered_data = df[df['Species'].isin(['Iris-setosa', 'Iris-versicolor'])]
filtered_df = filtered_data
df['Species'].isin([...]): Species 열의 각 값이 리스트 내 값과 일치하면 True, 아니면 False를 가지는 Boolean Series를 반환한다. 이를 인덱싱에 사용하여 해당 행만 필터링한다.Salary Dataset에서는 목표 변수가 연속형 값이었기 때문에 따로 변환이 필요 없었다. 하지만 Iris Dataset의 목표 변수는 텍스트 데이터이므로, 모델이 처리할 수 있도록 이산형 레이블(0, 1)로 매핑해야 한다.
# Iris-setosa → 0, Iris-versicolor → 1로 매핑
filtered_df.loc[:, 'Species'] = filtered_df['Species'].map({'Iris-setosa': 0, 'Iris-versicolor': 1})
# 특징 변수: 2차원 배열로 추출
x = filtered_df[['PetalLengthCm']].values
# 목표 변수: 1차원 배열로 추출 후 정수형 변환
t = filtered_df['Species'].values.astype(int)
[['PetalLengthCm']] (이중 대괄호): DataFrame 형태를 유지하여 2차원 배열로 추출됨.['Species'] (단일 대괄호): Series 형태로 1차원 배열을 추출함.데이터를 학습용과 평가용으로 분리한다.
from sklearn.model_selection import train_test_split
# 80% 학습, 20% 테스트로 분할 (random_state=42로 재현성 확보)
x_train, x_test, t_train, t_test = train_test_split(x, t, test_size=0.2, random_state=42)
random_state=42에서 42는 "은하수를 여행하는 히치하이커를 위한 안내서"에서 유래한, 관습적으로 자주 사용되는 시드 값이다.이진 분류 모델 구축에서도 데이터 표준화가 필요하다. 주의할 점은 fit_transform은 트레이닝 데이터에만 적용하고, 테스트 데이터에는 transform만 사용하는 것이다.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train) # 트레이닝: 통계량 계산 + 표준화
x_test = scaler.transform(x_test) # 테스트: 트레이닝 통계량으로 표준화만
x_train = torch.tensor(x_train, dtype=torch.float32)
x_test = torch.tensor(x_test, dtype=torch.float32)
t_train = torch.tensor(t_train, dtype=torch.float32).unsqueeze(1)
t_test = torch.tensor(t_test, dtype=torch.float32).unsqueeze(1)
unsqueeze(1): 목표 변수를 1차원 [N]에서 2차원 [N, 1]로 변환한다. 이유는 다음과 같다.[N, 1]이어야 함.[데이터 수, 특징 수]로 이미 2차원이므로, 일관된 형태를 위해 맞춰줌.배치란 머신러닝과 딥러닝에서 데이터를 처리하는 묶음 단위를 의미한다. 일반적으로 16, 32, 64개 등의 단위로 나눠서 모델에 입력한다.

기존 경사하강법 알고리즘들의 장점과 단점을 비교하면 다음과 같다:

PyTorch에서 Dataset 클래스는 데이터셋을 정의하는 기본 클래스이다. Dataset을 상속받아 커스텀 데이터셋을 만들며, 다음 세 가지 메서드를 구현해야 한다.
__init__: 데이터를 초기화__len__: 데이터의 크기를 반환__getitem__: 특정 인덱스의 데이터 샘플을 반환from torch.utils.data import Dataset, DataLoader
class IrisDataset(Dataset):
def __init__(self, features, labels):
self.features = features # 특징 변수 저장
self.labels = labels # 목표 변수 저장
def __len__(self):
return len(self.features) # 데이터셋 크기 반환
def __getitem__(self, idx):
return self.features[idx], self.labels[idx] # 인덱스에 해당하는 (특징, 레이블) 쌍 반환
DataLoader 클래스는 Dataset 인스턴스를 감싸서 배치 단위로 데이터를 로드하고, 데이터 셔플 등의 작업을 수행한다.
shuffle=True로 데이터를 섞는다.shuffle=False로 설정한다.# CustomDataset 인스턴스 생성
train_dataset = IrisDataset(x_train, t_train)
test_dataset = IrisDataset(x_test, t_test)
# DataLoader 생성
batch_size = 4
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) # 훈련용: 셔플 O
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) # 평가용: 셔플 X
로지스틱 회귀란 트레이닝 데이터의 특성과 분포를 바탕으로 데이터를 잘 구분할 수 있는 최적의 결정 경계를 찾아, 시그모이드 함수를 통해 이 경계를 기준으로 데이터를 이진 분류하는 알고리즘이다. 딥러닝의 기본적인 구성요소로 널리 사용된다.

시그모이드 함수는 비선형 함수로, 입력 값을 0과 1 사이의 값으로 변환한다.

import torch.nn as nn
class BinaryClassificationModel(nn.Module):
def __init__(self):
super(BinaryClassificationModel, self).__init__()
self.layer_1 = nn.Linear(1, 1) # 입력 차원 1, 출력 차원 1인 선형 계층
self.sigmoid = nn.Sigmoid() # 시그모이드 활성화 함수
def forward(self, x):
z = self.layer_1(x) # 선형 변환: z = wx + b
y = self.sigmoid(z) # 시그모이드 적용: y = sigmoid(z)
return y
# 모델 초기화
model = BinaryClassificationModel()
nn.Linear(1, 1): 입력 차원과 출력 차원이 모두 1인 선형 계층. 를 계산함.nn.Sigmoid(): 선형 계층의 출력 를 0~1 사이의 이진 분류 확률 로 변환함.forward(): 특징 변수 를 받아 선형 계층 → 시그모이드를 순차적으로 통과시켜 최종 이진 분류 확률을 반환함.