본문 바로가기
Tutorial/Big Data & ML

데이터 전처리의 중요성과 방법

by CLJ 2024. 7. 1.

데이터 전처리는 데이터 분석과 머신러닝 모델의 성능을 크게 좌우하는 중요한 과정입니다. 이번 글에서는 데이터 정제, 데이터 변환(스케일링, 정규화 등), 그리고 결측값 처리 및 데이터 증강에 대해 자세히 살펴보겠습니다.

 

1. 데이터 정제(Data Cleansing)

 

데이터 정제는 데이터 분석의 첫 번째 단계이자 가장 중요한 과정입니다. 이상값을 식별하고 제거하여 데이터의 정확성을 높이고, 중복 데이터를 제거하여 데이터의 일관성을 유지하며, 결측값을 처리하여 데이터의 완성도를 높이는 것이 데이터 정제의 주요 목표입니다. 이러한 과정을 통해 깨끗하고 신뢰할 수 있는 데이터를 확보하고, 더 나은 분석 결과와 비즈니스 성과로 이어질 수 있습니다.

 

이상값(Outlier) 식별

이상값(outlier)은 데이터 분포에서 극단적으로 벗어난 값으로, 종종 데이터 분석 결과에 큰 영향을 미칠 수 있습니다. 히스토그램이나 상자 그림(box plot)과 같은 시각화 도구를 사용하여 데이터의 분포를 시각화하면 이상값을 쉽게 발견할 수 있습니다. 이상값을 식별한 후에는 이를 제거하거나 적절하게 수정해야 합니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 예시 데이터 생성
data = {'가격': [100, 150, 200, 250, 300, 350, 400, 450, 5000]}
df = pd.DataFrame(data)

# 히스토그램을 사용한 이상값 시각화
plt.hist(df['가격'], bins=10)
plt.xlabel('가격')
plt.ylabel('빈도')
plt.title('가격 분포 히스토그램')
plt.show()

# 이상값 식별 및 제거
Q1 = df['가격'].quantile(0.25)
Q3 = df['가격'].quantile(0.75)
IQR = Q3 - Q1

# IQR을 이용한 이상값 제거
filtered_df = df[~((df['가격'] < (Q1 - 1.5 * IQR)) | (df['가격'] > (Q3 + 1.5 * IQR)))]
print(filtered_df)
    

 

위 코드에서는 먼저 pandas, numpy, matplotlib.pyplot 라이브러리를 불러옵니다. 그런 다음 예시 데이터를 생성하여 '가격' 열을 가진 데이터프레임을 만듭니다. 히스토그램을 그려 '가격'의 분포를 시각화하고, IQR(사분위 범위)을 계산하여 이상값을 식별합니다. 마지막으로 IQR을 기준으로 이상값을 제거한 후 필터링된 데이터프레임을 출력합니다.

 

가격 분포 히스토그램, filtered_df

 

중복 데이터 제거

 

중복 데이터는 분석 결과를 왜곡시키고, 불필요한 계산을 증가시킵니다. 예를 들어, 고객 데이터베이스에서 동일한 고객이 여러 번 등록되어 있는 경우, 이를 하나로 통합해야 합니다. 이를 위해 데이터베이스의 기본 키(primary key)를 활용하여 중복된 레코드를 식별하고 제거할 수 있습니다.

# 예시 데이터 생성
data = {'고객ID': [1, 2, 2, 3, 4, 4, 5], '이름': ['홍길동', '김철수', '김철수', '박영희', '이순신', '이순신', '정약용']}
df = pd.DataFrame(data)

# 중복 데이터 확인
print(df.duplicated())

# 중복 데이터 제거
df_unique = df.drop_duplicates()
print(df_unique)

 

이 코드에서는 고객 ID와 이름을 가진 예시 데이터를 생성합니다. df.duplicated()를 사용하여 중복된 행을 확인하고, df.drop_duplicates()를 사용하여 중복 데이터를 제거한 후 중복이 제거된 데이터프레임을 출력합니다. 중복 데이터는 고객 ID와 이름이 동일한 경우로 간주됩니다.

중복 데이터 확인 df.duplicated(), 중복데이터 제거 df.drop_duplicates()

결측값(Missing value) 처리

결측값은 데이터의 완성도를 낮추고 분석 결과의 신뢰성을 떨어뜨릴 수 있습니다. 결측값(missing value)은 다양한 원인으로 발생할 수 있으며, 이를 적절히 처리하지 않으면 분석 결과가 왜곡될 수 있습니다. 결측값(missing value)의 처리는 여러 가지 방법으로 수행될 수 있습니다. 결측값이 포함된 데이터를 삭제하는 방법, 결측값을 평균값이나 중앙값으로 대체하는 방법, 그리고 결측값을 예측하여 보완하는 방법이 있습니다. 데이터의 특성과 분석 목적에 따라 가장 적절한 방법을 선택하는 것이 중요합니다. 

 

