머신러닝_11일차

임성진·2024년 1월 21일
0

ML/DL

목록 보기
11/18
post-thumbnail

11일차

  • 오늘은 Decision Tree(결정 트리)에 대해서 알아보도록 하겠다

Decision Tree(의사결정 트리)

  • 앞서 배웠듯이 머신러닝에는 지도학습과 비지도 학습이 존재
  • 그 중, 지도 학습은 훈련 데이터와 정답이 모두 포함된 경우
  • 이러한 지도 학습은 크게 두 가지로 나뉜다
    • 분류(Classification)
      • 전형적인 지도학습의 형태로, 예측하고자 하는 종속변수가 범주형일 때, class를 예측하는 것
    • 회귀(Regression)
      - 특성(feature)를 활용해서 연속형 종속변수를 예측하여 해당 class에 속할 확률을 수치화 해서 표현하는 것
  • 결정 트리는 위 두 가지의 경우 중 분류(classification)에 좀 더 적합!
  • 사람의 의사결정 방식 및 판단 기법과 매우 유사
  • 장점
    • 속도가 빠르고 간단
    • 데이터에 따라 상대적으로 다른 model에 비해서 성능이 좋음
  • 단점
    • 독립변수가 이산데이터인 경우에는 적합하지 않다!
    • class의 수가 많은 경우, 사용하기 어려움
    • 데이터의 수가 적은 경우에도 좋지 않다

Decision Tree 생성 예시

  • 위와 같은 형태로 decison tree를 구성하려고 할 때,
  • 어떤 기준(feature)을 가지고 Tree를 만들어야 하는지가 중요!
    • 잘 만들면 학습과 예측이 달라지기 때문
  • decision tree의 경우, tree를 분기해 나가는(만들어가는) 과정이
    학습 과정이다!!
  • 그럼 그 기준은??
    • 순도(homogeneity)가 높고,
    • 불순도(impurity) 혹은 불확실성(entropy)가 낮은 방향으로 분기!!
      -> 즉 순도가 증가하고 불순도(불확실성)가 감소하는 방향

정보 획득과 엔트로피

  • 정보 획득은 분기 이전의 불순도와 분기 이후의 불순도의 차이를 의미
  • 이를 수치화 시킨 것이 정보 획득량이다
  • 정보획득량을 계산하기 위한 정보 함수는 위와 같으며,
  • 무조건 일어날 일(확률이 1)일 수록 0에 수렴하고 거의 일어나지 않을 일(확률이 0)일 수록 무한대로 수렴한다!
    ex) 아침에 해가 동쪽에서 뜨는 경우 -> 확률 1
    아침에 해가 북쪽에서 뜨는 경우 -> 확률 0
  • Entropy(불확실성)
    • 무질서 정도를 정량화 한 값으로 이 값이 높다는 것은 무질서도가 높은,
    • 즉, 특징을 찾기 힘들다는 것을 의미한다.
    • 엔트로피 함수는 다음과 같다
  • A에서 B로 전이할 때,
    • 불확실한 상황(entropy가 높다) -> 정보량이 많다
    • 불확실하지 않은 상황(entropy가 낮다) -> 정보량이 작다!

Decision Tree 정리

  • 상태의 전이
    • 순도가 증가하는 방향으로 진행
    • entropy가 최대한 감소하는 방향으로 진행
  • 하나의 영역에 대해서
    • 동일한 범주의 data만 존재하는 경우
      -> 불확실성 0
    • 두 범주의 데이터가 반반씩 존재하는 경우
      -> 불확실성 1

KNN(K-Nearest Neighbors)

  • 지도학습의 알고리즘 중 하나
  • 말 그대로, 비슷한 특성이나 속성을 가진 값들끼리 모여있는 것을 의미
  • 데이터에 대해, 거리가 가까운 K개의 다른 데이터들의 레이블을 파악해
  • 빈도수가 가장 높게 나온 데이터의 레이블로 분류하는 것
  • 반드시 정규화를 진행해야 한다는 특징이 있다.
  • 아래 그림은 검은색 점을 KNN을 이용해 분류하는 예시이다
  • 일반적으로 k = 1인 경우, 수학적으로 어느정도 성능이 보장됨을 의미

유클리디안 거리

  • KNN 알고리즘에서의 거리계산 방법

주의점

  • 구현 시, 변수의 범위값을 재조정해야 한다!
    • why?
      • 거리 측정 시, 숫자를 사용하므로 변수 값의 범위를 재조정해줘야 변수의 중요도를 고르게 해석할 수 있기 때문!
  • 그럼 어떻게 재조정해요?
    -> 정규화 사용하면 된다

코드 구현

  • Decision Tree
# result_ori -> 엔트로피 구하는 공식
# np.log2() -> 주어진 값의 이진 로그를 계산하여 반환
import numpy as np
result_ori = -(10/16 * np.log2(10/16)) - (6/16*np.log2(6/16))
result_ori
# R1 영역
r1 = (8/16) * -((7/8)*np.log2(7/8) + (1/8)*np.log2(1/8))

# R2 영역
r2 = (8/16) * -((5/8)*np.log2(5/8) + (3/8)*np.log2(3/8))

result = r1 + r2
result
# 따라서 정보 획득량은!
# 전체 entropy - 분기 후 entropy
result_ori - result
  • 아래 그림에 대한 코드
# root node를 wind로 분류해서 entropy 계산
# weak -> [yes 6, no 2]
# strong -> [yes 3, no 3]

