完整解读!机器学习模型评估指标!
模型评估是机器学习里挺重要的一环,通过评估,我们就能知道模型能否很好地应用到新数据上,能否达到预期目标。
机器学习模型有很多种,像是分类、回归、聚类和降维这些。不同类型的模型,评估方式也不一样。
比如说,分类模型,主要看准确率、精度、召回率、F1 分数,简单来说就是预测数据点属于哪个类别,与实际类别是否一致。比如预测邮件是不是垃圾邮件,肿瘤是不是良性的,或者客户会不会买咱们的产品。
再比如说,回归模型就是要评估模型预测的数值(比如预测股票第二天的价格是10块),与实际价格数值差异大不大。
分类模型的评估指标
也就是要看模型分类准不准。具体来说,有这些常用的指标:
- 准确性:这个最好理解,就是模型预测对的比例。算法很简单,就是用预测对的数量除以总数。
- 精度:这个指标主要看模型预测为正例的里面,真正是正例的比例。算法是:真阳性数除以(真阳性数+假阳性数)。
- 召回率:这个指标主要看模型真正预测出正例的比例。算法是:真阳性数除以(真阳性数+假阴性数)。
- F1 分数:这个指标综合了精度和召回率,给出了一个单一的分数,表示模型的整体性能。算法是:2精度召回率除以(精度+召回率)。
- 混淆矩阵:这个矩阵里包括了真阳性、假阳性、真阴性和假阴性的数量,能全面展示模型的性能,还能帮你找出错误来源和改进的地方。
- ROC 曲线和 AUC:ROC 曲线能展示不同阈值下的真正率和假正率,而 AUC 是衡量 ROC 曲线下的面积,值越大表示模型性能越好。
这里有个简单的例子,用 sklearn 库计算上面提到的指标:
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, roc_auc_score, roc_curve
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
# 加载数据集
data = load_iris()
X, y = data.data, data.target
# 为了简单起见,我们只取两个类别的数据
X_binary = X[y != 2]
y_binary = y[y != 2]
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_binary, y_binary, test_size=0.3, random_state=42)
# 初始化模型
model = LogisticRegression()
# 训练模型
model.fit(X_train, y_train)
# 进行预测
y_pred = model.predict(X_test)
# 计算各项指标
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
conf_mat = confusion_matrix(y_test, y_pred)
# 计算AUC
auc = roc_auc_score(y_test, y_pred_prob)
print("AUC: ", auc)
回归模型指标
回归,简单说就是基于已知的东西,来猜未知的数。比如你想知道一套房子的价格,就可以根据房子的面积、地理位置等特征来猜。回归模型就是这样帮你预测的。
但模型预测得准不准呢?这就需要用回归指标来量化了。
- 均方误差(MSE):这就是看你模型预测出来的价格和真实价格差多少。差值越小,模型预测得越准。
公式:MSE = (1/n) * Σ(实际值 – 预测值)²
- 均方根误差(RMSE):就是MSE的“平方根版”。和MSE相比,它的数值更容易理解,因为它和真实数据的单位是一样的。
公式:RMSE = √MSE
- 平均绝对误差(MAE):这个和MSE类似,但是它算的是预测值和真实值差多少的平均值,而不是差值的平方的平均值。
公式:MAE = (1/n)* Σ|实际值 – 预测值|
- R平方:这个指标是衡量模型有多好地解释了数据的变动。值越接近1,说明模型解释得越好。
除了上面这些,还有调整后的R平方,这个考虑了模型中特征的数量,避免因为特征多导致R平方虚高。
这些指标都可以帮你评估回归模型的好坏,选择最适合你问题的模型。
下面是一个用Python的sklearn
库来计算这些指标的简单例子:
Python
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import numpy as np
# 假设这是你的数据和目标值(你可以用你自己的数据替换这些)
X = np.random.rand(100, 1) # 特征数据
y = X * 2 + np.random.randn(100, 1) * 0.1 # 目标数据
# 把数据分成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建一个线性回归模型并训练它
model = LinearRegression()
model.fit(X_train, y_train)
# 使用模型进行预测
y_pred = model.predict(X_test)
# 计算指标
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 样本数量和特征数量
n = len(y_test)
p = X_test.shape[1]
# 计算调整后的R平方
adjusted_r2 = 1 - (1 - r2) * (n - 1) / (n - p - 1)
# 输出结果
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"MAE: {mae}")
print(f"R平方: {r2}")
print(f"调整后的R平方: {adjusted_r2}")
聚类指标
聚类嘛,就是一种没有标签的数据分组方法。比如,咱们可以根据客户的购物习惯把他们分成不同的群体,或者根据文章的内容判断它们是不是讲同一件事。
- Silhouette Score:这个指标看的是样本点跟它所在类的其他点的相似度。得分在-1到1之间,越高说明这个样本点越应该在这个类里。a 是样本点跟它所在类的其他点的平均距离,b 是样本点到其他类所有点的平均距离。
- Davies-Bouldin Index:这个指标越小,说明聚类效果越好。它是根据类里的点之间的距离和类与类之间的距离来算的。k 是类的数量,s 是类里的点之间的距离,c 是类的中心点,d 是两个类中心点之间的距离。
- Calinski-Harabasz 指数:这个指数看的是类与类之间的距离和类里的点之间的距离的比例。比例越高,说明聚类效果越好。+ B 是类与类之间的距离矩阵,W 是类里的点之间的距离矩阵,n 是样本数量,k 是类的数量。
下面是一个简单的代码示例,用 scikit-learn 来计算这些指标:
from sklearn.metrics import silhouette_score, davies_bouldin_score, calinski_harabasz_score
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# 生成一些随机数据
X, _ = make_blobs(n_samples=150, n_features=2, centers=3, cluster_std=0.5, shuffle=True, random_state=0)
# 用 KMeans 进行聚类
kmeans = KMeans(n_clusters=3, random_state=0)
y_kmeans = kmeans.fit_predict(X)
# 计算指标
silhouette = silhouette_score(X, y_kmeans)
davies_bouldin = davies_bouldin_score(X, y_kmeans)
calinski_harabasz = calinski_harabasz_score(X, y_kmeans)
print(f"Silhouette Score: {silhouette}")
print(f"Davies-Bouldin Index: {davies_bouldin}")
print(f"Calinski-Harabasz Index: {calinski_harabasz}")
降维指标
降维,简单来说,就是把高维度的数据变成低维度的,同时尽量保留原始数据的信息。比如,我们可以把一张彩色图片变成灰度图,虽然颜色信息丢失了,但大致的轮廓还在。
降维指标主要分两类:重建和保存。重建指标看的是降维后的数据能不能还原成原始数据;保存指标看的是降维后的数据能不能保持原始数据的某些特性,比如点与点之间的距离。
一些常用的降维指标有:
- 重建误差:这个指标看的是降维后的数据跟原始数据有多大的差距。差距越小,说明降维效果越好。
- 解释方差:这个指标看的是降维模型能保留多少原始数据的方差。方差越大,说明模型保留的信息越多。
- 压力:这个指标看的是原始空间里的点与点之间的距离和降维后的空间里点与点之间的距离有多大的差距。差距越小,说明降维效果越好。
- 可信度和连续性:这两个指标通常用于评估像t-SNE这样的流形学习算法。可信度看的是降维后的邻居在原始空间里是不是也是邻居;连续性则反过来,看的是原始空间里的邻居在降维后的空间里是不是也是邻居。
下面是一个简单的代码示例,用 scikit-learn 来计算这些指标(以PCA为例):
from sklearn.decomposition import PCA
from sklearn.metrics import mean_squared_error
from sklearn.datasets import make_blobs
# 生成一些随机数据
X, _ = make_blobs(n_samples=150, n_features=5, centers=3, cluster_std=0.5, shuffle=True, random_state=0)
# 用 PCA 进行降维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# 计算重建误差
X_reconstructed = pca.inverse_transform(X_pca)
reconstruction_error = mean_squared_error(X, X_reconstructed)
# 计算解释方差
explained_variance = pca.explained_variance_ratio_.sum()
print(f"Reconstruction Error: {reconstruction_error}")
print(f"Explained Variance: {explained_variance