728x90
데이터 전처리(Data Preprocessing):
데이터를 분석하기 편하게 만드는 작업.
전체 프로젝트의 80~90%의 시간이 소요되는 데이터 전처리 과정에 대해 알아보자.

 

 


 

          짬뽕(label)        

 

 

 

 

위의 그림은 "문제"(feature)이고 아래는 "답(label)"이다. 데이터가 있으면 라벨을 붙이는 것을 라벨링(labelling)이라고 한다. 라벨링은 시간과 돈이 많이 소요되는 작업이다.

 

- Feature (특성): 데이터에서 중요한 속성이나 정보를 나타내는 부분이다. 이는 모델이 학습하는 동안 입력으로 사용되는 데이터의 특징을 의미한다. 예를 들어, 꽃의 특성들(꽃잎의 길이, 꽃잎의 폭 등)이나 주택의 특성들(면적, 방의 개수, 욕실의 개수 등)은 feature이다. 이러한 특성들은 모델에 입력되어 모델이 예측이나 분류를 수행하는 데 사용된다.

- Label (레이블): 모델이 학습하고자 하는 목표 값 또는 예측하고자 하는 출력 변수이다. 예를 들어, 학생들의 시험 점수 데이터에서 합격 여부(합격 또는 불합격)가 레이블이 될 수 있다. 이미지 분류 문제에서는 "고양이", "개", "자동차" 등의 카테고리를 사용할 수 있다.

간단히 말하면, feature는 모델에 입력되는 데이터의 특징이고, label은 모델이 예측하거나 분류하려는 목표 값이다. feature는 모델에 정보를 제공하고, label은 모델의 학습이나 예측에 사용되는 값이다.

 


예시 1: 이진 분류 문제
- Feature: 학생의 시험 점수
- Label: 시험 결과 (합격 또는 불합격)


예시 2: 다중 클래스 분류 문제
- Feature: 꽃의 꽃잎 길이, 꽃잎 폭, 꽃받침 길이, 꽃받침 폭
- Label: 꽃의 종류 (Setosa, Versicolor, Virginica)

 


예시 3: 회귀 문제
- Feature: 주택의 면적, 방의 개수, 욕실의 개수
- Label: 주택 가격



 

 

  • 데이터에서 나타나는 문제들
    • 결측치: 데이터에 값이 없는 것. NA, NaN
    • 데이터 오류: 잘못된 데이터가 입력된 것
    • 이상치: 값의 범위가 일반적인 범위에서 벗어난 것
    • 데이터 형식: 데이터 형식이 분석하기에 적합하지 않은 것
    • 범주형 데이터의 오형태: 범주형으로 표현되어야 하는 데이터가 다른 형태로 되어 있는 경우
      (범주형 데이터는 'A', 'B', 'C'와 같이 종류를 표시하는 데이터를 말한다)
  • 문제점을 해결하기 위해서 사용되는 데이터 전처리 기법
    • Scaling
    • Sampling
    • Dimensionality Reduction(차원의 축소)
    • Categorical Variable Numeric Variable

 

 

1. Scaling

 

변수의 크기가 너무 작거나 너무 큰 경우, 변수의 크기를 일정하게 맞춰 주는 작업.

■ 종류

  • Min-Max Scaling

X: 데이터 셋, x; 데이터 샘플

 

가장 작은 값을 0, 가장 큰 값을 1로 두고, 나머지 값들을 0과 1 사이의 값으로 변환하는 것이다. x라는 값을 스케일링 한다고 하면, (x-최소값)을 (최대값-최소값)으로 나누어 준다.  예를 들어 x= 10, 최대값=50, 최소값=5라고 하면 (10-5)/(50-5)= 0.1이 된다.

 

  • z- 정규화를 이용한 Standard Scaling

 

표준편차: 통계 집단의 분산을 제곱근한 것. 표준편차가 작을수록 평균값에서 변량들의 거리가 가깝다.

분산: 관측값에서 평균을 뺀 값을 제곱하고 그것을 모두 더한 후 전체 개수로 나눠서 구한 값이다.

 

점수 데이터: 5, 10, 5, 3, 7, 8, 10, 10, 7, 5

평균값= 7

