Python 我如何解释测试数据的性能下降?

Python 我如何解释测试数据的性能下降?,python,scikit-learn,classification,Python,Scikit Learn,Classification,我在这里问这个问题,尽管我在交叉验证(或数据科学)StackExchange上发布它时犹豫了。我有一个包含60个标记对象(用于培训)和150个未标记对象(用于测试)的数据集。这个问题的目的是预测150个对象的标签(这曾经是一个家庭作业问题)。对于每个对象,我计算了258个特征。以每个对象为样本,我有X\u序列:(60258),y\u序列:(60,)(用于训练的对象的标签)和X\u测试:(150258)。由于家庭作业问题的解决方案已经给出,我也有了150个对象的真实标签,在y\u测试中:(150,

我在这里问这个问题,尽管我在交叉验证(或数据科学)StackExchange上发布它时犹豫了。我有一个包含60个标记对象(用于培训)和150个未标记对象(用于测试)的数据集。这个问题的目的是预测150个对象的标签(这曾经是一个家庭作业问题)。对于每个对象,我计算了258个特征。以每个对象为样本,我有
X\u序列:(60258)
y\u序列:(60,)
(用于训练的对象的标签)和
X\u测试:(150258)
。由于家庭作业问题的解决方案已经给出,我也有了150个对象的真实标签,在
y\u测试中:(150,)

为了预测150个对象的标签,我选择使用LogisticRegression(Scikit学习实现)。数据标准化后,分类器在
(X\u序列,y\u序列)
上进行训练,并用于对150个对象进行预测。将这些预测与y_检验进行比较,以评估模型的性能。为了再现性,我复制了我使用过的代码

from sklearn import metrics
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import cross_val_score, crosss_val_predict

# Fit classifier
LogReg = LogisticRegression(C=1, class_weight='balanced')
scaler = StandardScaler()
clf = make_pipeline(StandardScaler(), LogReg)
LogReg.fit(X_train, y_train)

# Performance on training data
CV_score = cross_val_score(clf, X_train, y_train, cv=10, scoring='roc_auc')
print(CV_score)

# Performance on test data
probas = LogReg.predict_proba(X_test)[:, 1]
AUC = metrics.roc_auc_score(y_test, probas)
print(AUC)
矩阵
X\u列
y\u列
X\u测试
y\u测试
保存在.mat文件中,该文件位于。我的问题如下:


使用这种方法,我在训练数据上获得了很好的性能(CV_分数=0.8),但在测试数据上的性能更差:对于LogReg中的C=1,AUC=0.54;对于C=0.01,AUC=0.40。如何获得AUC首先,60个训练项目拥有258个功能是没有意义的。其次,60个项目的CV=10意味着将数据分为10个序列/测试集。每个测试集中只有6个项目。所以无论你得到什么结果都是无用的。您需要更多的训练数据和更少的功能。

看起来您遇到了过度拟合问题,即使用训练数据训练的分类器与训练数据过度拟合。泛化能力差。这就是测试数据集的性能不好的原因

cross\u val\u predict
实际上是使用部分测试数据训练分类器,然后对其余数据进行预测。所以性能要好得多

总的来说,您的培训和测试数据集之间似乎有相当大的差异。因此,具有最高训练精度的分类器在测试集上无法正常工作


另一点与您的问题不直接相关:由于您的训练样本数量远小于特征维度,因此在输入分类器之前执行维度缩减可能会有所帮助。

看起来您的训练和测试过程不一致。虽然您打算从代码中标准化数据,但在测试过程中未能做到这一点。我的意思是:

clf=make_管道(StandardScaler(),LogReg)
LogReg.fit(X_系列、y_系列)
尽管您定义了一个管道,但您并不适合管道(
clf.fit
),而只适合逻辑回归。这很重要,因为交叉验证分数是通过管道计算的(
CV\u分数=交叉验证分数(clf,X\u序列,y\u序列,CV=10,scoring='roc\u auc')
),但在测试过程中,您没有按照预期使用管道,而是只使用
LogReg
,因此测试数据没有标准化

你提出的第二点是不同的。在
y_pred=cross_val_predict中(clf,X_检验,y_检验,cv=5)
您可以通过对测试数据进行交叉验证来获得预测,同时忽略列车数据。在这里,您使用
clf
进行数据标准化,因此您的分数很高;这证明标准化步骤很重要

总之,标准化考试数据,我相信会提高你的考试成绩

y_pred = cross_val_predict(clf, X_test, y_test, cv=5) 
AUC = metrics.roc_auc_score(y_test, y_pred)
print(AUC)