Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

project:eve

23.01.24 Classification 분류분석 본문

Daily

23.01.24 Classification 분류분석

eveee 2023. 1. 24. 11:59

오늘은 저번에 못다한 분류분석을 이어서 하려고 한다.

 

sklearn dataset 중 붓꽃 데이터를 가지고 간단한 분류분석을 해보기로 했다. 

 

분석 모델은 의사결정나무를 사용!

 


 

 

1) 데이터 가져오기


from sklearn.datasets import load_iris

iris = load_iris()
df_iris = pd.DataFrame(iris.data, columns=iris.feature_names)
df_iris['result'] = iris.target

여기까지는 이제 뚝딱이다.

 

 

가장 간단하게 하려면 여기에서 훈련/검증 데이터 나눠서 fit-predict하면 되는데, 책에서는 데이터 수가 적기 때문에 교차검증 과정을 거쳐야 한다고 한다. 

 

 

 

2) 교차검증 정의하기


교차검증이란 전체 데이터를 n개로 나누고, 이 데이터 중 각각 1개씩 돌아가며 검증 데이터가 되고 나머지는 훈련 데이터가 되어 총 n번 예측 테스트를 거치는 것이다. 그러면 각 테스트의 정확도가 나오는데 이 값이 높으면 높을수록 좋은 모델이다.

from sklearn.model_selection import KFold

kf = KFold(n_splits=6, shuffle=True, random_state=156)

교차검증을 위한 데이터 분할 함수로 KFold가 있다. train_test_split과 달리 데이터를 총 n개로 나눌 수 있고, 분할 작업을 도와주는 속성들도 많다. shuffle은 분할하기 전에 데이터를 섞을 건지 여부.

 

 

3) 분석모델 정의하기


의사결정나무 불러놓기. 아직 튜닝을 배우기 전이라서 수동으로 속성을 3개만 정의해 봤다.

from sklearn.tree import DecisionTreeClassifier

Dt_1 = DecisionTreeClassifier(max_depth=1, random_state=100)
Dt_3 = DecisionTreeClassifier(max_depth=3, random_state=100)
Dt_5 = DecisionTreeClassifier(max_depth=5, random_state=100)

 

4) 분석하기(1)


kfold와 의사결정나무를 이용해 분석하는 방법 첫번째는 일일이 n번 데이터를 쪼개서 함수에 넣고 정확도를 구하는 것이다. 

split() 함수를 쓰면 인수 데이터에서 훈련용 데이터와 테스트 데이터의 index를 나눠준다. 이 index를 가지고 역으로 독립, 종속 데이터에서 구분해주어야 하기 때문에 처음부터 데이터를 np.array 형식으로 저장해 두면 훨씬 편하게 분석할 수 있다.

from sklearn.metrics import accuracy_score # 정확도 측정 함수

X = df_iris.drop(columns=['result']).values
Y = df_iris['result'].values

acc = []

for train_index, test_index in kf.split(X):
    
    train_x, test_x = X[train_index], X[test_index]
    train_y, test_y = Y[train_index], Y[test_index]
    
    dt_1 = DecisionTreeClassifier(max_depth=1, random_state=100)
    
    dt_1.fit(train_x, train_y)
    pred = dt_1.predict(test_x)
    
    acc.append(accuracy_score(test_y, pred))
    
print(np.mean(acc)) # 0.62 출력

 

두번째는 이런 코드 노가다를 안할 수 있는 좋은 함수를 쓰는 것이다.

cross_val_score 함수에 사용할 데이터와 분석모델, 회차(cv)를 넣으면 회차만큼 정확도를 구해준다.

from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split

X = df_iris.drop(columns=['result'])
Y = df_iris['result']

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=0, stratify=Y)




scores_5 = cross_val_score(Dt_5, x_train, y_train, scoring='accuracy', cv=kf)

print('교차검증 정확도 : ', scores_5)
print('평균 정확도 : ', np.mean(scores_5))

scores_3 = cross_val_score(Dt_3, x_train, y_train, scoring='accuracy', cv=kf)

print('교차검증 정확도 : ', scores_3)
print('평균 정확도 : ', np.mean(scores_3))

scores_1 = cross_val_score(Dt_1, x_train, y_train, scoring='accuracy', cv=kf)

print('교차검증 정확도 : ', scores_1)
print('평균 정확도 : ', np.mean(scores_1))

첫번째 방법으로 한 것과 정확도는 비슷한 것 같다(Dt_1 참고). 정확도를 보니 max_depth가 3인 모델을 쓰면 될 것 같다.

그리고 첫번째 방법과 달리 전체 데이터에 train_test_split으로 훈련/ 검증 데이터를 나눠놓고 훈련 데이터로만 교차검증을 시행했다. 회귀분석 때 설명했던 것처럼 검증 데이터는 완전히 새로운 데이터여야 하기 때문!

(근데 다시 생각해보니 교차검증 때는 어차피 정확도만 추출하는 거고 정확도 가장 높은 모델로 다시 적합, 예측할 건데 굳이 그 전부터 나눠야 하나 싶기도 하다. 이건 두가지 경우를 모두 구해서 비교해봐야 알 것 같다??)

 

그래서 바로 비교해보기로 했다🤓

scores_5 = cross_val_score(Dt_5, X, Y, scoring='accuracy', cv=kf)

print('교차검증 정확도 : ', scores_5)
print('평균 정확도 : ', np.mean(scores_5))

scores_3 = cross_val_score(Dt_3, X, Y, scoring='accuracy', cv=kf)

print('교차검증 정확도 : ', scores_3)
print('평균 정확도 : ', np.mean(scores_3))

scores_1 = cross_val_score(Dt_1, X, Y, scoring='accuracy', cv=kf)

print('교차검증 정확도 : ', scores_1)
print('평균 정확도 : ', np.mean(scores_1))

위의 정확도와 비교해 보면 max_depth 1, 3인 값은 비슷한데 5인 모델은 조금 차이가 있다. 이렇게 보니까 전체 데이터를 교차검증 하는게 더 좋은 것 같기도 하다.

 

 

어쨌든, max_depth 5 모델이 제일 성능이 좋으니 그것으로 적합한 뒤 예측을 해보겠다.

Dt_5.fit(x_train, y_train)
y_pred = Dt_5.predict(x_test)

from sklearn.metrics import accuracy_score

acc = round(accuracy_score(y_test, y_pred), 3)
print(acc) # 0.967

정확도는 96.7%로 엄청 좋은 모델인 것을 알 수 있다.