결측값 삭제

결측값 삭제는 결측값을 포함한 데이터를 제거하는 방법입니다. 데이터셋이 충분히 크고 결측값이 적은 경우에 유용합니다. 그러나 결측값이 많을 경우 데이터의 손실이 클 수 있습니다. 

import pandas as pd

# 예시 데이터 생성
data = {'이름': ['홍길동', '김철수', '박영희', '이순신', '정약용'],
        '나이': [28, None, 34, 45, None]}
df = pd.DataFrame(data)

# 결측값 삭제
df_dropped = df.dropna()
print(df_dropped)

 

이 코드에서는 pandas 라이브러리를 사용하여 데이터프레임을 생성하고, dropna() 메서드를 사용하여 결측값이 포함된 행을 삭제합니다.

결측값 삭제 df_dropped

 

결측값 대체

 

결측값 대체는 결측값을 평균값, 중앙값, 최빈값 등으로 채우는 방법입니다. 이 방법은 결측값을 제거하지 않으면서 데이터의 완성도를 높일 수 있습니다. 

# 예시 데이터 생성
data = {'이름': ['홍길동', '김철수', '박영희', '이순신', '정약용'],
        '나이': [28, np.nan, 34, 45, np.nan]}
df = pd.DataFrame(data)

# 결측값 확인
print(df.isnull())

# 결측값을 평균값으로 대체
df['나이'].fillna(df['나이'].mean(), inplace=True)
print(df)

 

이 예시에서는 이름과 나이 열을 가진 데이터프레임을 생성합니다. df.isnull()을 사용하여 결측값을 확인하고, df['나이'].fillna(df['나이'].mean(), inplace=True)를 사용하여 나이 열의 결측값을 평균값으로 대체합니다. 이 과정에서 결측값이 평균값으로 채워진 데이터프레임이 출력됩니다.

결측값 확인- df.isnull(), 결측값을 평균값으로 대체

결측값 예측

결측값 예측은 머신러닝 모델을 사용하여 결측값을 예측하는 방법입니다. 이 방법은 결측값을 보다 정확하게 대체할 수 있으며, 데이터의 일관성을 유지하는 데 도움이 됩니다. 예를 들어, K-최근접 이웃(KNN)이나 회귀 모델을 사용하여 결측값을 예측할 수 있습니다.

from sklearn.impute import KNNImputer

# 예시 데이터 생성
data = {'특징1': [1, 2, 3, 4, None],
        '특징2': [6, 7, None, 9, 10]}
df = pd.DataFrame(data)
print(df)

# KNN을 사용한 결측값 예측
imputer = KNNImputer(n_neighbors=2)
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
print(df_imputed)

 

이 코드에서는 sklearn 라이브러리의 KNNImputer를 사용하여 결측값을 예측합니다. KNNImputer는 K-최근접 이웃 알고리즘을 사용하여 결측값을 대체합니다.

df 데이트프레임, KNN을 사용한 결측값 예측 df_imputed 데이터프레임

 

2. 데이터 변환

데이터 변환 단계에서 스케일링과 정규화는 가장 많이 사용되는 기법입니다. 데이터 변환을 통해 데이터의 범위와 분포를 조정하면, 분석의 정확성과 모델의 성능을 높일 수 있습니다.

 

 

스케일링

 

스케일링은 데이터를 일정한 범위로 변환하는 과정입니다. 스케일링을 통해 각 변수의 값이 동일한 범위 내에 들어오도록 하여, 데이터 간의 비교를 용이하게 만들고, 머신러닝 모델의 학습 속도와 성능을 향상시킬 수 있습니다. 대표적인 스케일링 방법에는 Min-Max 스케일링과 표준화(standardization)가 있습니다.

 

Min-Max 스케일링

 

Min-Max 스케일링은 데이터의 최소값과 최댓값을 기준으로 모든 데이터를 0에서 1 사이의 값으로 변환합니다. 이 방법은 데이터의 분포를 유지하면서도, 각 변수의 범위를 동일하게 만듭니다. 예를 들어, 다음과 같은 수식을 사용하여 Min-Max 스케일링을 수행할 수 있습니다:

X' = (X - X_min) / (X_max - X_min)

 

Python 코드 예시는 다음과 같습니다:

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

# 예시 데이터 생성
data = {'가격': [100, 150, 200, 250, 300, 350, 400, 450, 500]}
df = pd.DataFrame(data)

