为什么我的 MultiOutputRegressor 方法的平均绝对误差 (MAE) 显示一个值而不是三个?

Why is my Mean Absolute Error (MAE) from a MultiOutputRegressor method showing one value instead of three?

我有以下代码,其中我需要预测 3 个不同的输出,然后计算每个输出的 MAE(平均绝对误差)。 由于支持向量机回归本身不像其他模型那样支持多输出回归,例如随机森林和线性回归。我找到了一个选项,可以使用 MultiOutputRegressor class 并将其视为每个输出的单独模型。

我有以下代码,其中 x 是我的训练和测试特征,y 是我的目标。

1) 首先我想证明我的目标 (y) 有 3 个值

print(X.shape, X_test.shape,y.shape,y_test.shape)

(10845, 2116) (4648, 2116) (10845, 3) (4648, 3)

2) 然后我有以下代码来计算平均绝对误差 (MAE) 以及训练模型并在数据集上对其进行评估:

# Function to calculate mean absolute error
def mae(y_true, y_pred):
    return np.mean(abs(y_true - y_pred))

# Funtion to take in a model, train it and evaluate it on the test set
def fit_and_evaluate2 (model):

    # Train the model with training dataset for features (X) and target (y) 
    model.fit(X, y)

    # Make predictions for the test dataset and evaluate the predictions vs the target in the test dataset
    model_pred = model.predict(X_test)
    model_mae = mae(y_test, model_pred)

    # Return the performance metric
    return model_mae

3) 当我为支持向量机回归调用此函数时,model_pred 给出的输出实际上是 3 个值,但 MAE model_mae 只有 1 个值:

svm = SVR(C = 1000, gamma = 0.1)
wrapper= MultiOutputRegressor(svm)

svm_mae = fit_and_evaluate2(wrapper)

print('Support Vector Machine Regression Performance on the test set is')
svm_mae

Support Vector Machine Regression Performance on the test set is
0.19932177495538966

我不明白为什么 model_mae 只显示一个值,因为如上图所示,我的目标 y 实际上有 3 个值,而 model_pred 也显示了 3 个值。我做错了什么吗?我用随机森林试过了,预测和 MAE 都显示了 3 个值。

原因是在没有指定 axis 参数时在 np.mean 中使用的默认值 axis=None;来自 docs:

axis: None or int or tuple of ints, optional

Axis or axes along which the means are computed. The default is to compute the mean of the flattened array.

因为它首先展平数组(即不再有 3 个不同的输出),然后计算 MAE,它现在是一个数字。

您应该将 mae 函数的定义更改为:

def mae(y_true, y_pred):
    return np.mean(abs(y_true - y_pred), axis=0)

让我们确认它可以处理一些虚拟数据:

import numpy as np

# 2-output data
y_true = np.array([[0.5, 1], [-1, 1], [7, -6]])
y_pred = np.array([[0, 2], [-1, 2], [8, -5]])
mae(y_true, y_pred)
# array([0.5, 1. ])

即2 值 MAE 输出,根据需要。

我们实际上可以使用 scikit-learn 的 mean_absolute_error 和适当的参数 multioutput='raw_values' (docs):

来确认这个结果
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_true, y_pred, multioutput='raw_values')
# array([0.5, 1. ])

可以说,由于您已经在使用 scikit-learn,因此最好利用 MAE 的现有功能而不是使用您自己的功能。