2016-08-02 2 views
3

나는 분류 작업을하고있다. 그럼에도 불구하고, 나는 점점 오전 약간 다른 결과 :scikit-learn에서 correclty 교차 유효성 검사 점수를 계산하는 방법은 무엇입니까?

#First Approach 
kf = KFold(n=len(y), n_folds=10, shuffle=True, random_state=False) 
pipe= make_pipeline(SVC()) 
for train_index, test_index in kf: 
    X_train, X_test = X[train_index], X[test_index] 
    y_train, y_test = y[train_index], y[test_index] 

print ('Precision',np.mean(cross_val_score(pipe, X_train, y_train, scoring='precision'))) 



#Second Approach 
clf.fit(X_train,y_train) 
y_pred = clf.predict(X_test) 
print ('Precision:', precision_score(y_test, y_pred,average='binary')) 

#Third approach 
pipe= make_pipeline(SCV()) 
print('Precision',np.mean(cross_val_score(pipe, X, y, cv=kf, scoring='precision'))) 

#Fourth approach 

pipe= make_pipeline(SVC()) 
print('Precision',np.mean(cross_val_score(pipe, X_train, y_train, cv=kf, scoring='precision'))) 

아웃 :

Precision: 0.780422106837 
Precision: 0.782051282051 
Precision: 0.801544091998 

/usr/local/lib/python3.5/site-packages/sklearn/cross_validation.py in cross_val_score(estimator, X, y, scoring, cv, n_jobs, verbose, fit_params, pre_dispatch) 
    1431            train, test, verbose, None, 
    1432            fit_params) 
-> 1433      for train, test in cv) 
    1434  return np.array(scores)[:, 0] 
    1435 

/usr/local/lib/python3.5/site-packages/sklearn/externals/joblib/parallel.py in __call__(self, iterable) 
    798    # was dispatched. In particular this covers the edge 
    799    # case of Parallel used with an exhausted iterator. 
--> 800    while self.dispatch_one_batch(iterator): 
    801     self._iterating = True 
    802    else: 

/usr/local/lib/python3.5/site-packages/sklearn/externals/joblib/parallel.py in dispatch_one_batch(self, iterator) 
    656     return False 
    657    else: 
--> 658     self._dispatch(tasks) 
    659     return True 
    660 

/usr/local/lib/python3.5/site-packages/sklearn/externals/joblib/parallel.py in _dispatch(self, batch) 
    564 
    565   if self._pool is None: 
--> 566    job = ImmediateComputeBatch(batch) 
    567    self._jobs.append(job) 
    568    self.n_dispatched_batches += 1 

/usr/local/lib/python3.5/site-packages/sklearn/externals/joblib/parallel.py in __init__(self, batch) 
    178   # Don't delay the application, to avoid keeping the input 
    179   # arguments in memory 
--> 180   self.results = batch() 
    181 
    182  def get(self): 

/usr/local/lib/python3.5/site-packages/sklearn/externals/joblib/parallel.py in __call__(self) 
    70 
    71  def __call__(self): 
---> 72   return [func(*args, **kwargs) for func, args, kwargs in self.items] 
    73 
    74  def __len__(self): 

/usr/local/lib/python3.5/site-packages/sklearn/externals/joblib/parallel.py in <listcomp>(.0) 
    70 
    71  def __call__(self): 
---> 72   return [func(*args, **kwargs) for func, args, kwargs in self.items] 
    73 
    74  def __len__(self): 

/usr/local/lib/python3.5/site-packages/sklearn/cross_validation.py in _fit_and_score(estimator, X, y, scorer, train, test, verbose, parameters, fit_params, return_train_score, return_parameters, error_score) 
    1522  start_time = time.time() 
    1523 
-> 1524  X_train, y_train = _safe_split(estimator, X, y, train) 
    1525  X_test, y_test = _safe_split(estimator, X, y, test, train) 
    1526 

