머신러닝

머신 러닝(with Google Colab) - 5일차(1)

aisw7984 2024. 10. 17. 17:50
반응형

어떻게 하면 여러 개의 데이터가 섞여있는데서 종류별로 분류를 하는 프로그램을 만들 수 있을까?   

앞서 배운 내용중 로지스틱 회귀를 통해 와인의 분류를 해보자

 


우선 데이터를 세팅해보자

import pandas as pd
wine = pd.read_csv('https://bit.ly/wine_csv_data')

# print(wine.head()) : 5개의 샘플 확인
# print(wine.info()) :데이터의 정보 종합
# print(wine.describe()) # 데이터의 기초 통계 정보를 알려줌
wine_data = wine[["alcohol","sugar","pH"]].to_numpy()
wine_target = wine["class"].to_numpy()

from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = \
train_test_split(wine_data, wine_target, test_size=0.2, random_state=42)

 위의 코드를 보면 데이터의 정보를 보는 3가지 방법이 있는데 3가지 해당 코드를 통해 데이터를 어떻게 접근해야 하는지를 미리 예측해 볼 수 있다. 한번  print(wine.describe())을 확인해 보자

           alcohol        sugar           pH        class
count  6497.000000  6497.000000  6497.000000  6497.000000
mean     10.491801     5.443235     3.218501     0.753886
std       1.192712     4.757804     0.160787     0.430779
min       8.000000     0.600000     2.720000     0.000000
25%       9.500000     1.800000     3.110000     1.000000
50%      10.300000     3.000000     3.210000     1.000000
75%      11.300000     8.100000     3.320000     1.000000
max      14.900000    65.800000     4.010000     1.000000

내용을 보면 각 특성별로 class를 결정하는 정도를 대강 확인할 수 있다.

이제 훈련세트와 데이터 세트의 크기를 확인해 보자

print(train_input.shape, test_input.shape)
=> (5197, 3) (1300, 3)

코드가 비율에 맞게 나누어진 것을 볼 수 있고 특성이 3개(["alcohol", "sugar", "pH"]) 인 것을 알 수 있다.

스케일을 맞춰주고 로지스틱 회귀를 통해 훈련하고 정확도를 확인해 보자

#데이터 전처리
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)

#로지스틱 회귀 모델
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))
=> 0.7808350971714451
   0.7776923076923077

생각보다 정확도가 낮은 것을 확인할 수 있다. 정확도는 앞서했던 데로 C와 max_iter을 조절하면 결과가 좋아질 수 있다. 그러나 로지스틱 회귀는 프로그램적으로는 문제가 없지만 사람들에게 설명하기는 좀 어려운 느낌이 있다. 따라서 순서도 처럼 조건에 따라 결과가 나뉘는 것을 확인할 수 있는 방법으로 결정 트리를 사용한다.


결정 트리

결정 트리의 기본적인 과정은 분류 기준에 따라 Ture False로 나누어서 가지를 뻗고 그 과정을 이어서 나간다.

트리 모델에서 분류기준은 자동으로 정해주기 때문에 따로 설정해 줄 필요가 없다.

트리 모델은 sklearn.tree 패키지 안에 있는 DecisionTreeClassifier 클래스에 포함되어 있다. 

from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))
=> 0.996921300750433
   0.8592307692307692
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(10,7))
plot_tree(dt)
plt.show()

코드를 보면 트리모델의 정확도가 훈련세트에 대해 과하게 높은 과대 적합모델임을 볼 수 있다. 이는 그림으로도 확인이 가능한데 따로 규제를 하지 않은 트리모델은 동작이 상당히 오래 걸린다.

한눈에 봐도 엄청 복잡한 그림이 나왔는데 이렇게 많은 과정을 거쳤기 때문에 과대 적합이 일어났다고 볼 수 있다. 트리모델에서 정보를 담고 있는 박스를 노드 노드에서 분류되는 선을 가지 라고 한다.

규제를 하기 전에 트리 모델의 일부를 추출해서 보자.

트리모델은 plot_tree() 함수를 통해 트리의 깊이를 제한할 수 있다. 깊이는 함수의 max_depth 매개변수를 조절하면 된다. 추가로 filled 매개변수는 트리 노드의 색칠을 해준다. feature_names 매개변수는 테스트에 사용된 특성의 이름을 적어주는 것이다.

plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=2, filled=True, feature_names=['alcohol','sugar','pH'])
plt.show()

위의 노드를 읽는 방법은 아래와 같다

  1. 테스트 조건(sugar < 범위)
  2. gini : 불순도
  3. samples : 총 샘플수
  4. value : 클래스별 샘플수

여기서 불순도는 순수하지 않은 정도 즉 섞여있는 정도에 따라 수치가 달라짐 반반일때가 가장 불순하고 한쪽의 데이터만 있으면 순수하다.

불순도에 관한 내용을 다음에 이어서 설명하겠다.

반응형