분산 구하기= {(5-7)^2+(10-7)^2+(5-7)^2+(3-7)^2+(7-7)^2+(8-7)^2+(10-7)^2+(10-7)^2+(7-7)^2+(5-7)^2}/10=5.6

표준편차=2.36

 

x=8을 가지고 위의 공식에 대입해 보면  (8-7)/2.36=0.4237

 

---> 표준정규분포화 시켜 데이터의 평균이 0, 표준 편차가 1이 되도록 스케일링한다.

 

 

 

2. Sampling

 

클래스 불균형 문제를 처리하는 작업. Undersampling, Oversampling, Random Oversampling, Undersampling, SMOTE(Synthetic Minority Oversampling Technique)가 있다. 알고리즘은 imblearn을 사용한다.

 

  • Undersampling: 불균형한 데이터 셋에서 높은 비율을 차지하는 클래스의 데이터 수를 줄이는 것
  • Oversampling: 불균형한 데이터 셋에서 낮은 비율을 차지하는 클래스의 데이터 수를 늘리는 것
  • Random Oversampling: 기존에 존재하는 소수의 클래스를 무작위로 단순 복제하여 비율을 맞춰주는 것. 분포 변화X, 가중치 多. *과적합 문제가 발생하기도 한다.
  • Random Undersampling: 기존에 존재하는 다수의 클래스를 무작위로 단순 복제하여 비율을 맞춰주는 것.
  • SMOTE(Synthetic Minority Oversampling Technique): 오버샘플링 기법 중 하나로, 수가 적은 클래스의 데이터를 KNN 알고리즘을 활용하여 새롭게 생성하는 방법이다. Random Oversampling보다 과적합 발생 가능성이 낮다. 수가 적은 클래스의 점을 하나 선택해 k개의 가까운 데이터 샘플을 찾고 그 사이에 새로운 점을 생성하는 방식

 

 

3. Dimensionality Reduction(차원의 축소)

 

저차원에서 일어나지 않았던 현상이 고차원에서 발생하는 현상(=차원의 저주). 공간의 크기가 증가할 경우 데이터가 존재하지 않는 빈 공간이 생김으로 인해 문제 발생. --> 차원을 축소한다.

 

 

 

4. Categorical Variable to Numeric Variable

 

범주형 데이터를 수치화 하기

  • Label Encoding: 정수로 매핑하는 방법.
    예) 사과, 바나나, 오렌지 ---> 0, 1, 2 
  • One-hot Encoding: 이진값으로 새로운 feature를 주는 것. 예를 들어 고양이, 사자, 말 세 가지를 표현하기 위해서는 3개의 비트가 필요하다. 순서가 없는 경우, 고유값 개수가 많지 않은 경우 사용한다.
    예) 고양이, 사자, 말 --> [1, 0, 0], [0, 1, 0], [0, 0, 1]

 

 

 

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

import sklearn # Machine Learning Framework 
import os
from os.path import join

abalone_path = join('.', 'abalone.txt') #.은 현재경로 ..는 상위 경로
column_path = join('.', 'abalone_attributes.txt')

print(abalone_path)  # 암수 정보 데이터. 어떤 조건이면 암컷이 되고, 수컷이 되는지 M(수컷), F(암컷), I(미정)

abalone_columns = list() # 리스트 객체로 만들기
for line in open(column_path):
  abalone_columns.append(line)

print(abalone_columns)
"""
['Sex\n', 'Length\n', 'Diameter\n', 'Height\n', 'Whole weight\n', 'Shucked weight\n', 'Viscera weight\n', 'Shell weight\n', 'Rings']
"""

#불필요한 요소들 잘라내기
abalone_columns = list()
for line in open(column_path):
  abalone_columns.append(line.strip()) #abalone_columns에 저장하기

print(abalone_columns)

pd.read_csv(abalone_path, header = None, names = abalone_columns)

#data 변수에 저장
data = pd.read_csv(abalone_path, header = None, names = abalone_columns)

print(data)

label = data['Sex']
del data['Sex']

data.describe()

data.info()

#Scaling하기

#data = (data - np.min(data)) / (np.max(data) - np.min(data))
#print(data)

