머신러닝
교차검증
긔
2020. 7. 28. 11:11
데이터를 검증하는 방법
-
모델의 타당성을 검증하는 크로스 밸리데이션
교차 검증 - Cross-validation
-
모델의 타당성을 검증하는 방법 중 하나
-
특정 데이터를 훈련 전용데이터와 테스트 전용 데이터로 분할
-
훈련데이터로 학습하고 테스트 데이터로 학습의 타당성 검증하는 방법
K 분할 교차 검증 : K-fold cross validation
3-fold cross validation
-
집합 X 를 3개로 분할 : A, B, C
-
A:테스트, (B,C):훈련 => 정밀도 s1
-
B:테스트, (A,C):훈련 => 정밀도 s2
-
C:테스트, (A,B):훈련 => 정밀도 s3
-
s1, s2, s3의 평균을 구해 최종적인 분류 정밀도 구하기
붓꽃 데이터 데이터 검증해보기
scikit-learn 이용
-
model_selection.cross_val_score() 사용
import pandas as pd
from sklearn import svm, metrics, model_selection
import random, re
# 붓꽃의 CSV 데이터 읽어 들이기 --- (1)
csv = pd.read_csv('pyml_rev_examples/ch4/iris.csv')
csv.head()
SepalLength | SepalWidth | PetalLength | PetalWidth | Name | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
# 리스트를 훈련 전용 데이터와 테스트 전용 데이터로 분할하기 --- (2)
data = csv[["SepalLength","SepalWidth","PetalLength","PetalWidth"]]
label = csv["Name"]
# 크로스 밸리데이션 하기 --- (3)
clf = svm.SVC()
# cv : 몇개로 분할 할지
scores = model_selection.cross_val_score(clf, data, label, cv=5)
# cv번의 정답률 평균이므로 더욱 신뢰성 있는 값 도출 가능
print("각각의 정답률 =", scores)
print("평균 정답률 =", scores.mean())
각각의 정답률 = [0.96666667 0.96666667 0.96666667 0.93333333 1. ]
평균 정답률 = 0.9666666666666666
type(scores)
numpy.ndarray
참고 - 파이썬으로 구현
from sklearn import svm, metrics
import random, re
# 붓꽃의 CSV 파일 읽어 들이기 --- (※1)
lines = open('iris.csv', 'r', encoding='utf-8').read().split("\n")
f_tonum = lambda n : float(n) if re.match(r'^[0-9\.]+$', n) else n
f_cols = lambda li: list(map(f_tonum,li.strip().split(',')))
csv = list(map(f_cols, lines))
del csv[0] # 헤더 제거하기
random.shuffle(csv) # 데이터 섞기
# 데이터를 K개로 분할하기 --- (※2)
K = 5
csvk = [ [] for i in range(K) ]
for i in range(len(csv)):
csvk[i % K].append(csv[i])
# 리스트를 훈련 전용 데이터와 테스트 전용 데이터로 분할하는 함수
def split_data_label(rows):
data = []; label = []
for row in rows:
data.append(row[0:4])
label.append(row[4])
return (data, label)
# 정답률 구하기 --- (※3)
def calc_score(test, train):
test_f, test_l = split_data_label(test)
train_f, train_l = split_data_label(train)
# 학습시키고 정답률 구하기
clf = svm.SVC()
clf.fit(train_f, train_l)
pre = clf.predict(test_f)
return metrics.accuracy_score(test_l, pre)
# K개로 분할해서 정답률 구하기 --- (※4)
score_list = []
for testc in csvk:
# testc 이외의 데이터를 훈련 전용 데이터로 사용하기
trainc = []
for i in csvk:
if i != testc: trainc += i
sc = calc_score(testc, trainc)
score_list.append(sc)
print("각각의 정답률 =", score_list)
print("평균 정답률 =", sum(score_list) / len(score_list))
그리드 서치
-
scikit-learn의 학습기 알고리즘은 여러 가지 선택 가능
-
각 알고리즘은 여러 개의 매개변수를 지정 가능
-
적절한 매개변수를 지정하면 정밀도가 높아짐
-
매개변수 튜닝이 굉장히 중요한 작업
-
매개변수 자동으로 조사 -> 그리드 서치
-
GridSerachCV() 제공
import pandas as pd
from sklearn import model_selection, svm, metrics
#from sklearn.grid_search import GridSearchCV => error
from sklearn.model_selection import GridSearchCV
# MNIST 학습 데이터 읽어 들이기 --- (1)
train_csv = pd.read_csv('./mnist/train.csv')
test_csv = pd.read_csv('./mnist/t10k.csv')
# 필요한 열 추출하기 --- (2)
train_label = train_csv.iloc[:, 0]
train_data = train_csv.iloc[:, 1:577]
test_label = test_csv.iloc[:, 0]
test_data = test_csv.iloc[:, 1:577]
print("학습 데이터의 수 =", len(train_label))
학습 데이터의 수 = 1000
# 그리드 서치 매개변수 후보 설정 --- (3)
# 매개변수 참고 : https://wikidocs.net/26271
params = [
{"C": [1,10,100,1000], "kernel":["linear"]},
{"C": [1,10,100,1000], "kernel":["rbf"], "gamma":[0.001, 0.0001]}
]
# # 그리드 서치 수행 --- (※4)
# n_jobs=-1 병렬 계산할 프로세스 수 지정, -1 자동으로 코어수에 맞게 처리
# 시간이 꽤 걸림
clf = GridSearchCV(svm.SVC(), params, n_jobs=-1)
clf.fit(train_data, train_label)
print("학습기 =", clf.best_estimator_)
학습기 = SVC(C=1, kernel='linear')
# 테스트 데이터 확인하기 --- (5)
pre = clf.predict(test_data)
ac_score = metrics.accuracy_score(pre, test_label)
print("정답률 =",ac_score)
정답률 = 0.866
매개변수 참고 : https://wikidocs.net/26271