平均神经网络性能取决于 KFold 交叉验证中使用的折叠次数

时间:2021-05-04 16:02:24

标签: python tensorflow keras scikit-learn k-fold

这是我第一次将 KFold 与神经网络结合使用,我正在努力理解为什么性能会因折叠次数而发生显着变化。

我担心我的代码中有错误,也许我遗漏了一些东西。代码如下:

import pandas as pd
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.metrics import r2_score

df = pd.read_csv('../xxx/xxx')

X = df.drop('Dependent', axis=1).values
y = df['Dependent'].values

kf = KFold(n_splits=10, shuffle=True, random_state=101)

oos_y = []
oos_pred = []

fold = 0
for train, test in kf.split(X):
    fold+=1
    print(f'Fold #{fold}')
    
    X_train = X[train]
    y_train = y[train]
    X_test = X[test]
    y_test = y[test]
    
    scaler = MinMaxScaler()
    X_train = scaler.fit_transform(X_train)
    X_test = scaler.transform(X_test)
    
    model = Sequential()
    model.add(Dense(units=936, activation='relu'))
    model.add(Dropout(0.2))
    
    model.add(Dense(units=468, activation='relu'))
    model.add(Dropout(0.2))
    
    model.add(Dense(units=1))
    
    model.compile(loss='mse', optimizer='adam')
    
    early_stop = EarlyStopping(monitor='val_loss',
                          mode='min',
                          verbose=0,
                          patience=25)
    
    model.fit(X_train, y_train, 
              validation_data=(X_test, y_test),
              batch_size=128,
              verbose=0, 
              epochs=400,
             callbacks=[early_stop])
    
    pred = model.predict(X_test)
    
    oos_y.append(y_test)
    oos_pred.append(pred)
    
    score = r2_score(pred, y_test)
    print(f'Fold score (r2): {score}')
    
oos_y = np.concatenate(oos_y)
oos_pred = np.concatenate(oos_pred)
score = r2_score(oos_pred, oos_y)
print(f'Final, out of sample score (r2): {score}')

我运行了这段代码,分割次数为 5、10、15、20、25 和 30,性能分别为:0.77、0.72、0.79、0.80、0.79 和 0.76。具体来说,在 10 倍时,性能似乎显着下降,这令人困惑,因为将其与具有相同拆分和数据集的不同机器学习算法进行比较并没有重现这种趋势。如果有人可以解释性能突然下降 10 倍,或者额外指出代码中的错误,我将不胜感激!

大部分代码是通过遵循这个youtube tutorial获得的,我自己添加了缩放器和提前停止。

1 个答案:

答案 0 :(得分:0)

如果您仔细研究一下交叉验证是什么,对于不同的 k 值有不同的结果是很正常的。

特别是如果您有 100 个数据点,10 次折叠将使用 90 个用于训练的元素和 10 个用于测试的元素创建折叠。 如果将折叠次数改为 20 次,则测试部分会变小,而测试部分会变大,分别为 95 和 5。

考虑到这一点,平均准确度会有所不同,因为您使用的数据本身在维度上发生变化。 它们直接影响网络可用于训练的示例以及用于测试的示例数量。

选择 k 值时应该考虑的一件事是数据集的维度,对于大数据集,您可以考虑 k >= 10 但请记住这意味着您将使用少于 10% 作为每个折叠的测试集。这可能会导致对结果有效性的错误假设。