#위와 같이 코딩하지 않아도 MinMaxScaler를 사용하면 처리된다

from sklearn.preprocessing import MinMaxScaler
mMscaler = MinMaxScaler()
#fit()
#mMscaler.fit(data)
#transfrom()
#mScaled_data = mMscaler.transform(data)
mScaled_data = mMscaler.fit_transform(data)
mScaled_data

#numpy 배열을 pandas에 있는 data frame 객체로 바꿔주기(보기 좋게)

mScaled_data = pd.DataFrame(mScaled_data, columns = data.columns)
mScaled_data

from sklearn.preprocessing import StandardScaler
sdscaler = StandardScaler()

sdscaled_data = sdscaler.fit_transform(data)

#NumPy배열로 되어 있는 data를 Pandas로 바꾸기
sdscaled_data = pd.DataFrame(sdscaled_data, columns=data.columns)
print(sdscaled_data)

# Samlping

from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler

ros = RandomOverSampler()
rus = RandomUnderSampler()

#resampling

oversampled_data, oversampled_label = ros.fit_resample(data, label)
undersampled_data, undersampled_label = rus.fit_resample(data, label)

oversampled_data = pd.DataFrame(oversampled_data, columns=data.columns)
undersampled_data = pd.DataFrame(undersampled_data, columns=data.columns)

print('원본 데이터의 클래스 비율: \n{}'.format(pd.get_dummies(label).sum()))
print('Oversample 데이터의 클래스 비율: \n{}'.format(pd.get_dummies(oversampled_label).sum()))
print('Undersample 데이터의 클래스 비율: \n{}'.format(pd.get_dummies(undersampled_label).sum()))

#n_informative 튀는 data

from sklearn.datasets import make_classification
data, label = make_classification(n_samples=1000,
                    n_features=2,
                    n_redundant=0,
                    n_informative=2,
                    n_repeated=0,
                    n_classes=3,
                    n_clusters_per_class=1,
                    weights=[0.05,0.15,0.8],
                    class_sep=0.8,
                    random_state=2019)

#나오는 결과값 첫번째: 데이터, 두 번째: 라벨

plt.Figure(figsize=(12, 6))
plt.scatter(data[:,0],data[:,1],c=label,alpha=0.3) #alpha 투명도

from imblearn.over_sampling import SMOTE
smote = SMOTE()

smoted_data, smoted_label = smote.fit_resample(data, label)

print('원본 데이터의 클래스 비율 \n{}'.format(pd.get_dummies(label).sum()))
print('\nSOMTE 결과 \n{}'.format(pd.get_dummies(smoted_label).sum()))

fig = plt.Figure(figsize=(12,6))
plt.scatter(smoted_data[:,0],smoted_data[:,1],c=smoted_label,alpha=0.3)

# 차원의 축소

from sklearn.datasets import load_digits
digits = load_digits()

print(digits.DESCR)

data = digits.data
label = digits.target

data.shape

label.shape

data[0].reshape(8,8)

label[0]

plt.imshow(data[0].reshape((8,8)))
print('Label: {}'.format(label[0]))

from sklearn.decomposition import PCA #주성분분석
pca = PCA(n_components=2)

new_data = pca.fit_transform(data)

print('원본 데이터의 차원 \n{}'.format(data.shape))
print('PCA를 거친 데이터의 차원 \n{}'.format(new_data.shape))

new_data[0] #data[0]을 2개의 차원으로 압축한 것

data[0] #64차원

plt.scatter(new_data[:, 0], new_data[:, 1], c=label, alpha=0.4)
plt.legend()

data = pd.read_csv(abalone_path, header=None, names=abalone_columns)

label = data['Sex']

from sklearn.preprocessing import LabelEncoder
le =LabelEncoder()

type(label)

print(label)

#위의 MFI 자료를 숫자로 바꿔주기
label_encoded_label = le.fit_transform(label)
label_encoded_label

#One Hot Encoding #(sparse=False) 넣어야 배열 형태의 결과 나옴. 기본값은 True로 매트릭스 형태

from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(sparse=False) #True

one_hot_encoded = ohe.fit_transform(label.values.reshape((-1,1)))

print(one_hot_encoded)
728x90

+ Recent posts