본문 바로가기

Python/Machine Learning

Machine Learning and Data Preprocessing(Supervised , Unsupervised/Regression(회귀) 과 Classification(분류)/ 카테고리컬 데이터를 처리하는 방법 - Label encoding / One Hot encoding/Feature Scailng : StandardScaler, MinMaxScaler

Machine Learning and Data Preprocessing

머신러닝으로 할 수 있는 것

  • 편지봉투에 손으로 쓴 우편번호 숫자 자동 판별
  • 의료 영상 이미지에 기반한, 종양 판단
  • 의심되는 신용카드 거래 감지
  • 블로그 글의 주제 분류
  • 고객들을 취향이 비슷한 그룹으로 묶기

머신러닝 : Supervised , Unsupervised

 

문제와 데이터 이해하기

  • 가지고 이는 데이터가 내가 원하는 문제의 답을 가지고 있는가?
  • 내 문제를 가장 잘 해결할 수 있는 머신러닝 방법은 무엇인가
  • 문제를 풀기에 충분한 데이터를 모았는가?
  • 머신러닝의 성과를 어떻게 측정할 것인가

용어 및 설명

레퍼런스 : https://www.youtube.com/watch?v=KDrys0OnVho

 

Supervised Learning

우리는 Iris꽃의 꽃잎의 길이와 넓이, 꽃받침의 길이와 넓이 데이터를 가지고 있다. 이 데이터들을 가지고, Iris 꽃 (붓꽃) 의 품종을 분류할 수 있는 분류기를 만든다.

따라서, 새로운 꽃잎의 길이와 넓이, 꽃받침의 길이와 넓이에 대한 데이터를 입력하면, 이 붓꽃이 어떤 품종인지 분석이 가능하다.

이렇게 분류할 수 있는 분류기(classifier) 를 만들기 위해서는 데이터가 필요하며,

학습을 하기 위해서는, 데이터 뿐만 아니라, 품종이라는 결과를 학습 시키기 위해서, 데이터와 매핑된 품종 데이터도 함께 필요하다.

즉, 품종에 대한 데이터를 Lable 이라고 한다. 즉 이러한 레이블이 있는 데이터를 학습시키는 것이 지도학습이다.

레이블을 가지고 학습시키는 방법을 지도 학습 (Supervised Learning) 라고 한다.
 

Regression(회귀) 과 Classification(분류)

Regression

  • 예 ) 어떤 사람의 교육수준, 나이, 주거지를 바탕으로 연간 소득을 예측하는 것
  • 예 ) 옥수수 농장에서 전년도 수확량과 날씨, 고용 인원수 등으로 올해 수확량을 예측하는 것

Classifiation

  • 예) 웹사이트가 어떤 언어로 되어있는가
  • 예) 사진을 보고, 고양이 인지 강아지 인지, 소인지 분류

 

Training 과 Test

* 훈련이란, 데이터를 입력하고, 그 결과인 레이블이 나오도록 만드는 과정.

즉, 데이터와 레이블을 통해 학습을 시키는 과정

* 테스트란, 학습이 완료된 분류기에, 학습에 사용하지 않은 데이터를 넣어서, 정답을 맞추는지 확인하는 작업


import library

# Data Preprocessing Template

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

import the dataset

df = pd.read_csv('data/Data.csv')
df


NaN 처리 -  nan 있는지 확인하고 시작하기.

df.isna().sum()
#######out
Country      0
Age          1
Salary       1
Purchased    0
dtype: int64

df = df.dropna()
df


X, Y 데이터 분리 : 즉 학습할 변수와 레이블링 변수로 분리

X = df.loc[ : , 'Country' : 'Salary' ]
y = df['Purchased']
X

-----  주의사항  ------

* y는 대문자로 쓰지 않는다.
* 데이터를 숫자로 바꿔야한다.

y
###### out
0     No
1    Yes
2     No
3     No
5    Yes
7    Yes
8     No
9    Yes
Name: Purchased, dtype: object

X['Country'].nunique()
######## 3

sorted( X['Country'].unique() ) #정렬 : sorted
####### out
['France', 'Germany', 'Spain']

* 숙지할 점

