라이브러리
데이터 전처리를 위해 기본적으로 사용되는 주요 라이브러리는 다음과 같다.
- numpy
- 고성능 수치 계산과 배열(행렬) 연산을 위한 라이브러리이다.
- 머신러닝 데이터 구조인 특징 행렬과 타깃 벡터 구성에 자주 사용된다.
- matplotlib
- 다양한 차트를 시각화할 수 있는 라이브러리이다.
- 이 중에서도 pyplot 모듈이 가장 많이 사용된다.
- pandas
- CSV 파일 등 다양한 형식의 데이터를 불러오고, 정리 및 전처리하는 데 유용한 라이브러리이다.
데이터셋 불러오기/엔터티 생성하기
데이터셋 불러오기
import pandas as pd
dataset = pd.read_csv("Data.csv")
- pandas의 read_csv() 함수를 사용하면 CSV 파일을 쉽게 불러올 수 있다.
- 이 함수는 파일의 모든 데이터를 데이터프레임 형식으로 로드한다.
- 이후, 이 dataset을 이용하여 두 개의 변수를 생성해야 한다.
- 두 개의 변수는 특징 행렬(feature matrix), 타깃 벡터(target vector)이다.
- 특징 행렬(feature matrix) : 타깃 벡터를 예측하기 위한 입력 변수들의 집합
- 타깃 벡터(target vector) : 머신러닝 모델이 예측하려는 대상 변수로, 보통 레이블(label) 또는 정답 값에 해당한다.
- 보통 타깃 벡터는 데이터셋의 첫 번째 열 혹은 마지막 열에 위치한다.
- 두 개의 변수는 특징 행렬(feature matrix), 타깃 벡터(target vector)이다.
엔터티 생성하기
Country | Age | Salary | Purchased |
a | 44 | 52000 | No |
b | 27 | 48000 | Yes |
c | 30 | 76000 | Yes |
a | 38 | No | |
c | 65000 | No | |
... | ... | ... | ... |
Country, Age, Salary는 특징 행렬(feature matrix)에 해당하고, Purchased는 타깃 벡터(target vector)에 해당한다.
특징 행렬을 가져오기 위해 아래와 같이 작성할 수 있다.
X = dataset.iloc[:, :-1].values
- iloc은 행과 열의 인덱스를 기준으로 데이터를 추출할 수 있는 기능이다.
- :은 모든 행을 의미하고, :-1은 마지막 열을 제외한 모든 열을 선택한다.
- X는 특징 행렬(feature matrix)을 담기 위한 변수이다.
- 이 때, 모든 행의 값을 가져와야하므로, 첫번째 인자에 전체 행을 의미하는 :를 작성하였다.
- Purchased가 타깃 벡터(target vector)에 해당하기 때문에, Purchased를 제외한 모든 열을 가져와야되므로, 두번째 인자에 :-1을 작성하였다.
- -1은 마지막 열의 인덱스를 의미한다.
- 즉, 0번째 인덱스부터 마지막 열의 인덱스를 제외한 모든 열을 가져온다는 의미이다.
타깃 벡터(target vector)를 가져오기 위해서는 아래와 같이 작성할 수 있다.
Y = dataset.iloc[:, -1].values
- Y는 타깃 벡터(target vector)를 담기 위한 변수이다.
- 이때, 타깃 벡터(target vector)는 가장 마지막 열인 Purchased열만 해당하므로 해당 열만 가져오기 위하여 범위 없이 마지막 인덱스를 뜻하는 -1을 작성하였다.
이렇게 특징 행렬 X와 타깃 벡터 Y로 나누는 이유는 나중에 머신러닝 모델을 만들 때 두 요소를 입력해야하기 때문이다.
결측값 처리하기
데이터셋에 간혹가다 데이터가 누락되어 작성되어있는 경우가 있는데, 이때 해결하는 방법은 아래와 같이 여러가지가 있다.
- 결측값을 포함한 행을 삭제
- 결측값을 다른 값으로 대체
- 결측값 대체하는 값으로는 카테고리의 평균값, 중간값, 최빈값 등이 있다.
- 가장 일반적으로 사용되는 방식은 평균값으로 대체하는 방법이다.
- scikit-learn의 SimpleImputer를 통해 쉽게 구현할 수 있다.
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values=np.nan, strategy="mean")
imputer.fit(X[:, 1:3])
X[:, 1:3] = imputer.transform(X[:, 1:3])
- 1번째 줄
- 결측값을 평균값으로 대체하기 위해 sklearn의 SimpleImputer 모듈을 이용한다.
- 2번째 줄
- missing_values=np.nan : SimpleImputer의 첫번째 인자는 결측값을 의미한다.
- 즉, 누락된 값을 결측값으로 처리한다는 의미이다.
- strategy="mean" : SimpleImputer의 두번째 인자는 어떤 값으로 대체할지를 의미한다.
- 즉, 평균값으로 대체한다는 의미이다.
- missing_values=np.nan : SimpleImputer의 첫번째 인자는 결측값을 의미한다.
- 3번째 줄
- fit()은 평균값을 계산한다.
- fit()의 인자에는 숫자로만 구성된 열(카테고리)가 들어가야 한다.
- 이 때, Country열은 문자열이 포함된 범주형 데이터이므로 평균 계산이 불가능하기 때문에 숫자형 열인 Age와 Salary열만 대상으로 결측값 처리를 한다.
- 이에 해당하는 부분이 X[:, 1:3]로 작성하였다.
- 이 때, 1:3은 1열부터 2열까지를 의미한다.(3열은 포함되지 않는다.)
- 이에 해당하는 부분이 X[:, 1:3]로 작성하였다.
- 이 때, Country열은 문자열이 포함된 범주형 데이터이므로 평균 계산이 불가능하기 때문에 숫자형 열인 Age와 Salary열만 대상으로 결측값 처리를 한다.
- 4번째 줄
- transform()은 계산된 평균값으로 실제 결측값을 대체한다.
- transform()의 인자에는 결측값을 대체하고자 하는 곳을 작성한다.
- 여기서는 열 Country가 문자열로 이루어진 범주형 데이터이므로 평균 계산이 불가능하다.
- 따라서 숫자형 열인 Age와 Salary(X[:, 1:3])만 대상으로 결측값 처리를 수행한다.
- 이 메서드는 결측값이 대체된 새로운 배열을 반환하므로, 이를 다시 X에 할당해준다.
카테고리 유형을 수치형 값으로 변환하기
- 대부분의 머신러닝 알고리즘은 수치 연산을 기반으로 작동하기 때문에, 문자열로 구성된 범주형(카테고리형) 데이터는 직접 처리할 수 없다.
- 따라서 이러한 데이터를 수치형 값으로 변환하는 전처리 과정이 필요하다.
독립 변수 인코딩(입력 변수 인코딩)
- Country 열은 문자열로 구성되어 있기 때문에 이를 수치형 값으로 변환하는 전처리 과정을 진행해야한다.
- 수치형 값으로 변환하는 방법에는 아래의 방법을 생각해볼 수 있다.
- a를 0, b를 1, c를 2로 인코딩하는 방법
- 이 방법을 사용하면 모델은 숫자 순서가 있다고 이해할 수 있기 때문에, 대부분 이 순서가 중요하다고 생각할 수 있기 때문에 적합하지 않은 방법이다.
- 각 나라에 해당하는 열을 생성하여 인코딩하는 방법
- 예를들어, a는 [1, 0, 0], b는 [0, 1, 0], c는 [0, 0, 1]로 바꾸는 방법이다.
- 이렇게 바꾸면 각 나라에 순서가 있는 것이 아니기 때문에 이러한 인코딩 방법이 적합한 방법이다.
- 이러한 방법을 원 핫 인코딩이라고 한다.
- 범주형 변수가 포함된 데이터셋을 전처리 할 때 매우 유용하며, 가장 많이 사용되는 방법이다.
- a를 0, b를 1, c를 2로 인코딩하는 방법
- 수치형 값으로 변환하는 방법에는 아래의 방법을 생각해볼 수 있다.
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [0])], remainder="passthrough")
X = np.array(ct.fit_transform(X))
- 1번째 줄
- ColumnTransformer는 여러 열에 대해 각각 다른 전처리 방법을 적용할 수 있도록 해준다.
- 실제 데이터가 범주형과 숫자형으로 섞여 있을 때 유용하다.
- 2번째 줄
- OneHotEncoder는 범주형 데이터를 0과 1로 이루어진 벡터로 바꿔준다.
- 머신러닝 모델이 문자열 데이터를 이해할 수 있도록 변환해준다.
- 4번째 줄
- ColumnTransformer에는 두 가지 인자가 들어간다.
- 첫번째 인자는 어떤 전처리를 어떤 열에 적용할지 정의한다.
- 각 요소는 [이름, 변환기, 적용할 열 인덱스] 형태의 튜플이다.
- 따라서, encoder라는 이름으로, 0번째 열에 OneHotEncoder()를 적용하겠다는 의미이다.
- 두번째 인자는 지정하지 않은 나머지 열에 대해 어떻게 처리할지를 결정한다.
- passthrough: 나머지 열은 전처리 없이 그대로 유지
- drop: 나머지 열은 제거
- 첫번째 인자는 어떤 전처리를 어떤 열에 적용할지 정의한다.
- ColumnTransformer에는 두 가지 인자가 들어간다.
- 5번째 줄
- 변환된 데이터를 실제로 적용하고 저장한다.
- ct.fit_transform(X)
- 앞서 정의한 ColumnTransformer를 X 데이터에 학습(fit)시키고, 동시에 변환(transform)한다.
- np.array(...)
- ColumnTransformer의 출력은 기본적으로 희소 행렬(sparse matrix)일 수 있다.
- 따라서, 이후 연산이나 다른 머신러닝 모델과 호환성을 위해 일반 배열로 변환하는 것이 편리하기 때문에 배열로 바꾼다.
종속 변수 인코딩(타깃 변수 인코딩)
- 마찬가지로 Purchased 열 또한 문자열로 구성되어 있기 때문에 이를 수치형 값으로 변환하는 전처리 과정을 진행해야한다.
- Yes와 No로만 구성되어있고, 종속 변수에 해당하는 열이다.
- 따라서, Yes와 No를 각각 0과 1로 바꾸어도 상관없다.
- 왜냐하면, 0과 1로 바꾸어도 모델의 정확도에는 영향이 없기 때문이다.
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
Y = le.fit_transform(Y)
- 1번째 줄
- LabelEncoder는 타깃 변수 또는 범주형 데이터를 숫자로 변환해주는 인코더이다.
- 3번째 줄
- LabelEncoder 객체를 생성한다.
- 이 객체를 통해 인코딩 작업을 수행할 수 있다.
- 4번째 줄
- () 안에 어떤 값이 있는지 학습하고 학습한 내용을 바탕으로 범주를 숫자로 변환한다.
- LabelEncoder는 기본적으로 알파벳 순서에 따라 인코딩한다.
OneHotEncoder vs LabelEncoder
OneHotEncoder | LabelEncoder | |
용도 | 입력 변수 내 범주형 열 인코딩 | 종속 변수 또는 단일 범주형 열 인코딩 |
출력 형태 | 0과 1로 구성된 벡터(배열 형태) | 정수(0, 1, 2, ...) |
변환 방식 | 각 범주를 개별 열로 분리하여 0/1로 표시 | 각 범주를 고유한 정수로 매핑 |
순서 정보 포함 여부 | 없음(모든 범주를 동등하게 취급) | 있음(암묵적인 순서가 생김) |
예시 | X=[["red"],["blue"]] → [[1,0], [0, 1]] | ["Yes", "No"] → [1, 0] |
여러 열 처리 가능 여부 | 여러 열에 동시에 적용 가능 | 한 열만 가능 |
데이터셋을 훈련셋(training set)와 테스트셋(test set)으로 나누기
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2, random_state = 1)
- 1번째 줄
- train_test_split은 전체 데이터를 훈련셋(train set)과 테스트셋(test set)으로 나누어주는 함수입니다.
- 머신러닝에서 모델을 학습시키고 성능을 평가하기 위해 반드시 필요한 전처리 단계입니다.
- 3번째 줄
- X_train: 학습에 사용할 입력 데이터 / X_test: 테스트에 사용할 입력 데이터 / Y_train: 학습에 사용할 타깃 값/ Y_test: 테스트에 사용할 타깃 값
- test_size=0.2 : 전체 데이터 중 20%를 테스트용으로 사용하겠다는 의미이다.
- 즉, 80%는 학습용, 20%는 테스트용
- random_state=1 : 데이터를 무작위로 섞을 때의 시드 값(seed)이다.
피처 스케일링(Feature Scailing)
- 모든 기능을 동일한 스케일에 놓을 수 있다.
- 피처 스케일링을 하는 이유는 다음과 같다.
- 일부 머신러닝 모델은 값의 크기에 민감하기 때문에, 값이 큰 특성이 다른 특성보다 모델에 더 큰 영향을 줄 수 있다.
- 피처 스케일링을 통해 이러한 특성 간의 불균형을 방지할 수 있다.
- 모든 모델에 피처 스케일링을 적용할 필요는 없다.
- 피처 스케일링을 위해 주로 사용되는 기능은 표준화(Standardization)과 정규화(Normalization)이 있다.
표준화
$$x_{stand} = \frac{x-mean(x) }{standard deviation(x)}$$
- 모든 값의 평균으로 각 값을 뺀 다음 표준편차로 나눈다.
- 표준화의 결과로 모든 값이 -3에서 3 사이의 값을 가지게 된다.
정규화
$$x_{norm} = \frac{x - min(x)}{max(x) - min(x)}$$
- 각 값을 최소값으로 뺀 다음 최대값과 최소값의 차이로 나눈다.
- 정규화의 결과로 모든 값이 0에서 1 사이의 값을 가지게 된다.
언제 무엇을 사용해야할까 ?
- 표준화는 데이터가 정규 분포(가우시안 분포)를 따를 때 가장 효과적이며, 대부분의 모델에서 안정적으로 작동한다.
- 정규화는 데이터의 최소값과 최대값이 명확히 정의되어 있고, 0~1 범위로 맞춰야 하는 경우에 주로 사용된다.
- 따라서, 상황에 따라 잘 구분해서 사용해야 한다.
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train[:, 3:] = sc.fit_transform(X_train[:, 3:])
X_test[:, 3:] = sc.transform(X_test[:, 3:])
- 1번째 줄
- StandardScaler는 각 특성(feature)의 값을 평균 0, 표준편차 1이 되도록 표준화(standardization)하는 데 사용됩니다.
- 즉, 모든 특성이 동일한 스케일에 놓이도록 변환해줍니다.
- StandardScaler는 각 특성(feature)의 값을 평균 0, 표준편차 1이 되도록 표준화(standardization)하는 데 사용됩니다.
- 3번째 줄
- 표준화를 수행하기 위한 StandardScaler 객체를 생성한다.
- StandardScaler()는 특별한 인자를 필요로 하지 않는다.
- 5번째 줄
- 수치형 특성 열만 골라서 표준화하려는 경우이다.
- 훈련 데이터로부터 평균과 표준편차를 계산(fit) 하고, 이를 기준으로 데이터를 표준화(transform) 한다.
- 6번째 줄
- 훈련 데이터에서 계산한 평균과 표준편차를 사용해 표준화를 적용한다.
- 중요한 점은, 테스트 데이터를 fit() 하지 않고 transform()만 사용하는 것이다.
- 이는 테스트 데이터가 훈련 과정에 영향을 주지 않도록 하기 위한 머신러닝의 기본 원칙이다.(데이터 누수 방지)
'Machine Learning' 카테고리의 다른 글
단순 선형 회귀(Simple Linear Regression) (0) | 2025.07.02 |
---|---|
머신러닝 기초 개념 (1) | 2025.06.29 |