Python 中的平方误差相关性区域 (SERA) 实现作为自定义评估指标

问题描述 投票:0回答:2

我面临着不平衡回归问题,我已经尝试了多种方法来解决这个问题。最终,我遇到了这个称为 SERA(平方误差相关区域)的新指标,作为本文中提到的不平衡回归的自定义评分函数。 https://link.springer.com/article/10.1007/s10994-020-05900-9

为了计算 SERA,您必须计算相关函数 phi,该函数以小步长从 0 变化到 1。对于每个相关性 (phi) 值(例如 0.45),选择训练数据集的一个子集,其中相关性大于或等于该值(例如 0.45)。对于选定的训练子集,计算平方误差之和,即 sum(y_true - y_pred)**2,称为平方误差相关性 (SER)。然后计算我们为 SER 与 phi 和曲线下面积创建的图,即 SERA。

这是我的实现,受到 this StackOverflow 中其他问题的启发:

import pandas as pd
from scipy.integrate import simps
from sklearn.metrics import make_scorer

def calc_sera(y_true, y_pred,x_relevance=None):
    # creating a list from 0 to 1 with 0.001 interval
    start_range = 0
    end_range = 1
    interval_size = 0.001

    list_1 = [round(val * interval_size, 3) for val in range(1, 1000)]
    list_1.append(start_range)
    list_1.append(end_range)
    epsilon = sorted(list_1, key=lambda x: float(x))
    
    df = pd.concat([y_true,y_pred,x_relevance],axis=1,keys= ['true', 'pred', 'phi'])
    # Initiating lists to store relevance(phi) and squared-error relevance (ser)
    relevance = []
    ser = []

    # Converting the dataframe to a numpy array
    rel_arr = x_relevance
    # selecting a phi value
    for phi in epsilon:
        relevance.append(phi)
        error_squared_sum = 0
        error_squared_sum = sum((df[df.phi>=phi]['true'] - df[df.phi>=phi]['pred'])**2)
        ser.append(error_squared_sum)

    # squared-error relevance area (sera)
#     numerical integration using simps(y, x)

    sera = simps(ser, relevance)

    return sera

sera = make_scorer(calc_sera, x_relevance=X['relevance'], greater_is_better=False)

我使用这个分数作为评估指标来实现一个简单的 GridSearch 来选择最佳模型:

model = CatBoostRegressor(random_state=0)
cv = KFold(n_splits = 5, shuffle = True, random_state = 42)

parameters = {'depth': [6,8,10],'learning_rate' : [0.01, 0.05, 0.1],'iterations': [100,   200, 500,1000]}

clf = GridSearchCV(estimator=model, 
               param_grid=parameters,
               scoring=sera, 
               verbose=0,cv=cv)

clf.fit(X=X.drop(columns=['relevance']),
      y=y,
      sample_weight=X['relevance'])

print("Best parameters:", clf.best_params_)
print("Lowest SERA: ", clf.best_score_)

我还将相关性函数作为权重添加到模型中,以便它可以在学习任务中应用该权重。但是,我得到的输出是这样的:

Best parameters: {'depth': 6, 'iterations': 100, 'learning_rate': 0.01}
Lowest SERA:  nan

关于为什么 SERA 值返回 nan 有任何线索吗?我应该以另一种方式实现吗?

python machine-learning metrics loss-function catboost
2个回答
0
投票

每当您在网格搜索中获得意外的 NaN 分数时,您应该设置参数

error_score="raise"
来获取错误回溯,并从那里进行调试。

在这种情况下,我认为我看到了问题:

sera
是用
x_relevance=X['relevance']
定义的,其中包括
X
的所有行。但在搜索中,您正在交叉验证:每个测试集的行数较少,而这些行将被调用。我可以想到几个选择;我也没有测试过,所以如果有问题请告诉我。
使用pandas索引

在您的

sera

中,只需设置

pd.concat
。如果
join="inner"
是原始 pandas 系列的一部分(我认为这就是
y_true
将如何传递它......),那么串联将连接到这些行索引,因此保留整个
GridSearchCV
就可以了:它只会删除不相关的行。
X['relevance']
很可能是一个 numpy 数组,因此您可能需要首先适当地设置其索引?
保持相关性 

y_pred

然后您的记分员可以直接从切片的 

X

引用

relevance
列。为此,您需要从拟合数据中删除该列,这对于训练集可能很难做到,但对于测试集则不然;然而,CatBoost 有一个我认为应该起作用的
X
参数。
    


0
投票

https://github.com/paobranco/ImbalanceMetrics

© www.soinside.com 2019 - 2024. All rights reserved.