尽管投了反对票,但问题很明确,而且我敢肯定,在做了一段时间的机器学习工作后,最常见的问题是。
目标是从多个经过训练的模型中制作出更强大的预测模型。
引用我的问题:
是否可以将这 30 个拟合模型聚合成一个模型?
答:是的,但是没有好的功能可以让您在 sklearn 中执行此操作。
详细回答:
假设您有 30 个 CSV 文件,其中包含 15,000 个0
类和 15,000 个1
类样本。换句话说,二元响应的数量相等(没有类别不平衡)。我自己生成了这些文件,因为 1)我正在使用的数据太大而无法放入内存(我原来问题的第 1 点)和 2)包含 97% 的类0
和 3% 的类1
(大类不平衡) . 我的目标是看看如果类不平衡问题已从等式中删除,是否甚至可以区分 a0
或 a 。1
如果发现了显着特征,我想知道这些特征是什么。
为了生成每个批次,我抓取了 15,000 个1
响应,并从另外 97% 的 15,000 个样本中随机抽样,加入一个数据集(总共 30,000 个样本),然后随机打乱它们。
然后,我检查了每个批次并使用从 GridSearchCV() 中找到的最佳参数训练了一个 XGBClassifier()。然后我将模型保存到磁盘(使用 Python 的 pickle 功能)。
此时,您已保存 30 个模型。
/models/
目录如下所示:
['model_0.pkl', 'model_1.pkl', 'model_10.pkl', 'model_11.pkl', 'model_12.pkl',
'model_13.pkl', 'model_14.pkl', 'model_15.pkl', 'model_16.pkl', 'model_17.pkl',
'model_18.pkl', 'model_19.pkl', 'model_2.pkl', 'model_20.pkl', 'model_21.pkl',
'model_22.pkl', 'model_23.pkl', 'model_24.pkl', 'model_25.pkl', 'model_26.pkl',
'model_27.pkl', 'model_28.pkl', 'model_29.pkl', 'model_3.pkl', 'model_4.pkl',
'model_5.pkl', 'model_6.pkl', 'model_7.pkl', 'model_8.pkl', 'model_9.pkl']
再次回到最初的问题——是否可以将这些聚合成一个模型?我为此编写了一个非常基本的 python 函数。
def xgb_predictions(X):
''' returns predictions from 30 saved models '''
predictions = {}
for pkl_file in os.listdir('./models/'):
file_num = int(re.search(r'\d+', pkl_file).group())
xgb = pickle.load(open(os.path.join('models', pkl_file), mode='rb'))
y_pred = xgb.predict(X)
predictions[file_num] = y_pred
new_df = pd.DataFrame(predictions)
new_df = new_df[sorted(new_df.columns)]
return new_df
它遍历保存模型目录中的每个文件,并一次加载一个文件,从而投出自己的“投票”。最终结果是一个新的预测数据框。
由于这个新数据集更小(X.shape x 30),它将适合内存。我遍历每个批处理文件调用xgb_predictions(X)
,获取预测数据框,将y
列添加到数据框,并将其附加到新文件中。然后,我阅读了完整的预测数据集并创建了一个“2 级”模型实例,其中X
预测数据y
仍然是y
.
回顾一下,这个概念是,对于二元分类,创建同样平衡的类数据集,在每个数据集上训练一个模型,遍历每个数据集并让每个训练的模型进行预测。在某种程度上,这个预测集合是原始数据集的转换版本。您构建另一个模型来尝试和预测y
给定的预测数据集。全部在内存中进行训练,最终得到一个模型。任何时候您想预测,您都可以获取数据集,将其转换为预测,然后使用您的 2 级训练模型来进行最终预测。
这种技术比任何其他单一模型表现得更好,甚至与未经训练的先前模型叠加。