模型如何在随机数据上获得完全相同的准确性?

时间:2019-05-09 10:45:01

标签: python machine-learning keras

我正在比较遗传学分类的模型,它们在4类基因之间进行分类,以便确定与疾病影响有关的基因的肯定,可能,可能或未知。

我运行它们,它们的准确性都在65-80%左右,这是通过嵌套交叉验证来避免过度拟合而获得这些百分比。但是,然后我给这些模型提供了一个随机数据集,并且其中一些模型通过多次运行获得了完全相同的准确性(没有交叉验证,只是看到了分割测试数据的准确性),这真的可能吗,还是这些模特正达到平稳状态?从我的初学者的角度来看,我会认为这不太可能,任何帮助将不胜感激。

这是我用于测试随机数据的代码:

inner_cv = KFold(n_splits=10, shuffle=True, random_state=seed)
outer_cv = KFold(n_splits=10, shuffle=True, random_state=seed)

models = []
models.append(('LR', dcv.GridSearchCV(logreg, LR_par, cv=inner_cv, iid=False, n_jobs=-1)))
models.append(('SVM', dcv.GridSearchCV(svm, tuned_parameters, cv=inner_cv, iid=False, n_jobs=-1)))
models.append(('RFC', dcv.GridSearchCV(rfc, param_grid, cv=inner_cv,iid=False, n_jobs=-1)))
models.append(('Keras', GridSearchCV(estimator=keras, param_grid=kerasparams, cv=inner_cv,iid=False, n_jobs=-1)))

arr = np.arange(5400).reshape((600, 9))
random = np.random.permutation(arr)
ran = np.random.randint(4, size=600)
rand = np.column_stack((random, ran))
print(rand.shape)
X1 = rand[0:600,0:8]
Y1 = rand[0:600,-1]
print("Random data counts of label '0': {}".format(sum(ran==0)))
print("Random data counts of label '1': {}".format(sum(ran==1)))
print("Random data counts of label '2': {}".format(sum(ran==2)))
print("Random data counts of label '3': {}".format(sum(ran==3)))
print(X1.shape)
print(Y1.shape)
X1 = MinMaxScaler().fit_transform(X1)

X_train1, X_test1, Y_train1, Y_test1 = train_test_split(X1, Y1, test_size=0.2, random_state=0)

for name, model in models:
    model.fit(X1, Y1)
    print(name, 'Random accuracy: {:.2f}'.format(model.score(X_test1, Y_test1)*100),  '%')

输出如下:

(600, 10)
Random data counts of label '0': 136
Random data counts of label '1': 153
Random data counts of label '2': 155
Random data counts of label '3': 156
(600, 8)
(600,)


LR Random accuracy: 26.67 %
SVM Random accuracy: 26.67 %
RFC Random accuracy: 38.33 %
Keras Random accuracy: 23.33 %

好像是这样,如果我运行此代码4次,则第一次精度是不同的,接下来的3次对于SVM和LR(逻辑回归),它们通常保持不变。

我在anaconda中使用python 3.7,并使用Jupyterlab 0.35.4

1 个答案:

答案 0 :(得分:0)

据我所知,您的问题出在使用sklearn的KFold的方式上。就RFC(猜测随机森林分类器)而言,它也具有随机元素。 Logistic回归也有一个随机因素,我不知道SVM。对于它的价值,这里是一些文档。在对stackoverflow提出问题之前,我建议您查阅每种算法的文档。

来自KFold的文档:

  

随机播放:布尔值,可选

     

是否在拆分成批之前重新整理数据。

     

random_state:整数,RandomState实例或无,可选,   默认=无

     

如果为int,则random_state是随机变量使用的种子   数字发生器如果是RandomState实例,则random_state是random   数字发生器如果为None,则随机数生成器为   np.random使用的RandomState实例。在shuffle == True时使用。

和随机森林分类器

  

引导程序:布尔值,可选(默认= True)

     

在构建树时是否使用引导程序样本。如果为False,则   整个数据集用于构建每棵树。

因此,如果您每次都希望获得完全相同的数据,则应将shuffle设置为false并删除random_state(因为默认值为None)。

inner_cv = KFold(n_splits=10, shuffle=False)
outer_cv = KFold(n_splits=10, shuffle=False)

尽管这不能确保您获得相同的结果,因为这很大程度上取决于您使用的算法。根据文档,Scikit-Learn的Random Forest和Logistic回归都有一个您不能关闭的随机元素。