实用技巧 - trick1

多分类下准召f1优化

简单地说就是如果多类别不均衡的话,这时候直接使用神经网络优化交叉熵损失得到的结果,f1显然不是全局最优的,很多同学都会问,二分类下的阈值搜索我会,如果是多分类怎么做一个阈值搜索呢?传统的多分类我们预测结果使用argmax(logits)这时候,可以形式化的表达为求argmax(w*logits)使得f1均值最大。其中w就是要求得的再放缩权重。 我们可以使用非线性优化的方法,求解这个问题,scipy的库里有很多实现了。

有序关系的离散标签优化

我们经常遇到这样的问题,比如情感打分预测1-5,我们用mse指标来评价,通常,我们用回归拟合1-5的时候,如何切分阈值对我们的结果有很大的影响,在这里我们也是进行阈值的搜索,不一样的是。我们的阈值要在1-5之间。使用的方法也是非线性优化。下面一段代码给一个简单的例子,同理前面多分类下的准召优化我们也可以这样写

from functools import partial
import numpy as np
import scipy as sp
class OptimizedRounder(object):
	def __init__(self):
		self.coef_ = 0
	
	def _kappa_loss(self,coef,X,y):
		X_p = np.copy(X)
		for i,pred in enumerate(X_p):
			if pred < coef[0]:
				X_p[i] = 0
			elif pred >= coef[0] and pred < coef[1]:
				X_p[i] = 1
			elif pred >= coef[1] and pred < coef[2]:
				X_p[i] = 2
			elif pred >= coef[2] and pred < coef[3]:
				X_p[i] = 3
			else:
				X_p[i] = 4
		ll = quadratic_weighted_kappa(y,X_p)
		return -ll
	def fit(self,X,y):
        loss_partial = partial(self._kappa_loss, X=X, y=y)
        initial_coef = [0.5, 1.5, 2.5, 3.5]
        self.coef_ = sp.optimize.minimize(loss_partial, initial_coef, method='nelder-mead')
	def predict(self,X,coef):
		X_p = np.copy(X)
		for i, pred in enumerate(X_p):
            if pred < coef[0]:
                X_p[i] = 0
            elif pred >= coef[0] and pred < coef[1]:
                X_p[i] = 1
            elif pred >= coef[1] and pred < coef[2]:
                X_p[i] = 2
            elif pred >= coef[2] and pred < coef[3]:
                X_p[i] = 3
            else:
                X_p[i] = 4
        return X_p
	def coefficients(self):
		return self.coef_['x']

活学活用trick,spearman优化

Google QUEST Q&A Labeling这个比赛是多标签(multi-lable)分类比赛,指标是spearman (度量一对观测数据的统计依赖性) 相关系数,特点是衡量两个结果的排序一致性。数据集的标注几个人标注后取平均,带来的结果就是,多标签的每个类上打分是nunique < 10的离散值,划重点,注意这里标注的是离散值。而spearman的特点是:

a = np.array([0.5, 0.5, 0.7, 0.7])
b = np.array([4., 5., 6., 7.])
print_spearmanr(a, b) # --> 0.89
b2 = np.array([4., 4., 6., 6.])
print_spearmanr(a, b2) # --> 1.

我们的神经网络,预测的logits 即使到fp16也很难一模一样,所以我们预测的结果一般nunique==len(predict),而标注nunique可是个位数。那么问题来了,标注的数量是有限个,你如果你不对标注的结果进行分箱离散化。那么就吃了大亏了…,所以你请你使用我们上述讲过的方法,设计一个好的办法来优化这件事情吧。

你可能感兴趣的:(Kaggle入门)