用于估计索赔成本的随机森林与 XGBoost 与 MLP 回归器

数据挖掘 Python 神经网络 scikit-学习 回归 xgboost
2022-02-10 13:07:37

语境

我正在建立一个(玩具)机器学习模型来估计保险索赔的成本(与伤害相关)。目的是通过实践自学机器学习。我选择了三种算法进行测试:随机森林、XGBoost 和多层感知器。

数据集

数据集具有以下列:

cols = [ 'AGE_RANGE', 'GENDER', 'TOTAL_PAID', 'INDUSTRY_DESCRIPTION', 'WORKER_AGE', 'NATURE_CODE', 'ACCIDENT_TYPE_CODE', 'INJURY_NATURE']

“TOTAL_PAID”是标签 ($s)。其余的都是特征。大多数特征是分类的:

categoricals = [ 'AGE_RANGE', 'GENDER', 'INDUSTRY_DESCRIPTION', 'NATURE_CODE', 'ACCIDENT_TYPE_CODE', 'INJURY_NATURE']

代码:

进口:

import pandas as pd
import numpy as np

cols = [ 'AGE_RANGE', 'GENDER', 'TOTAL_PAID', 'INDUSTRY_DESCRIPTION', 'WORKER_AGE', 'NATURE_CODE', 'ACCIDENT_TYPE_CODE', 'INJURY_NATURE']
features = pd.read_csv('gs://longtailclaims2/filename.csv', usecols = cols, header=0, encoding='ISO-8859-1')
categoricals = [ 'AGE_RANGE', 'GENDER', 'INDUSTRY_DESCRIPTION', 'NATURE_CODE', 'ACCIDENT_TYPE_CODE', 'INJURY_NATURE']

首先,我将分类值转换为 0 和 1:

features2 = pd.get_dummies(features, columns = categoricals)

然后我从标签中分离出特征(TOTAL_PAID):

labels = np.array(features['TOTAL_PAID'])
features = features2.drop('TOTAL_PAID', axis = 1)
feature_list = list(features.columns)
feature_list_no_facts = list(features.columns)

吐入 SK Learn 训练和测试集:

# Using Skicit-learn to split data into training and testing sets
from sklearn.model_selection import train_test_split

# Split the data into training and testing sets
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size = 0.25, random_state = 42)
test_features.head(5)
test_features.head(5)

然后我探索数据:

print('Training Features Shape:', train_features.shape)
print('Training Labels Shape:', train_labels.shape)
print('Testing Features Shape:', test_features.shape)
print('Testing Labels Shape:', test_labels.shape)

输出:

Training Features Shape: (128304, 337)
Training Labels Shape: (128304,)
Testing Features Shape: (42768, 337)
Testing Labels Shape: (42768,)

1. XGBRegressor

首先我们尝试训练 XGBoost 模型。我需要将 # 估计值推到 10,000 以上才能获得不错的准确度(R2 > 0.94)

# Import the model we are using
from xgboost import XGBRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn import ensemble 
from sklearn.metrics import mean_squared_error

x = XGBRegressor(random_state = 44, n_jobs = 8, n_estimators = 10000, max_depth=10, verbosity = 3)
x.fit(train_features, train_labels)
print('xgboost train score: ', x.score(train_features, train_labels))
predictions = x.predict(test_features)
print('xgboost test score: ', x.score(test_features, test_labels))

在这里,训练和测试分数:R2 ~0.94。

2. 随机森林回归器

然后我们尝试随机森林模型。经过一番摆弄后,看起来 100 个估计量足以获得相当不错的准确度(R2 > 0.94)

# Instantiate model with 100 decision trees
rf = RandomForestRegressor(n_estimators = 100, criterion='mse', verbose=1, random_state = np.random.RandomState(42), n_jobs = -1)
# Train the model on training data
rf.fit(train_features, train_labels);
print('random forest train score: ', rf.score(train_features, train_labels))
predictions = rf.predict(test_features)
print('random forest test score: ', rf.score(test_features, test_labels))

在这种情况下,训练和测试分数 R2 约为 0.94。

3. MLP 神经网络

最后,我想将性能与 MLP 回归器进行比较。根据我一直在阅读的有关深度学习的书籍,只要有足够的时间和马力,神经网络应该能够胜过任何浅层学习算法。我在 Google Cloud 上使用了一台非常强大的机器,它有 8 个内核和 30 GB RAM。

from sklearn.neural_network import MLPRegressor
nn = MLPRegressor(hidden_layer_sizes=(338, 338, 50), 
                  activation='relu', solver='adam', max_iter = 100, random_state = 56, verbose = True)
nn.fit(train_features, train_labels)
nn_predictions = nn.predict(test_features)
print('nn train score: ', nn.score(train_features, train_labels))
print('nn test score: ', nn.score(test_features, test_labels))

R2 约为 0.4。

我在输入层使用了 338 个神经元,因为这是确切的列数。神经网络在 82 次迭代时停止,不再继续。运行 50 次迭代,我在 R2 < 0.5 时获得了准确度,这并不令人印象深刻。

我的问题:

  1. 我是否正确处理分类特征的管理?有了上面的分数,模型 #1 和 #2 看起来是不是过拟合了?R2 > 0.94 非常好,测试和训练的准确性看起来都不错,而且在同一个球场,所以我不认为它是过度拟合的

  2. 为什么神经网络表现不佳?

  3. 我应该考虑使用不同类型的神经网络进行回归吗?

  4. 为什么我必须向 XGBoost (10,000) 添加这么多的估计器才能获得与随机森林 (100) 相同的性能?

  5. 什么是适合目的的神经网络来解决这个深度学习问题?我担心集成方法可能不合适,或者我做错了什么。

2个回答

一些想法:

  1. 正确处理分类特征:使用 one-hot 编码是一种有效的方法。其他方法包括目标编码(或平均编码)和散列技巧。关于何时选择哪种方法并没有真正的硬性规定。
  2. 神经网络性能不佳:我对神经网络没有太多经验,但我读过神经网络的输入应该以某种方式缩放——要么标准化,要么位于某个狭窄且一致的区间内。您还可以查看其他层结构 - 例如,您是否尝试过 Scikit-Learn 的默认值?
  3. 考虑不同类型的网络:根据上述(2)判断
  4. 更多估计器xgboost xgboost有许多参数需要微调。您还应该考虑xgboost使用线性回归作为默认回归任务,这意味着您的目标保险损失是正态分布的。在现实世界中通常情况并非如此,我们看到保险损失通常遵循 Tweedie 分布。xgboost提供 Tweedie 回归功能。
  5. 此问题的最佳神经网络:不确定,因为我对神经网络的经验有限。

关于MLPRegressor,您应该使用lbfgs优化器在小数据集上获得更好的结果。精度应达到 0.99。