/usr/local/lib/python3.5/site-packages/sklearn/cross_validation.py in _safe_split(estimator, X, y, indices, train_indices) 
    1589     X_subset = X[np.ix_(indices, train_indices)] 
    1590   else: 
-> 1591    X_subset = safe_indexing(X, indices) 
    1592 
    1593  if y is not None: 

/usr/local/lib/python3.5/site-packages/sklearn/utils/__init__.py in safe_indexing(X, indices) 
    161         indices.dtype.kind == 'i'): 
    162    # This is often substantially faster than X[indices] 
--> 163    return X.take(indices, axis=0) 
    164   else: 
    165    return X[indices] 

IndexError: index 900 is out of bounds for size 900 

그래서, 내 질문은 cross validated metrics을 계산하는 것이 올바른 것입니다 위의 접근 방식은 무엇입니까?. 크로스 밸리데이션을 수행 할 때가 혼란 스럽기 때문에 점수가 오염되었다고 생각합니다. 따라서, 올바르게 교차 검증 된 점수를 수행하는 방법에 대한 아이디어는 무엇입니까?

UPDATE

교육 단계에서 평가?

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = False) 
clf = make_pipeline(SVC()) 
# However, fot clf, you can use whatever estimator you like 
kf = StratifiedKFold(y = y_train, n_folds=10, shuffle=True, random_state=False) 
scores = cross_val_score(clf, X_train, y_train, cv = kf, scoring='precision') 
print('Mean score : ', np.mean(scores)) 
print('Score variance : ', np.var(scores)) 

답변

4

모든 분류 작업에는 항상 StratifiedKFold 교차 유효성 검사 분할을 사용하는 것이 좋습니다. 계층화 된 KFold에서는 분류 문제에 대해 각 클래스의 샘플 수가 동일합니다.

StratifiedKFold

는 그 다음 분류 문제의 당신의 유형에 따라 달라집니다. 항상 정밀도와 리콜 점수를 보는 것이 좋습니다. 설명 된 바와 같이

import numpy as np 
from sklearn.cross_validation import cross_val_score 
from sklearn.metrics import precision_score 
from sklearn.cross_validation import KFold 
from sklearn.pipeline import make_pipeline 
from sklearn.svm import SVC 

np.random.seed(1337) 

X = np.random.rand(1000,5) 

y = np.random.randint(0,2,1000) 

kf = KFold(n=len(y), n_folds=10, shuffle=True, random_state=42) 
pipe= make_pipeline(SVC(random_state=42)) 
for train_index, test_index in kf: 
    X_train, X_test = X[train_index], X[test_index] 
    y_train, y_test = y[train_index], y[test_index] 

print ('Precision',np.mean(cross_val_score(pipe, X_train, y_train, scoring='precision'))) 
# Here you are evaluating precision score on X_train. 

#Second Approach 
clf = SVC(random_state=42) 
clf.fit(X_train,y_train) 
y_pred = clf.predict(X_test) 
print ('Precision:', precision_score(y_test, y_pred, average='binary')) 

# here you are evaluating precision score on X_test 

#Third approach 
pipe= make_pipeline(SVC()) 
print('Precision',np.mean(cross_val_score(pipe, X, y, cv=kf, scoring='precision'))) 

# Here you are splitting the data again and evaluating mean on each fold 

는 따라서, 결과는,

+0

감사를 비교할 수있을 것으로

clf = make_pipeline(SVC()) # However, fot clf, you can use whatever estimator you like scores = cross_val_score(clf, X, y, cv = 10, scoring='precision') print('Mean score : ', np.mean(scores)) print('Score variance : ', np.var(scores)) 

은' cross_val_score', 왜 내가 다른 결과를 얻었는지, 그리고 그것들을 계산하는 올바른 방법은 무엇입니까? –

+1

랜덤 씨앗으로 인한 것일 수 있습니다. random_state 매개 변수를 설정하고 어떤 결과가 나타나는지보십시오. –