# Min-Max 스케일링 적용
scaler = MinMaxScaler()
df['가격'] = scaler.fit_transform(df[['가격']])
print(df)

 

이 코드에서는 pandas와 sklearn 라이브러리를 사용합니다. 데이터프레임을 생성하고, MinMaxScaler를 사용하여 '가격' 열의 값을 0에서 1 사이로 변환합니다.

Min-Max 스케일링 적용 결과 dataframe df

표준화(standardization)

표준화는 데이터의 평균을 0, 표준편차를 1로 변환하여 데이터를 정규분포 형태로 만듭니다. 이 방법은 특히 데이터의 분포가 정규분포를 따를 때 효과적입니다. 표준화를 위해 다음과 같은 수식을 사용합니다:

X' = (X - μ) / σ

 

여기서 μ는 평균, σ는 표준편차입니다. Python 코드 예시는 다음과 같습니다.

from sklearn.preprocessing import StandardScaler

# 예시 데이터 생성
data = {'가격': [100, 150, 200, 250, 300, 350, 400, 450, 500]}
df = pd.DataFrame(data)

# 표준화 적용
scaler = StandardScaler()
df['가격'] = scaler.fit_transform(df[['가격']])
print(df)

 

이 코드에서는 StandardScaler를 사용하여 '가격' 열의 값을 표준화합니다. 데이터를 평균 0, 표준편차 1로 변환하여 정규분포 형태로 만듭니다.

표준화 적용한 df 데이터프레임

정규화

정규화는 데이터를 일정한 분포로 변환하는 과정입니다. 이를 통해 각 변수의 중요도를 동일하게 만들고, 분석의 일관성을 높일 수 있습니다. 대표적인 정규화 방법에는 L1 정규화와 L2 정규화가 있습니다.

 

L1 정규화

 

L1 정규화는 데이터의 절대값 합이 1이 되도록 변환하는 방법입니다. 이 방법은 스파스(sparse)한 데이터셋, 즉 대부분의 값이 0인 데이터셋에서 효과적입니다. L1 정규화는 다음과 같은 수식을 사용합니다:

X' = X / ‖X‖_1

 

여기서 ‖X‖_1는 데이터의 절댓값 합입니다. Python 코드 예시는 다음과 같습니다.

from sklearn.preprocessing import Normalizer

# 예시 데이터 생성
data = {'특징1': [4, 1, 2], '특징2': [2, 3, 5]}
df = pd.DataFrame(data)

# L1 정규화 적용
scaler = Normalizer(norm='l1')
df[['특징1', '특징2']] = scaler.fit_transform(df[['특징1', '특징2']])
print(df)

 

이 코드에서는 Normalizer를 사용하여 L1 정규화를 수행합니다. 데이터의 각 행이 절댓값 합이 1이 되도록 변환합니다.

L1 정규화 적용 df

L2 정규화

L2 정규화는 데이터의 제곱합이 1이 되도록 변환하는 방법입니다. 이 방법은 데이터의 크기를 조정하면서도 데이터 간의 상대적인 차이를 유지하는 데 효과적입니다. L2 정규화는 다음과 같은 수식을 사용합니다:

X' = X / ‖X‖_2

 

여기서 ‖X‖_2는 데이터의 제곱합입니다. Python 코드 예시는 다음과 같습니다:

# L2 정규화 적용
scaler = Normalizer(norm='l2')
df[['특징1', '특징2']] = scaler.fit_transform(df[['특징1', '특징2']])
print(df)

 

이 코드에서는 Normalizer를 사용하여 L2 정규화를 수행합니다. 데이터의 각 행이 제곱합이 1이 되도록 변환합니다.

 

L2 정규화 적용 df

 

 

위에서 간단히 스케일링과 정규화를 알아보았습니다. 이러한 과정은 데이터 분석과 머신러닝에서 필수적인 단계입니다. 다양한 변수들이 서로 다른 범위를 가질 때, 스케일링을 통해 데이터를 동일한 범위로 조정하면 모델의 학습 과정이 원활해집니다. 또한, 정규화를 통해 데이터의 분포를 일정하게 만들면 분석의 일관성을 유지할 수 있습니다.

 

예를 들어, 주택 가격 예측 모델을 구축할 때 주택의 크기(평방미터)와 가격(원)이 매우 다른 범위를 가질 수 있습니다. 이 경우, 스케일링을 통해 두 변수를 동일한 범위로 조정하면 모델이 두 변수를 공정하게 비교할 수 있습니다. 또한, 정규화를 통해 데이터의 분포를 일정하게 만들면 모델이 더욱 일관된 예측을 할 수 있습니다.

 