# 문자로 되어있는 데이터는, 방정식에 대입할 수가 없다.
# 따라서, 문자를 숫자로 바꿔줘야 하는데,
# 먼저,해당 컬럼이 카테고리컬 데이터인지 확인한다.
# 카테고리컬 데이터이면, 데이터를 먼저 정렬한다.

# 정렬한 후의 문자열을, 앞에서부터 0으로 숫자를 하나씩 매겨준다.

# France : 0
# Germany : 1
# Spain: 2

## Label Encoding (레이블 인코딩)이라고 한다.


y

* 원리

# France   Germany      Spain << 이렇게 컬럼을 늘린다.
#   1           0               0
#   0           0               1
#   0           1               0
#   0           0               1
#   1           0               0

 

--------------------------------------------------------------

* 숙지할 점

# 카테고리컬 데이터가 3개 이상일 때는, 레이블 인코딩으로 학습시키면 학습이 잘 되지 않는것을 알아냈다.
# 따라서, 3개 이상의 카테고리컬 데이터는, 
# One-Hot  Encoding (원 핫 인코딩) 을 이용해야 성능이 좋아진다.

 


데이터를 확인해 보니, 컴퓨터가 이해할 수 있도록 바꿔야 한다.

컴퓨터는 숫자로 처리한다.

숫자가 아닌 데이터 중에서, 카테고리로 판단되는 데이터는, 숫자로 바꿔줄 수 있다.

 


from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.compose import ColumnTransformer

 

1. 레이블 인코딩 하는 방법

encoder = LabelEncoder()
encoder.fit_transform( X['Country'] )
##### out
array([0, 2, 1, 2, 0, 0, 1, 0])

1. One Hot (원 핫) 인코딩 하는 방법

# [0] 이라고 쓴 이유는? X에서 원핫인코딩 할 컬럼이
# 컴퓨터가 매기는 인덱스로 0 이기 때문이다.
# 즉, 원핫 인코딩할 컬럼의 인덱스를 써주면, 변환시켜준다.
# 만약, 원핫 인코딩할 컬럼이 2개면 , 해당 컬럼의 인덱스를  리스트안에 적어주면 된다.

 

ct = ColumnTransformer ([('encoder', OneHotEncoder() , [0])]   ,   remainder = 'passthrough' )

 

  remainder = 'passthrough 내가 원하는 컬럼이 아닌 나머지 컬럼은 통과시켜라 라는 코드

  - 결과는, 원핫 인코딩한 컬럼이, 행렬의 맨 왼쪽에 나온다.

X = ct.fit_transform(X)
X
###### out
array([[1.0e+00, 0.0e+00, 0.0e+00, 4.4e+01, 7.2e+04],
       [0.0e+00, 0.0e+00, 1.0e+00, 2.7e+01, 4.8e+04],
       [0.0e+00, 1.0e+00, 0.0e+00, 3.0e+01, 5.4e+04],
       [0.0e+00, 0.0e+00, 1.0e+00, 3.8e+01, 6.1e+04],
       [1.0e+00, 0.0e+00, 0.0e+00, 3.5e+01, 5.8e+04],
       [1.0e+00, 0.0e+00, 0.0e+00, 4.8e+01, 7.9e+04],
       [0.0e+00, 1.0e+00, 0.0e+00, 5.0e+01, 8.3e+04],
       [1.0e+00, 0.0e+00, 0.0e+00, 3.7e+01, 6.7e+04]])
       
       
encoder_y = LabelEncoder()
y = encoder_y.fit_transform(y)
y
###### out
array([0, 1, 0, 0, 1, 1, 0, 1], dtype=int64)

Feature Scaling

Age 와 Salary 는 같은 스케일이 아니다.

Age 는 27 ~ 50 Salary 는 40k ~ 90k

# 유클리디언 디스턴스로 오차를 줄여 나가는데, 하나의 변수는 오차가 크고, 하나의 변수는 오차가 작으면, 나중에 오차를 수정할때 편중되게 된다. 
# 따라서 값의 레인지를 맞춰줘야 정확히 트레이닝 된다.

 

