我正在 Keras 中构建一个用于回归任务的小型神经网络,我想使用与 scikit-learn RandomForestRegressor :
系数 R^2 定义为|相同的精度指标| ||,其中
(1 - u/v)
是回归平方和u
,而((y_true - y_pred) ** 2).sum()
是残差平方和v
((y_true - y_true.mean()) ** 2).sum()
这是一个方便的指标,因为它显示的值高达1.0(类似于百分比准确度)分类)。我对 Keras 后端的使用是否符合我想要的准确度指标?
这似乎有效,没有任何错误,并且指标随着时间的推移逐渐增加到 1,但我想确保我正确实现了该指标。
def create_model():
model = Sequential()
model.add(Dense(10, input_dim=X.shape[1], activation="relu"))
model.add(Dense(10, activation="relu"))
model.add(Dense(1))
# Compile model
model.compile(loss="mean_squared_error", optimizer="adam", metrics=[det_coeff])
return model
# Is this computing the right thing?
def det_coeff(y_true, y_pred):
u = K.sum(K.square(y_true - y_pred))
v = K.sum(K.square(y_true - K.mean(y_true)))
return K.ones_like(v) - (u / v)
This appears to work in that nothing errors and the metric is increasing towards 1 over time, but I want to be sure I implemented the metric correctly.
关于 R² 指标的实现
几乎是正确的
。只需要对
K.mean(y_true)
进行一次小的修改即可。
问题在于,当前的实现计算的是 每个批次的平均值 ,而不是 整个数据集的全局平均值 。在 R² 的上下文中,需要将预测值与目标变量的全局平均值进行比较,而不仅仅是当前批次的平均值。
以下是如何修复它的方法:
def det_coeff(y_true, y_pred):
SS_res = K.sum(K.square( y_true - y_pred ))
SS_tot = K.sum(K.square( y_true - K.mean(y_true) ) )
return ( 1 - SS_res/(SS_tot + K.epsilon()) )
解释:
-
使用
K.epsilon()
: 我们在分母中添加了一个小的常数K.epsilon()
,以防止出现除以零的情况,当SS_tot
非常小时,可能会发生这种情况。
通过此更改,的
det_coeff
函数现在将计算作为 Keras 模型指标的 R² 分数。
其他建议:
-
可以考虑使用
tf.keras.metrics.R_square
,它可以直接计算 R² 分数,而无需手动实现。
from tensorflow.keras.metrics import R_square
model.compile(loss="mean_squared_error",
optimizer="adam",
metrics=[R_square()])
- 请记住,虽然 R² 是一个有用的指标,但它并不是评估回归模型的唯一指标。还应该考虑其他指标,例如均方误差 (MSE)、均方根误差 (RMSE) 和平均绝对误差 (MAE)。