데이터 변환은 데이터의 범위와 분포를 조정하여 분석의 정확성과 모델의 성능을 높이는 데 필수적인 과정입니다. 스케일링과 정규화를 적절히 활용하면, 데이터 분석과 머신러닝에서 더욱 신뢰할 수 있는 결과를 얻을 수 있습니다.

 

3. 데이터 증강 (Data Augmentation)

 

데이터 증강(data augmentation)은 기존 데이터를 다양한 방법으로 변형하여 새로운 데이터를 생성하는 방법입니다. 이 방법은 특히 데이터가 부족할 때 유용하며, 모델의 일반화 성능을 향상시키는 데 도움이 됩니다.

 

이미지 데이터 증강

 

이미지 데이터 증강은 이미지를 다양한 방식으로 변형하여 새로운 이미지를 생성하는 방법입니다. 

# 라이브러리 설치
# pip install tensorflow

from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img

# 이미지 데이터 증강 설정
datagen = ImageDataGenerator(
    rotation_range=40,
    horizontal_flip=True,
    fill_mode='nearest')

# 예시 이미지 불러오기
img = load_img('sample_image.jpg')
x = img_to_array(img)
x = x.reshape((1,) + x.shape)

# 이미지 데이터 증강 생성
i = 0
for batch in datagen.flow(x, batch_size=1, save_to_dir='preview', save_prefix='aug', save_format='jpeg'):
    i += 1
    if i > 5:
        break  # 증강된 이미지 5개 생성 후 중단

 

위 코드는 간단한 회전과 수평 뒤집기를 사용하여 이미지를 증강합니다. 증강된 이미지는 'preview' 디렉토리에 저장됩니다.

 

텍스트 데이터 증강

텍스트 데이터 증강은 문장의 구조를 변경하거나, 동의어를 사용하여 새로운 문장을 생성하는 방법입니다. 

# 라이브러리 설치
# pip install nlpaug
# pip install nltk

import nlpaug.augmenter.word as naw

# 텍스트 데이터 증강 설정
aug = naw.SynonymAug(aug_src='wordnet')

# 예시 텍스트 데이터
sentence = 'The quick brown fox jumps over the lazy dog'

# 텍스트 데이터 증강
augmented_sentences = set()
attempts = 0
while len(augmented_sentences) < 5 and attempts < 100:
    augmented_sentence = aug.augment(sentence)
    if isinstance(augmented_sentence, list):
        augmented_sentence = augmented_sentence[0]
    if augmented_sentence != sentence:
        augmented_sentences.add(augmented_sentence)
    attempts += 1

for augmented_sentence in augmented_sentences:
    print(augmented_sentence)

 

위의 코드는 nlpaug 라이브러리를 사용하여 텍스트 데이터를 증강합니다. 동의어를 통해 문장을 변형하여 다양한 표현을 생성합니다.

 

결론

 

데이터 전처리는 데이터 분석과 머신러닝 모델의 성능을 극대화하는 데 필수적인 과정입니다. 데이터 정제를 통해 이상치, 중복 데이터, 결측치를 처리하고, 데이터 변환을 통해 분석에 적합한 형태로 변환하며, 데이터 증강을 통해 부족한 데이터를 보완할 수 있습니다. 이러한 전처리 과정을 통해 데이터의 신뢰성을 높이고, 보다 정확한 분석 결과를 도출할 수 있습니다. 데이터 전처리에 충분한 시간을 투자하여 더 나은 분석 결과와 모델 성능을 기대할 수 있습니다.

 

2024.07.07 - [Big Data & ML] - 데이터 시각화 (Data Visualization) 도구, 기법 및 heapmap 수치표시 안되는 문제 해결

 

데이터 시각화 (Data Visualization) 도구, 기법 및 heapmap 수치표시 안되는 문제 해결

데이터 시각화는 데이터 분석의 핵심 요소로, 복잡한 데이터를 이해하기 쉽게 시각적으로 표현하는 방법입니다. 이 글에서는 데이터 시각화 도구, 데이터를 시각화하는 기본적인 기법, 히트맵

it-learner.tistory.com

 

 

2024.06.30 - [Machine Learning] - 머신 러닝 프로세스 이해하기

 

머신 러닝 프로세스 이해하기

머신 러닝 프로젝트는 여러 단계로 이루어진 복잡한 과정입니다. 데이터 수집부터 모델 배포와 유지 보수에 이르기까지 각 단계는 성공적인 머신 러닝 솔루션을 만드는 데 중요합니다. 이 글에

it-learner.tistory.com