머신러닝

Data Preprocessing

lazy_marcie 2023. 12. 12. 16:25

☑️  Data Preprocessing

필요성

Garbage in Garbage out(GIGO) → 따라서 데이터를 깔끔하게 정제하는 과정이 필요하다.

 

유형

  • 데이터 정제
  • 데이터 인코딩
  • 데이터 스케일링
  • Feature Engineering

 

☑️ Data  Cleaning

Data Cleaning 과정은 데이터가 가지고 있는 문제점을 해결하는 과정을 의미한다. 데이터는 크게 두 가지 유형의 문제를 가질수 있다. 

 

데이터 문제 유형

 

①  데이터 품질의 문제  Dirty Data (Low Quality Data)를 판별하는 4가지 기준

  • 완결성(Completeness): 필수적인 데이터는 모두 기록되어 있어야 한다. → 결측치
  • 유일성(Uniqueness): 동일한 데이터가 불필요하게 중복되어 있으면 안된다. → 중복값
  • 통일성(Conformity): 데이터가 동일한 형식으로 저장돼 있어야 함. → 형식: 단위, 데이터 타입, 포맷
  • 정확성(Accuracy): 데이터가 정확해야 함 → 이상치

 

②  데이터 구조의 문제 → Messy Data (Untidy Data)를 판별하는 3가지 기준

  • 각 변수는 하나의 열을 구성
  • 각 관측치는 하나의 행을 구성
  • 각 유형의 관측 단위가 표를 구성

 

데이터 정제 단계

 

①  문제 정의: 어떻게 정제할지 정의

②  코드 구현: 정제하기 위한 코드 구현

③  결과 확인: 정제가 잘 되었는지 확인하는 과정이 필요

 

⚠️ 데이터 정제 시 유의사항

- 정제 단계 시행 전, 원본 DataFrame을 유지하기 위해 반드시 copy()하는 과정을 선행
- 데이터 정제 과정은 순서를 고려해서 진행하는 것이 중요:
                                                   품질 문제 해결(결측치 → 중복값) → 구조적 문제 해결

 

모델 유형별 전처리 전략

① 선형 모델

  • 입력 특성들의 크기, 범위, 분포에 영향을 받음 → scaling 등의 시도가 필요
  • 결측치 반드시 처리
  • 모든 값은 수치형으로 변환
  • 비선형적 특성이나 특성 간 상호작용 미리 처리 → 선형 관계를 갖도록 log, sqrt 등의 사용이 필요

 

② 트리 모델

  • 입력 특성들의 대소관계에만 영향을 받고 크기, 범위, 분포에 영향 x
  • 사용하는 라이브러리에 따라 결측치를 필수적으로 처리하지 않아도 됨
  • 특성과 타겟 간 비선형적 관계나 특성 간 상호작용이 자동으로 반영

 

☑️  Data Encoding

머신러닝 모델의 경우, 일반적으로 수치형 외에 값은 입력할 수 없다. 따라서 범주형 데이터를 수치형 데이터로 변환하는 과정이 필요하고 이 과정이 바로 데이터 인코딩 과정이다. 

 

Label Encoding:

각 범주에 정수값을 할당하여 수치형으로 변환하는 과정이다. 레이블 인코딩의 경우, 범주들 간의 원치 않은 대소 관계가 생성되기 때문에 선형 모델에서 사용하기에는 적합하지 않다. 

 

from sklearn.preprocessing import LabelEncoder

# 예시 데이터
data = {'Category': ['냉장고', 'TV', '에어컨', '컴퓨터']}
df = pd.DataFrame(data)

# 레이블 인코딩
label_encoder = LabelEncoder()
df['Category_encoded'] = label_encoder.fit_transform(df['Category'])

 

encoder에 classes_ 속성값을 확인하면 어떻게 인코딩되었는지 확인이 가능하다. 출력되는 array의 순서대로 0, 1, 2, 3번 순으로 인코딩 되었음을 알 수 있다. 

label_encoder.classes_ # array(['TV', '냉장고', '에어컨', '컴퓨터'], dtype=object)

 

또한 인코딩된 데이터를 다시 원래의 데이터로 역변환하는 것 또한 가능하다.

label_encoder.inverse_transform(df['Category_encoded'])

 

⚠️ 라벨 인코딩은 하나의 범주형 칼럼에 대해서만 적용이 가능하다.
from sklearn.preprocessing import LabelEncoder
import pandas as pd

# 예제 데이터 프레임 생성
data = {'Color': ['Red', 'Green', 'Blue', 'Red', 'Green'],
        'Size': ['Small', 'Medium', 'Large', 'Medium', 'Small'],
        'Class': ['A', 'B', 'C', 'A', 'B']}

df = pd.DataFrame(data)

encoder = LabelEncoder()
encoder.fit_transform(df)​
ValueError: y should be a 1d array, got an array of shape (5, 3) instead.

따라서 여러 개의 컬럼에 라벨 인코딩을 적용하기 위해선 for문이나 apply 함수를 활용해야한다.

1. for문을 활용하는 방법
from sklearn.preprocessing import LabelEncoder
import pandas as pd

# 예제 데이터 프레임 생성
data = {'Color': ['Red', 'Green', 'Blue', 'Red', 'Green'],
        'Size': ['Small', 'Medium', 'Large', 'Medium', 'Small'],
        'Class': ['A', 'B', 'C', 'A', 'B']}

