算法比赛Trick(1)——后处理指标优化

在算法比赛中,往往存在类别不均衡的问题,在有“偏见”数据上训练出的模型可能不是最优的。如果我们能在模型预测出的各类别分数上,添加权重因子,并利用优化算法自动计算这些因子的值,使预测结果达到验证集上的最优,那么在测试集也许会有提升。

示例

假设比赛的评分函数是macro-f1值,X的形状为(dev_num, class_num),表示模型的预测结果,y的形状为(dev_num, 1),表示真实的标签。

常规的预测评分代码如下所示:

pred = np.argmax(X, axis=1)
score = f1_score(y, pred, average='macro')

引入后处理指标优化的代码如下所示:

import numpy as np
import scipy as sp
from functools import partial
from sklearn.metrics import f1_score

np.random.seed(2)

# 待优化的函数
def func(coef, x, y):
    pred = np.argmax(x * coef, axis=1)
    macro_f1 = f1_score(y, pred, average='macro')
    return -macro_f1
func_1 = partial(func, x=X, y=y)

# 初始化各类别的权重因子
class_num = 14
init_coef = np.random.rand(1, class_num)

# 利用scipy,计算dev上最优的因子值
res = sp.optimize.minimize(func_1, init_coef, method='Nelder-Mead')
best_coef = res.x

# 预测,X_test表示模型在测试集上计算出的预测值
X_test = X_test * best_coef
test_pred = np.argmax(X_test, axis=1)
score = f1_score(y, test_pred, average='macro')

非线性优化

上文提到的**scipy.optimize.minimize()**是Python中非线性规划求极值常用的方法,其官方文档在此

下面以求 f(x) = a / x + x,a为常数 这一经典的勾函数极值问题,介绍minimize的用法,代码如下:

from functools import partial
from scipy.optimize import minimize
import numpy as np

# 待优化函数
def fun(a, x):
    return a / x + x
a = 1
fun_1 = partial(fun, a)

# 随意为x猜测一个初值
x0 = np.asarray([2.5])
res = minimize(fun_1, x0, method='Nelder-Mead')
# 是否成功优化
print(res.success)
# 函数最优时,x的值
print(res.x)
# 函数最优值
print(res.fun)

优化方法除了’Nelder-Mead’还有许多,参见官方文档。

实战验证

笔者参与了2022年科大讯飞的全球足球联赛比赛胜负预测挑战赛,三分类macro-f1从0.42395提升到了0.42869,净提升0.00474。提升并不是很大,但终归有所进步:)。

参考链接

  1. 疫情期间网民情绪识别比赛后记
  2. 非线性规划(scipy.optimize.minimize)
  3. How to Improve Class Imbalance using Class Weights in Machine Learning
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值