저는 sci-kit에서 MLPClassifier 모델을 배우고 있습니다. 모델을 채점하기 위해 roc_auc과 함께 gridSearchCV를 사용했습니다. 평균 열차와 시험 점수는 약 0.76이며 나쁘지 않습니다. cv_results_
의 출력은 다음과 같습니다AUC는 어떻게 GridSearchCV AUC와 다를 수 있습니까?
Train set AUC: 0.553465272412
Grid best score (AUC): 0.757236688092
Grid best parameter (max. AUC): {'hidden_layer_sizes': 10}
{ 'mean_fit_time': array([63.54, 136.37, 136.32, 119.23, 121.38, 124.03]),
'mean_score_time': array([ 0.04, 0.04, 0.04, 0.05, 0.05, 0.06]),
'mean_test_score': array([ 0.76, 0.74, 0.75, 0.76, 0.76, 0.76]),
'mean_train_score': array([ 0.76, 0.76, 0.76, 0.77, 0.77, 0.77]),
'param_hidden_layer_sizes': masked_array(data = [5 (5, 5) (5, 10) 10 (10, 5) (10, 10)],
mask = [False False False False False False],
fill_value = ?)
,
'params': [ {'hidden_layer_sizes': 5},
{'hidden_layer_sizes': (5, 5)},
{'hidden_layer_sizes': (5, 10)},
{'hidden_layer_sizes': 10},
{'hidden_layer_sizes': (10, 5)},
{'hidden_layer_sizes': (10, 10)}],
'rank_test_score': array([ 2, 6, 5, 1, 4, 3]),
'split0_test_score': array([ 0.76, 0.75, 0.75, 0.76, 0.76, 0.76]),
'split0_train_score': array([ 0.76, 0.75, 0.75, 0.76, 0.76, 0.76]),
'split1_test_score': array([ 0.77, 0.76, 0.76, 0.77, 0.76, 0.76]),
'split1_train_score': array([ 0.76, 0.75, 0.75, 0.76, 0.76, 0.76]),
'split2_test_score': array([ 0.74, 0.72, 0.73, 0.74, 0.74, 0.75]),
'split2_train_score': array([ 0.77, 0.77, 0.77, 0.77, 0.77, 0.77]),
'std_fit_time': array([47.59, 1.29, 1.86, 3.43, 2.49, 9.22]),
'std_score_time': array([ 0.01, 0.01, 0.01, 0.00, 0.00, 0.01]),
'std_test_score': array([ 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]),
'std_train_score': array([ 0.01, 0.01, 0.01, 0.01, 0.01, 0.00])}
당신은 평균 열차 점수로보고있는 동안 내가 흥미롭게도 수동으로 계산 된 기차 세트의 roc_auc_score이 0.55으로보고 3의 KFold 사용 볼 수 있듯이 ~ 0.76. 이 출력을 생성하는 코드는 다음과 같습니다
def model_mlp (X_train, y_train, verbose=True, random_state = 42):
grid_values = {'hidden_layer_sizes': [(5), (5,5), (5, 10),
(10), (10, 5), (10, 10)]}
# MLP requires scaling of all predictors
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
mlp = MLPClassifier(solver='adam', learning_rate_init=1e-4,
max_iter=200,
verbose=False,
random_state=random_state)
# perform the grid search
grid_auc = GridSearchCV(mlp,
param_grid=grid_values,
scoring='roc_auc',
verbose=2, n_jobs=-1)
grid_auc.fit(X_train, y_train)
y_hat = grid_auc.predict(X_train)
# print out the results
if verbose:
print('Train set AUC: ', roc_auc_score(y_train, y_hat))
print('Grid best score (AUC): ', grid_auc.best_score_)
print('Grid best parameter (max. AUC): ', grid_auc.best_params_)
print('')
pp = pprint.PrettyPrinter(indent=4)
pp.pprint (grid_auc.cv_results_)
print ('MLPClassifier fitted, {:.2f} seconds used'.format (time.time() - t))
return grid_auc.best_estimator_
이 차이 나는 다음과 같은 결과에 '에뮬레이트'는 GridSearchCV
루틴을 결정하고 가지고 있기 때문에 :
Shape X_train: (107119, 15)
Shape y_train: (107119,)
Shape X_val: (52761, 15)
Shape y_val: (52761,)
layers roc-auc
Seq l1 l2 train test iters runtime
1 5 0 0.5522 0.5488 85 20.54
2 5 5 0.5542 0.5513 80 27.10
3 5 10 0.5544 0.5521 83 28.56
4 10 0 0.5532 0.5516 61 15.24
5 10 5 0.5540 0.5518 54 19.86
6 10 10 0.5507 0.5474 56 21.09
점수는 모든 주위 0.55과 일치를 위의 코드에서 수동 계산. 저를 놀라게 한 것은 결과에 변화가 없다는 것입니다. 내가 어떤 실수를하고 것처럼 나타납니다,하지만 난 하나를 찾을 코드를 볼 수 없습니다 :
def simple_mlp (X, y, verbose=True, random_state = 42):
def do_mlp (X_t, X_v, y_t, y_v, n, l1, l2=None):
if l2 is None:
layers = (l1)
l2 = 0
else:
layers = (l1, l2)
t = time.time()
mlp = MLPClassifier(solver='adam', learning_rate_init=1e-4,
hidden_layer_sizes=layers,
max_iter=200,
verbose=False,
random_state=random_state)
mlp.fit(X_t, y_t)
y_hat_train = mlp.predict(X_t)
y_hat_val = mlp.predict(X_v)
if verbose:
av = 'samples'
acc_trn = roc_auc_score(y_train, y_hat_train, average=av)
acc_tst = roc_auc_score(y_val, y_hat_val, average=av)
print ("{:5d}{:4d}{:4d}{:7.4f}{:7.4f}{:9d}{:8.2f}"
.format(n, l1, l2, acc_trn, acc_tst, mlp.n_iter_, time.time() - t))
return mlp, n + 1
X_train, X_val, y_train, y_val = train_test_split (X, y, test_size=0.33, random_state=random_state)
if verbose:
print('Shape X_train:', X_train.shape)
print('Shape y_train:', y_train.shape)
print('Shape X_val:', X_val.shape)
print('Shape y_val:', y_val.shape)
# MLP requires scaling of all predictors
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_val = scaler.transform(X_val)
n = 1
layers1 = [5, 10]
layers2 = [5, 10]
if verbose:
print (" layers roc-auc")
print (" Seq l1 l2 train validation iters runtime")
for l1 in layers1:
mlp, n = do_mlp (X_train, X_val, y_train, y_val, n, l1)
for l2 in layers2:
mlp, n = do_mlp (X_train, X_val, y_train, y_val, n, l1, l2)
return mlp
내가 정확히 두 경우 모두 동일한 데이터 (159880 명 관찰과 15 예측)를 사용합니다. 나는 GridSearchCV
에 cv=3
(기본값)을 사용하고 수작업으로 만들어진 코드의 유효성 검사 설정에 동일한 비율을 사용합니다. 가능한 답을 찾을 때 같은 문제를 설명하는 this post on SO을 발견했습니다. 대답이 없었습니다. 어쩌면 누군가 정확히 무슨 일이 일어 났는지 이해할 수 있을까요?
감사합니다. 편집
나는 @Mohammed 제작 : Kashif가 제안 GridSearchCV 및 KFold의 코드를 확인하고 실제로 KFold 데이터를 셔플하지 않았다 명시 적 발언을 발견했다. 그래서 스케일러 전에 model_mlp하기 위해 다음과 같은 코드를 추가
np.random.seed (random_state) index = np.random.permutation (len(X_train)) X_train = X_train.iloc[index]
및 train_test_split의 교체로 simple_mlp에
: 다음과 같은 출력 결과np.random.seed (random_state)
index = np.random.permutation (len(X))
X = X.iloc[index]
y = y.iloc[index]
train_size = int (2 * len(X)/3.0) # sample of 2 third
X_train = X[:train_size]
X_val = X[train_size:]
y_train = y[:train_size]
y_val = y[train_size:]
:
Train set AUC: 0.5
Grid best score (AUC): 0.501410198106
Grid best parameter (max. AUC): {'hidden_layer_sizes': (5, 10)}
{ 'mean_fit_time': array([28.62, 46.00, 54.44, 46.74, 55.25, 53.33]),
'mean_score_time': array([ 0.04, 0.05, 0.05, 0.05, 0.05, 0.06]),
'mean_test_score': array([ 0.50, 0.50, 0.50, 0.50, 0.50, 0.50]),
'mean_train_score': array([ 0.50, 0.51, 0.51, 0.51, 0.50, 0.51]),
'param_hidden_layer_sizes': masked_array(data = [5 (5, 5) (5, 10) 10 (10, 5) (10, 10)],
mask = [False False False False False False],
fill_value = ?)
,
'params': [ {'hidden_layer_sizes': 5},
{'hidden_layer_sizes': (5, 5)},
{'hidden_layer_sizes': (5, 10)},
{'hidden_layer_sizes': 10},
{'hidden_layer_sizes': (10, 5)},
{'hidden_layer_sizes': (10, 10)}],
'rank_test_score': array([ 6, 2, 1, 4, 5, 3]),
'split0_test_score': array([ 0.50, 0.50, 0.51, 0.50, 0.50, 0.50]),
'split0_train_score': array([ 0.50, 0.51, 0.50, 0.51, 0.50, 0.51]),
'split1_test_score': array([ 0.50, 0.50, 0.50, 0.50, 0.49, 0.50]),
'split1_train_score': array([ 0.50, 0.50, 0.51, 0.50, 0.51, 0.51]),
'split2_test_score': array([ 0.49, 0.50, 0.49, 0.50, 0.50, 0.50]),
'split2_train_score': array([ 0.51, 0.51, 0.51, 0.51, 0.50, 0.51]),
'std_fit_time': array([19.74, 19.33, 0.55, 0.64, 2.36, 0.65]),
'std_score_time': array([ 0.01, 0.01, 0.00, 0.01, 0.00, 0.01]),
'std_test_score': array([ 0.01, 0.00, 0.01, 0.00, 0.00, 0.00]),
'std_train_score': array([ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00])}
하는 모하메드 발언을 확인하는 것으로 보인다. 나는 순서대로 보이지 않는 거대한 데이터 세트에 무작위 화의 강한 영향을 상상할 수 없었기 때문에 나는 처음에는 상당히 회의적이었다고 말해야 만합니다.
그러나 나는 약간의 의문이 있습니다. 원래의 설정에서 GridSearchCV는 지속적으로 약 0.20만큼 높게 나타 났으며, 이제는 지속적으로 약 0.05로 너무 낮습니다. 이것은 두 방법의 편차가 4 배만큼 감소함에 따라 향상되었습니다. 마지막 발견에 대한 설명이 있습니까? 아니면 두 방법 사이의 편차가 약 0.05 정도로 간단합니까? 나는 이것을 정답으로 표시하기로 마음 먹었지 만, 누군가 내 의심의 여지를 밝힐 수 있기를 바랍니다.
감사합니다. @mohammed kashif, 내가 언급 한 코드를 살펴보고 다시보고하겠습니다. – Arnold
@Arnold 환영합니다! 도움이 필요하면 알려주세요. –