from IPython.display import Image
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
# unicode 에러
plt.rcParams['axes.unicode_minus'] = False경고 메시지 출력 표기 생략
표준화 (Standardization)
표준화는 데이터의 평균을 0 분산 및 표준편차를 1로 만들어 줍니다.
표준화를 하는 이유
- 서로 다른 통계 데이터들을 비교하기 용이하기 때문입니다.
- 표준화를 하면 평균은 0, 분산과 표준편차는 1로 만들어 데이터의 분포를 단순화 시키고, 비교를 용이하게 합니다.
표준화 공식
\(\Large z = \frac{(X - \mu)}{\sigma}\)
샘플데이터
iris 붓꽃 샘플데이터를 가져옵니다.
from sklearn.datasets import load_iris- iris 데이터를 가져와
iris변수에 대입합니다.
# 코드를 입력해 주세요
iris = iris 데이터를 활용하여 DataFrame을 생성해 주세요
# 코드를 입력해 주세요
df =
df.head()[출력 결과]
| sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | target | |
|---|---|---|---|---|---|
| 0 | 5.1 | 3.5 | 1.4 | 0.2 | 0 |
| 1 | 4.9 | 3.0 | 1.4 | 0.2 | 0 |
| 2 | 4.7 | 3.2 | 1.3 | 0.2 | 0 |
| 3 | 4.6 | 3.1 | 1.5 | 0.2 | 0 |
| 4 | 5.0 | 3.6 | 1.4 | 0.2 | 0 |
4개의 feature 데이터 중 sepal length (cm)의 feature만 임의로 선택하여 X 변수에 저장합니다.
sepal length (cm) 컬럼만 X 변수에 저장
# 코드를 입력해 주세요
X = 표준화 코드 구현
표준화를 Python으로 직접 구현하면 다음과 같습니다. 공식을 그대로 코드로 옮기면 됩니다.
X_변수에 바로 위에서 만든X변수를 표준화를 거친 후 결과를 담습니다.
\(\Large z = \frac{(X - \mu)}{\sigma}\)
# 코드를 입력해 주세요
X_ = 시각화
시각화로 표준화의 전과 후를 비교합니다.
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.distplot(X, bins=5, color='b')
plt.title('Original', fontsize=16)
plt.subplot(1, 2, 2)
sns.distplot(X_, bins=5, color='r')
plt.title('Standardization', fontsize=16)
plt.show()iris 붓꽃 데이터 분포 시각화
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.scatterplot(df['sepal length (cm)'], df['sepal width (cm)'], hue=df['target'], palette='Set1')
plt.title('Sepal', fontsize=16)
plt.subplot(1, 2, 2)
sns.scatterplot(df['petal length (cm)'], df['petal width (cm)'], hue=df['target'], palette='Set1')
plt.title('Petal', fontsize=16)
plt.show()StandardScaler의 활용
sklearn.preprocesssing 에 StandardScaler로 표준화 (Standardization) 할 수 있습니다.
from sklearn.preprocessing import StandardScaler# 코드를 입력해 주세요
scaler = feature 데이터를 표준화 합니다. (표준화 할 때는 Y 값은 제외합니다.)
# 코드를 입력해 주세요
scaled_data = scaled_data[:5]# 코드검증
round(scaled_data.mean(), 2), scaled_data.std()[출력 결과]
(-0.0, 1.0)
Scale 전, 후 비교 (시각화)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.scatterplot(df['sepal length (cm)'], df['sepal width (cm)'], hue=df['target'], palette='Set1')
plt.title('Sepal (Original)', fontsize=16)
plt.subplot(1, 2, 2)
sns.scatterplot(scaled_data[:, 0], scaled_data[:, 1], hue=df['target'], palette='Set1')
plt.title('Sepal (Scaled)', fontsize=16)
plt.show()plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.scatterplot(df['petal length (cm)'], df['petal width (cm)'], hue=df['target'], palette='Set1')
plt.title('Petal (Original)', fontsize=16)
plt.subplot(1, 2, 2)
sns.scatterplot(scaled_data[:, 2], scaled_data[:, 3], hue=df['target'], palette='Set1')
plt.title('Petal (Scaled)', fontsize=16)
plt.show()정규화 (Normalization)
정규화 (Normalization)도 표준화와 마찬가지로 데이터의 스케일을 조정합니다.
정규화가 표준화와 다른 가장 큰 특징은 모든 데이터가 0 ~ 1 사이의 값을 가집니다.
즉, 최대값은 1, 최소값은 0으로 데이터의 범위를 조정합니다.
정규화 코드 구현
sepal length (cm) 컬럼만 X 변수에 저장
# 코드를 입력해 주세요
X = 정규화 공식
Image(url='https://mblogthumb-phinf.pstatic.net/MjAxODA3MzFfMjgx/MDAxNTMzMDIxNzg5MTkz.odx32KoGhDrjwJHgjb_NslL1Nlmsp4veLz6OULb2q00g.5Ynl7GOds1YAgBgJ_TSiuWjHZfrNWPq3hsHtwCjvNP0g.PNG.angryking/image_4532734831533021765958.png?type=w800', width=200)정규화 코드 구현합니다.
# 코드를 입력해 주세요
X_ = 시각화
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.distplot(X, bins=5, color='b')
plt.title('Original', fontsize=16)
plt.subplot(1, 2, 2)
sns.distplot(X_, bins=5, color='r')
plt.title('Normalization', fontsize=16)
plt.show()MinMaxScaler의 활용
from sklearn.preprocessing import MinMaxScaler# 코드를 입력해 주세요
minmax_scaler =- feature 4개를 모두 변환합니다.
- 변환된 결과는
scaled_data2에 대입합니다.
# 코드를 입력해 주세요
scaled_data2 = scaled_data2[:5]# 코드검증
scaled_data2.min(), scaled_data2.max()[출력 결과]
(0.0, 1.0)
Scale 전, 후 비교 (시각화)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.scatterplot(df['sepal length (cm)'], df['sepal width (cm)'], hue=df['target'], palette='Set1')
plt.title('Sepal (Original)', fontsize=16)
plt.subplot(1, 2, 2)
sns.scatterplot(scaled_data2[:, 0], scaled_data2[:, 1], hue=df['target'], palette='Set1')
plt.title('Sepal (Scaled)', fontsize=16)
plt.show()plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.scatterplot(df['petal length (cm)'], df['petal width (cm)'], hue=df['target'], palette='Set1')
plt.title('Petal (Original)', fontsize=16)
plt.subplot(1, 2, 2)
sns.scatterplot(scaled_data2[:, 2], scaled_data2[:, 3], hue=df['target'], palette='Set1')
plt.title('Petal (Scaled)', fontsize=16)
plt.show()Label Encoder
머신러닝 알고리즘은 문자열 데이터를 입력으로 받지 못합니다.
따라서, 데이터가 가지고 있는 범주형(Categorical) 데이터는 반드시 숫자형(Numerical)으로 변환해주어야 합니다.
LabelEncoder는 범주형(Categorical) 데이터를 수치형으로 인코딩(encoding) 합니다.
여기서 인코딩(encoding) 이란, 문자형 -> 숫자형 데이터로 변환 해주는 것을 의미합니다.
샘플 데이터 (tips)
tips 데이터를 load 합니다.
tips = sns.load_dataset('tips')
tips.head()# day 컬럼의 분포 확인
tips['day'].value_counts()plt.figure(figsize=(10, 5))
sns.countplot(tips['day'])
plt.title('Data Counts', fontsize=16)
plt.show()만약 tips데이터의 day컬럼에서의 값(value)인 [Thur(목), Fri(금), Sat(토), Sun(일)] 을 인코딩(encoding) 해주지 않고 그대로 머신러닝 모델에 학습데이터로 feed한다면 error가 발생합니다.
apply를 활용한 인코딩(encoding)
아래와 같이 encoding이라는 함수를 정의한 후 변환하고자 하는 컬럼에 apply해줌으로써 인코딩을 진행합니다.
# 코드를 입력해 주세요
def converted(x):
converted변수에 변환된 결과를 대입합니다.- 대입한 후 결과에 대한 분포를 확인합니다.
# 코드를 입력해 주세요
converted =
converted.value_counts()[출력 결과]
2 87 3 76 0 62 1 19 Name: day, dtype: int64
인코딩 한 값을 간단히 시각화 해 볼 수 있습니다.
plt.figure(figsize=(10, 5))
sns.countplot(converted)
plt.title('(Encoded) Data Counts', fontsize=16)
plt.show()LabelEncoder 활용
위와 같이 apply로 변환하고자 하는 컬럼 별로 인코딩을 해줄 수 있지만, sklearn.preprocessing.LabelEncoder를 활용하여 쉽게 인코딩할 수 있습니다.
from sklearn.preprocessing import LabelEncoder# 코드를 입력해 주세요
encoder = # 코드를 입력해 주세요
encoded = encodedplt.figure(figsize=(10, 5))
sns.countplot(encoded, order=[3, 0, 1, 2])
plt.title('(Encoded) Data Counts', fontsize=16)
plt.show()LabelEncoder를 사용하면 원래 class 의 label도 확인할 수 있습니다.
encoder.classes_Inverse Transform(역변환)
머신러닝 학습을 위하여 어쩔 수 없이 범주형(Categorical) 데이터를 숫자형으로 변환하였다면, 이제 결과 확인을 위하여 다시 역변환이 필요합니다.
이는 LabelEncoder의 inverse_transform을 사용하여 쉽게 역변환할 수 있습니다.
inversed = encoder.inverse_transform(encoded)
inversedplt.figure(figsize=(10, 5))
sns.countplot(inversed, order=['Thur', 'Fri', 'Sat', 'Sun'])
plt.title('(Inversed) Data Counts', fontsize=16)
plt.show()