+0

네, 무작위로 시작하기 전에 다음과 같이했습니다 :'np.random.seed (1337)' –

3

먼저 다른 :

from sklearn import metrics 
metrics.roc_auc_score(ytest, ypred) 

이 솔루션 볼 수 있습니다 : 왜곡 된 이진 분류의 경우, 사람들은 ROC AUC 점수를 사용하는 경향이 documentation이고 일부는 examples으로 표시되며 scikit-learn 교차 유효성 검사 cross_val_score은 다음을 수행합니다.

  1. 데이터 집합 X을 N 폴드 내에서 분할하십시오 (매개 변수 cv에 따라). 이에 따라 레이블 y을 나눕니다.
  2. N-1 이전 폴드에 대해 견적기를 사용하여 견적기를 사용하십시오 (매개 변수 estimator).
  3. 추정량을 사용하여 마지막 폴드의 레이블을 예측합니다.
  4. 예측값과 실제 값을 비교하여 점수 (매개 변수 scoring)를 반환합니다.
  5. 테스트 폴드를 변경하여 2 단계부터 4 단계까지를 반복합니다. 따라서 N 개의 점수 배열로 끝납니다.

각 방법을 살펴 보겠습니다.

첫 번째 방법 :

당신을 위해 수행 기능을 scikit가 배울 당신이 훈련은 cross_validation 전에 설정 나누 것 왜

?따라서, 당신은 가치가 검증로 끝나는 적은 데이터 모델을 훈련

두 번째 방법 점수 : 여기

, 당신은 다른 메트릭 데이터에 cross_validation_sore보다를 사용합니다. 따라서 다른 유효성 검사 점수와 비교할 수 없습니다. 두 가지 다른 이유 때문입니다. 하나는 오류의 전형적인 백분율이지만 precision은 이진 분류 자 ​​(true 또는 false)를 보정하는 데 사용되는 메트릭입니다. 그러나 이는 좋은 측정 항목이지만 (ROC 곡선 및 정밀도 및 회수 측정 항목을 확인할 수 있음) 이러한 측정 항목 만 비교할 수 있습니다.

세 번째 방법 :

이 하나가 더 자연스러운 것입니다. 이 점수는 입니다.입니다 (다른 분류 기준/견적 도구와 비교하려는 경우). 그러나 나는 그 결과로 직접적으로 평균을 취하는 것을 경고합니다. 비교할 수있는 두 가지가 있기 때문에 : 평균뿐만 아니라 분산. 배열의 각 점수는 다른 다른 당신은

네 번째 접근 방식 (당신은 확실히 가능한 한 작게하여 분산을 원하는) 다른 추정량 비교, 얼마나로 알고 할 수 있습니다 :

이 보인다 마지막으로 cross_val_score

관련되지 않은 Kfold에 문제가 :

만 사용 두 번째 또는 견적을 비교하는 세 번째 방법. 그러나 정확도와 오류율의 차이를 정확히 예측하지는 않습니다. 또 다른 추정에 clf을 변경 (또는 루프에 통합)에 관해서는, 당신은 각 eastimator에 대한 점수를 가지고 그들에게 도움을

+0

도움을 주셔서 감사합니다, 제 3의 접근 방식에 관해서는 왜 내가 할 수 없는지 이해하지 못합니다 :'cross_val_score (pipe, X_train, y_train, cv = kf, scoring = 'precision')', 나는 예외를 얻습니다 : 'IndexError : 인덱스 900이 크기 900을 벗어납니다 .' 왜 이런 일이 일어나고 있습니까? –

+2

kf가 풀 세트 (예 : len (y))이고 X_train, y_train을 사용하고 있습니다. –

+1

네, 절대적으로 :) 당신이하려고하는 것은'cv = 10' ('cv = kf' 대신에)이라고 생각합니다. –

관련 문제