데이터 전처리(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
가장 작은 값을 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)
'MS AI School' 카테고리의 다른 글
DAY 19 - 머신러닝 지도 학습: 선형 회귀 (0) | 2022.11.01 |
---|---|
DAY 18 - Scikit Learn 머신러닝 모델 만들기 (0) | 2022.11.01 |
DAY 14 - Flask, Web crawling(BS4), MySQL (0) | 2022.11.01 |
DAY 13 - Matplotlib (0) | 2022.11.01 |
DAY 12 - Numpy(파이썬 기반 배열) (0) | 2022.11.01 |