result_wind_weak = (8/14) * -((6/8)*np.log2(6/8) + (2/8)*np.log2(2/8))

result_wind_strong = (6/14) * -((3/6)*np.log2(3/6) + (3/6)*np.log2(3/6))

result_wind = result_wind_weak + result_wind_strong
result_wind
# sunny -> [yes 2 no 3]
# overcast -> [yes 4 no 0]
# rain -> [yes 3 no 2]
result_outlook_sunny = 5/14 * (-2/5 * np.log2(2/5) - 3/5 * np.log2(3/5))
result_outlook_overcast = 4/14 * (-4/4 * np.log2(4/4))
result_outlook_rain = 5/14 * (-3/5 * np.log2(3/5) - 2/5 * np.log2(2/5))

result_outlook = result_outlook_sunny + result_outlook_overcast + result_outlook_rain
result_outlook
# humidity
# high -> [yes 3 no 4]
# normal -> [yes 6 no 1]
result_humidity_high = 7/14 * (-3/7 * np.log2(3/7) - 4/7 * np.log2(4/7))
result_humidity_normal = 7/14 * (-6/7 *np.log2(6/7) - 1/7 * np.log2(1/7))
result_humidity = result_humidity_high + result_humidity_normal
result_humidity
# 전체 데이터를 wind로 분류했을때 우리가 얻을 수 있는 정보량
print(result - result_wind)

# 전체 데이터를 outlook으로 분류했을때 우리가 얻을 수 있는 정보량
print(result - result_outlook)

# 전체 데이터를 humidity로 분류했을때 우리가 얻을 수 있는 정보량
print(result - result_humidity)
  • iris(붓꽃) 데이터를 활용한 decison tree
# 위와 같은 Decision Tree를 사용하려면 어떻게 해야하나요?
# sklearn을 이용해서 사용하면 되요!

# iris 예제를 이용하여 Decision Tree를 구현해 보아요
# feature는 2개만 사용할 거에요!(꽃받침의 길이, 꽃잎의 길이)

# 필요 module import
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.datasets import load_iris
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from mlxtend.plotting import plot_decision_regions
from sklearn.tree import DecisionTreeClassifier
# Raw Data Loading
iris = load_iris()

df = pd.DataFrame(iris.data,
                  columns=iris.feature_names)
df.columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
df['target'] = iris.target

# 중복 데이터 정리
df = df.drop_duplicates()

# 데이터셋 준비
x_data = df.drop(['sepal_width', 'petal_width','target'],axis=1,inplace=False).values
t_data = df['target'].values

# 정규화
scaler = MinMaxScaler()
scaler.fit(x_data)
x_data_norm = scaler.transform(x_data)

# 데이터 분리
x_data_train_norm, x_data_test_norm, t_data_train, t_data_test = \
train_test_split(x_data_norm,
                 t_data,
                 stratify=t_data,
                 test_size=0.3)
# 모델 생성
model = DecisionTreeClassifier()

model.fit(x_data_train_norm,
          t_data_train)

# Evaiuation
score = accuracy_score(t_data_test, model.predict(x_data_test_norm))

# 시각화
plot_decision_regions(X=x_data_train_norm,
                      y=t_data_train,
                      clf=model)
plt.show()
score

  • MNIST 데이터를 활용한 다중분류작업
    • 데이터 전처리
# 필요 module import
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.optimizers import Adam

from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier

df = pd.read_csv('/content/drive/MyDrive/AI스쿨 파일/ML/MNIST/train.csv')
df

# 데이터셋 분리
x_data = df.drop('label',axis=1,inplace=False).values
t_data = df['label'].values

# 정규화
scaler = MinMaxScaler()
scaler.fit(x_data)
x_data_norm = scaler.transform(x_data)

# 데이터 분리
x_data_train_norm, x_data_test_norm, t_data_train, t_data_test = \
train_test_split(x_data_norm,
                 t_data,
                 stratify=t_data,
                 test_size=0.3,
                 random_state=0)
  • tensorflow ver.
# tensorflow 구현
keras_model = Sequential()

keras_model.add(Flatten(input_shape=(784,)))
keras_model.add(Dense(units=10,
                      activation='softmax'))

keras_model.compile(optimizer=Adam(learning_rate=1e-2),
                    loss='sparse_categorical_crossentropy',
                    metrics=['acc'])

keras_model.fit(x_data_train_norm,
                t_data_train,
                epochs=100,
                batch_size=100,
                verbose=1,
                validation_split=0.3)

keras_model.evaluate(x_data_test_norm,
                     t_data_test)

  • sklearn ver.
# sklearn 구현
sklearn_model = LogisticRegression()

sklearn_model.fit(x_data_train_norm,
                  t_data_train)
accuracy_score(t_data_test,
               sklearn_model.predict(x_data_test_norm))

  • svc ver.
svm_model = SVC()
svm_model.fit(x_data_train_norm,
              t_data_train)
accuracy_score(t_data_test,svm_model.predict(x_data_test_norm))

  • decision tree ver.
# Decision Tree 구현
model = DecisionTreeClassifier()

model.fit(x_data_train_norm,
          t_data_train)

accuracy_score(t_data_test, model.predict(x_data_test_norm))

  • knn ver.
# KNN 이용한 구현
from sklearn.neighbors import KNeighborsClassifier
knn_model = KNeighborsClassifier(n_neighbors=5)

knn_model.fit(x_data_train_norm,
              t_data_train)

accuracy_score(t_data_test, knn_model.predict(x_data_test_norm))

0개의 댓글