Feature Scaling 2가지 방법

  • 표준화 : 평균을 기준으로 얼마나 떨어져 있느냐? 같은 기준으로 만드는 방법, 음수도 존재, 데이터의 최대최소값 모를때 사용.
  • 정규화 : 0 ~ 1 사이로 맞추는 것. 데이터의 위치 비교가 가능, 데이터의 최대최소값 알떄 사용


from sklearn.preprocessing import StandardScaler, MinMaxScaler # 둘중에 하나 선택해서 코딩한다.
df.describe()


# 피쳐 스케일링도, X 따로, Y따로 한다.

X
####### out
array([[1.0e+00, 0.0e+00, 0.0e+00, 4.4e+01, 7.2e+04],
       [0.0e+00, 0.0e+00, 1.0e+00, 2.7e+01, 4.8e+04],
       [0.0e+00, 1.0e+00, 0.0e+00, 3.0e+01, 5.4e+04],
       [0.0e+00, 0.0e+00, 1.0e+00, 3.8e+01, 6.1e+04],
       [1.0e+00, 0.0e+00, 0.0e+00, 3.5e+01, 5.8e+04],
       [1.0e+00, 0.0e+00, 0.0e+00, 4.8e+01, 7.9e+04],
       [0.0e+00, 1.0e+00, 0.0e+00, 5.0e+01, 8.3e+04],
       [1.0e+00, 0.0e+00, 0.0e+00, 3.7e+01, 6.7e+04]])
       
       
s_scaler = StandardScaler()
s_scaler.fit_transform(X)
####### out
array([[ 1.        , -0.57735027, -0.57735027,  0.69985807,  0.58989097],
       [-1.        , -0.57735027,  1.73205081, -1.51364653, -1.50749915],
       [-1.        ,  1.73205081, -0.57735027, -1.12302807, -0.98315162],
       [-1.        , -0.57735027,  1.73205081, -0.08137885, -0.37141284],
       [ 1.        , -0.57735027, -0.57735027, -0.47199731, -0.6335866 ],
       [ 1.        , -0.57735027, -0.57735027,  1.22068269,  1.20162976],
       [-1.        ,  1.73205081, -0.57735027,  1.48109499,  1.55119478],
       [ 1.        , -0.57735027, -0.57735027, -0.211585  ,  0.1529347 ]])
       
     
X = s_scaler.fit_transform(X)

DatasetTraining 용과 Test용으로 나눈다.

X
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=3)
X_train
####### out
array([[ 1.        , -0.57735027, -0.57735027, -0.47199731, -0.6335866 ],
       [-1.        ,  1.73205081, -0.57735027,  1.48109499,  1.55119478],
       [-1.        , -0.57735027,  1.73205081, -0.08137885, -0.37141284],
       [-1.        , -0.57735027,  1.73205081, -1.51364653, -1.50749915],
       [ 1.        , -0.57735027, -0.57735027,  0.69985807,  0.58989097],
       [-1.        ,  1.73205081, -0.57735027, -1.12302807, -0.98315162]])


y_train
### out
array([1, 0, 0, 1, 0, 0], dtype=int64)

X_train.shape
### out
(6, 5)


X_test
#### out
array([[ 1.        , -0.57735027, -0.57735027,  1.22068269,  1.20162976],
       [ 1.        , -0.57735027, -0.57735027, -0.211585  ,  0.1529347 ]])
       
       
train_test_split(X, y ,test_size=0.2 , random_state=3)  
##### out
[array([[ 1.        , -0.57735027, -0.57735027, -0.47199731, -0.6335866 ],
        [-1.        ,  1.73205081, -0.57735027,  1.48109499,  1.55119478],
        [-1.        , -0.57735027,  1.73205081, -0.08137885, -0.37141284],
        [-1.        , -0.57735027,  1.73205081, -1.51364653, -1.50749915],
        [ 1.        , -0.57735027, -0.57735027,  0.69985807,  0.58989097],
        [-1.        ,  1.73205081, -0.57735027, -1.12302807, -0.98315162]]),
 array([[ 1.        , -0.57735027, -0.57735027,  1.22068269,  1.20162976],
        [ 1.        , -0.57735027, -0.57735027, -0.211585  ,  0.1529347 ]]),
 array([1, 0, 0, 1, 0, 0], dtype=int64),
 array([1, 1], dtype=int64)]