df = pd.DataFrame(data)

for col in df.columns:
    encoder = LabelEncoder()
    df[col] = encoder.fit_transform(df[col])​

2. apply 함수를 활용하는 방법
from sklearn.preprocessing import LabelEncoder
import pandas as pd

# 예제 데이터 프레임 생성
data = {'Color': ['Red', 'Green', 'Blue', 'Red', 'Green'],
        'Size': ['Small', 'Medium', 'Large', 'Medium', 'Small'],
        'Class': ['A', 'B', 'C', 'A', 'B']}

df = pd.DataFrame(data)

# 여러 컬럼에 대해 LabelEncoder 적용하는 함수
def label_encode_multiple_columns(df, col):
    encoder = LabelEncoder()
    df[col] = df[col].apply(lambda col: encoder.fit_transform(col))

# 'Color', 'Size', 'Class' 컬럼에 대해 LabelEncoder 적용
label_encode_multiple_columns(df, col=['Color', 'Size', 'Class'])

# 결과 출력
print(df)​

 

 

Ordinal Encoding:

범주 간의 상대적인 순서를 고려하여 레이블을 부여하는 인코딩으로 주로 순서형 변수에서 사용된다. Label Encoding의 경우 범주 간의 순서나 크기를 고려하지 않고 정수로 변환한다는 차이점을 가지고 있다. 

from sklearn.preprocessing import OrdinalEncoder

# 예시 데이터
data = {'Category': ['Low', 'Medium', 'High', 'Low']}
df = pd.DataFrame(data)

# Ordinal Encoding
ordinal_encoder = OrdinalEncoder(categories=[['Low', 'Medium', 'High']])
df['Category_encoded'] = ordinal_encoder.fit_transform(df[['Category']])

 

One-Hot Encoding:

새로운 피처들을 생성하여 각 범주에 해당하는 컬럼에만 1을 표시하고 나머지 컬럼들에 0을 표시하는 인코딩 방법이다. 

# 예시 데이터
data = {'Category': ['냉장고', 'TV', '에어컨', '컴퓨터']}
df = pd.DataFrame(data)

# 원-핫 인코딩
df_encoded = pd.get_dummies(df, columns=['Category'])

 

☑️  Data Scaling

척도가 다른 데이터들을 균일하게 만들어주는 과정을 의미한다. 특성들 간의 범위 차이가 발생할 경우 선형 모델과 거리 기반 모델에서 큰 영향을 끼칠 수 있다. 상대적으로 트리 모델은 순서 또는 크기에 영향을 받지 않으므로 데이터 스케일링 과정이 덜 중요할 수 있다.

 

표준화(Standardization):

표준화는 각 특성의 평균을 0, 표준편차를 1로 만들어주는 과정을 의미한다. 

 

$$x_{i_{\text{new}}} = \frac{x_i - \text{mean}(x)}{\text{stdev}(x)}$$

 

import numpy as np
from sklearn.preprocessing import StandardScaler

# 예시 데이터 생성
data = np.array([[1.0, 2.0, 3.0],
                 [4.0, 5.0, 6.0],
                 [7.0, 8.0, 9.0]])

# StandardScaler 객체 생성
scaler = StandardScaler()

# 데이터를 표준화
scaled_data = scaler.fit_transform(data)

print("Original Data:\n", data)
print("\nScaled Data (Standardized):\n", scaled_data)

 

정규화(Normalization):

정규화 과정은 각 특성의 값을 [0, 1] 또는 [-1, 1] 범위로 조절하는 과정을 의미한다. 

 

$$x_{normalized}=\frac{x-\text{min}(x)}{\text{max}(x)-\text{min}(x)}$$

 

import numpy as np
from sklearn.preprocessing import MinMaxScaler

# 예시 데이터 생성
data = np.array([[1.0, 2.0, 3.0],
                 [4.0, 5.0, 6.0],
                 [7.0, 8.0, 9.0]])

# 정규화
scaler_minmax = MinMaxScaler()
data_normalized = scaler_minmax.fit_transform(data)

# 결과 출력
print("Original Data:\n", data)
print("\nMinMax Normalized Data:\n", data_normalized)

 

# 실행 결과
# Original Data:
 [[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]

# Standardized Data:
 [[-1.22474487 -1.22474487 -1.22474487]
 [ 0.          0.          0.        ]
 [ 1.22474487  1.22474487  1.22474487]]

# MinMax Normalized Data:
 [[0. 0. 0.]
 [0.5 0.5 0.5]
 [1. 1. 1.]]

 

☑️  Feature Engineering

feature engineering이란 특성을 최적화하거나 새로운 특성을 만들어내는 과정을 말한다. 특성들 간의 관계를 고려하여 새로운 특성을 만들거나, 특성의 분포를 변환시키거나, 주성분 분석을 통해 차원을 축소하는 방법 등이 존재한다.

 

🔗 참고자료

 

'머신러닝' 카테고리의 다른 글

데이터 분할  (1) 2023.12.26
Data Wrangling  (0) 2023.12.12
머신러닝 개요  (0) 2023.12.12
N122 - 중심극한정리  (0) 2023.09.04
N121- 확률 및 베이즈 정리  (0) 2023.08.28