如何选择或优化标签以获得更好的多类分类结果?

最近我在做一个Kaggle项目“Prudential Life Insurance Assessment”,参赛者们讨论通过改变标签来获得更好的评估指标。

在那个特定的比赛中,目标变量有8个类别(1-8),但是其中一人使用了不同的标签(-1.6, 0.7, 0.3, 3.15, 4.53, 6.5, 6.77, 9.0),而另一个例子中他们使用[-1.6, 0.7, 0.3, 3.15, 4.53, 6.5, 6.77, 9.0]替代[1,2,3,4,5,6,7,8]

我想知道这些神奇的数字是如何得出的?

我很乐意接收任何关于如何进行这种转换的想法/技巧/建议。非常欢迎您的输入!

示例代码

# 导入import numpy as npimport pandas as pdimport seaborn as snsimport xgboost as xgbfrom sklearn import metricsfrom sklearn.model_selection import train_test_split# 数据df = sns.load_dataset('iris')df['species'] = pd.factorize(df['species'])[0]df = df.sample(frac=1,random_state=100)# 训练测试分割X = df.drop('species',axis=1)y = df['species']Xtrain,  Xtest, ytrain, ytest = train_test_split(X,y,stratify=y,random_state=100)# 建模model = xgb.XGBClassifier(objective='multi:softprob', random_state=100)model.fit(Xtrain, ytrain)preds = model.predict(Xtest)kappa = metrics.cohen_kappa_score(ytest, preds, weights='quadratic')print(kappa)

我的思考

  • 标签可以取的数字实际上是无限的,如何将[1-8]转换为[x-y]

  • 我们应该随机选择8个数字并检查它们的kappa值吗?这似乎是最不理性的想法,可能永远不会奏效。

  • 是否有某种梯度下降方法可以用于此?也许没有,只是我的一个想法。

参考链接


回答:

您问题中的第一个链接实际上包含了答案:

#这些硬编码的值是通过使用模拟退火优化交叉验证分数获得的

作者后来也评论说:

起初我是逐一优化参数的,但后来我改为通过网格搜索和模拟退火同时优化它们。我不确定是否找到了CV分数的全局最大值,即使在调整了模拟退火的各种设置后。也许遗传算法会有所帮助。

第二个链接的解决方案使用相同的值,因为(可能)作者从第一个解决方案中复制了它们(参见他们的评论):

受启发于:https://www.kaggle.com/mariopasquato/prudential-life-insurance-assessment/linear-model/code

简单来说 – 您可以将这些值视为您的学习算法的元参数(实际上它们就是)。这样您可以定义一个函数F(元参数),计算它的单一值时,您在训练集上进行完整训练并在验证集上输出损失(或者更好的是使用n折交叉验证并使用CV损失)。然后您的任务基本上就是以某种方式优化函数F,以找到最佳的元参数集,使用您喜欢的任何优化方法 – 例如,第一个解决方案的作者声称他们使用了网格搜索和模拟退火。

没有为优化本身进行元调优的小示例:

import numpy as npcnt = 0def use_a_function_which_calls_training_and_computes_cv_instead_of_this(x):    global cnt    cnt += 1    return ((x - np.array([-1.6, 0.7, 0.3, 3.15, 4.53, 6.5, 6.77, 9.0]))**2).sum()my_best_guess_for_the_initial_parameters = np.array([1.,2.,3.,4.,5.,6.,7.,8.])optimization_results = scipy.optimize.basinhopping(    use_a_function_which_calls_training_and_computes_cv_instead_of_this,    my_best_guess_for_the_initial_parameters,    niter=100)print("函数被调用的次数: {0}".format(cnt))print(optimization_results.x)

示例输出:

函数被调用的次数: 3080[-1.6         0.7         0.3         3.15        4.52999999  6.5  6.77        8.99999999]

您很可能希望实验优化本身的参数,甚至可能编写您自己的自定义优化器和/或回调以进行步骤调整。但也可能即使是默认参数也能在某种程度上为您工作。如果您发现计算函数一次所需的时间太长,您可以尝试例如用您完整数据的一个较小子集进行初始优化,等等。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注