模型的评估和验证是机器学习和数据分析流程中的关键步骤,用于确保模型的有效性和可靠性。它们帮助我们理解模型的性能、准确性和可靠性,确保模型在实际应用中能够做出正确的预测或决策。

评估专注于衡量模型在未见数据上的最终性能,通常在模型开发的最后阶段进行。验证聚焦于模型训练过程中的性能监测与调优,以确保模型既不过拟合也不欠拟合。

模型的评估与验证是一个迭代过程,可能需要多次循环直到达到满意的性能水平。在整个过程中,重要的是要保持数据的清洁和预处理的一致性,以及模型评估的公正性和可重复性。

以下是模型评估与验证的一些关键概念和方法

数据集拆分

在训练过程中,假设数据量比较小,我们不可能将一整个数据集都用在训练上,这样我们想使用一些新的数据去验证这个模型是否过拟合时,就没有数据了。

这个时候,我们就需要对数据进行拆分,分为如下三个数据集:

  • 训练集(Training Set):用于训练模型的数据。

  • 验证集(Validation Set):在训练过程中用于调整模型参数和选择最佳模型版本的数据。

  • 测试集(Test Set):独立于训练集和验证集的数据,用于最终评估模型的泛化能力。

通常来说,在原始数据中拆分只会拆成训练集(验证集会包含在里面)和测试集。个人建议按照8:2的比例进行拆分,即80%作为训练集,20%作为测试集。

例如,假设拿到的数据集有8000条,那么训练集就是6400条,测试集就是1600条。

当然,这个比例不是固定的,可以根据自己的数据量进行调整。常见的也有7:3的比例拆分数据集。

拆分数据集的方法有很多,这里使用sklearn中的sklearn.model_selection.train_test_split去进行拆分,例子如下:

from sklearn.model_selection import train_test_split
​
X = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
Y = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
​
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.2, random_state=42)

其中test_size就是定义测试集的长度,输入值在[0, 1]之间。

random_state的作用是控制随机数生成器的状态,从而确保每次运行代码时,数据分割的结果都是相同的。该参数建议固定为42(原因是官方案例为42),固定为42不会影响到使用,在实际案例时请放心抄。

train_test_split也支持对多维数组进行拆分,例如:

from sklearn.model_selection import train_test_split
​
X = np.array([[np.random.randint(0, 100000000) for _ in range(100)] for _ in range(8000)])
Y = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
​
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.2, random_state=42)

当模型仅需要X,不需要Y时,train_test_split可以只切割X,例如:

from sklearn.model_selection import train_test_split
​
X = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
​
Xtrain, Xtest = train_test_split(X, test_size=0.2, random_state=42)

交叉验证(Cross-validation)

前面提到了对数据进行拆分,分为三个数据集。而训练集会包含验证集,这个会怎么用上呢?这里就会用到交叉验证这个方法

交叉验证是一种统计学方法,用于评估模型的性能,特别是当可用数据量非常有限时。

常见的有k折交叉验证(k-Fold CV),其中数据被分为k个子集,每次将其中一个子集作为验证集,其余作为训练集,重复k次。

k折交叉验证会将训练集分块拆分,拆分多少块记为K(像折纸一样),并用不同的折块进行验证,得出来的所有结果取平均数为最终结果

比较常用的是sklearn.model_selection.cross_val_score,例子如下

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, cross_val_score
​
X = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
Y = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
​
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.2, random_state=42)
​
clf = DecisionTreeClassifier(random_state=42, max_depth=4, criterion="entropy").fit(Xtrain, Ytrain)
score = cross_val_score(clf, X, Y, cv=10).mean()

这个例子中,首先在cross_val_score中输入模型,然后将未被拆分的数据X和Y输入进去,而后定义cv=10表示将数据集拆分成10份进行交叉验证。所得的分数取平均最终得到结果

该函数得到的分数区间(置信区间)为[0, 1],其分数越接近1,置信度(也就是该模型的泛化程度)越高。

cross_val_score函数目前只支持sklearn的模型,如果需要使用自定义模型(特别是神经网路模型),可以使用sklearn.model_selection.KFold,例子如下:

from sklearn.model_selection import KFold
​
X = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
Y = np.array([np.random.randint(0, 100000000) for _ in range(8000)])
​
kf = KFold(n_splits=10, shuffle=True, random_state=42)
scores = []
for train_index, test_index in kf.split(X):
    Xtrain, Xtest = X[train_index], X[test_index]
    Ytrain, Ytest = Y[train_index], Y[test_index]
    clf = DecisionTreeClassifier(random_state=42, max_depth=4, criterion="entropy").fit(Xtrain, Ytrain)
    score = clf.score(Xtest, Ytest)
    scores.append(score)
score = np.mean(scores)

这个例子中,首先定义了KFold,然后使用for循环遍历KFold,每次将数据集拆分成训练集和测试集,然后训练模型并计算分数,最后取平均得到结果

评估指标

对于每种不同的模型,对应有不同的评估指标,通常使用sklearn.metrics下的包

详细请看: https://scikit-learn.org/stable/modules/model_evaluation.html

回归问题

均方误差(MSE):metrics.mean_squared_error

均方根误差(RMSE):sklearn没有提供RMSE,但它可以通过先计算MSE再取平方根来获得。

平均绝对误差(MAE):sklearn.metrics.mean_absolute_error

R^2分数:metrics.r2_score

分类问题

准确率(Accuracy):sklearn.metrics.accuracy_score

精确率(Precision):sklearn.metrics.precision_score

召回率(Recall):sklearn.metrics.recall_score

F1分数:sklearn.metrics.f1_score

AUC-ROC曲线下的面积(AUC-ROC):sklearn.metrics.roc_auc_score

其他问题:

对于聚类,可以使用如下指标

轮廓系数(Silhouette Coefficient):sklearn.metrics.silhouette_score

Calinski-Harabasz指数:sklearn.metrics.calinski_harabasz_score

强化学习通常使用累计奖励(Cumulative Reward)或策略评估(Policy Evaluation)来衡量,它们通常不在scikit-learn的范围内。

文章作者: Vsoapmac
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 soap的会员制餐厅
人工智能 数据分析 个人分享 第三方库 算法
喜欢就支持一下吧