如何在相当平衡的二进制分类中修复非常高的漏报率?
How to fix a very high false negative rate in fairly balanced binary classification?
我有一个项目要求根据大约 52 个特征和 2000 行数据对员工是否会离开公司进行二元分类。数据在 1200 neg 到 800 pos 之间有些平衡。我做了广泛的 EDA 和数据清理。我选择尝试 sklearn、对数回归、SVM 和随机森林中的几种不同模型。我从他们那里得到的结果非常糟糕和相似。我只使用了 52 个特征中的 15 个 运行,但结果与我使用所有 52 个特征时几乎相同。在 52 个特征中,有 6 个是分类的,我将其转换为虚拟对象(每个特征 3-6 个类别),3 个是日期时间,我将其转换为自纪元以来的天数。没有要填充的空值。
这是我最近 运行 随机森林的代码和混淆矩阵。
x_train, x_test, y_train, y_test = train_test_split(small_features, endreason, test_size=0.2, random_state=0)
RF = RandomForestClassifier(bootstrap = True,
max_features = 'sqrt',
random_state=0)
RF.fit(x_train, y_train)
RF.predict(x_test)
cm = confusion_matrix(y_test, rf_predictions)
plot_confusion_matrix(cm, classes = ['Negative', 'Positive'],
title = 'Confusion Matrix')
我可以采取哪些步骤来帮助更好地适应这个模型?
对于你提出的方法和你描述的数据的平衡,你所展示的结果确实有点令人沮丧。但是,从问题的描述来看,确实有很大的改进空间。
当您使用 train_test_split
时,确保传递 stratify=endreason
以确保在拆分数据集时没有关于标签的问题。继续讨论有助于改进模型的要点:
首先,降维:由于您正在处理许多特征,因此其中一些可能无用甚至污染您试图解决的分类问题。考虑将不同的 dimension reduction 技术拟合到您的数据并使用此拟合数据来提供您的模型非常重要。一些可能值得尝试的常见方法:
- PCA(主成分分析)
- 低方差和相关性过滤器
- 随机森林特征重要性
其次了解模型:虽然逻辑回归可能被证明是线性分类器的优秀基线,但它可能不一定是这个任务你需要什么。 随机森林在捕获非线性关系时似乎要好得多,但需要进行控制和修剪以避免过度拟合并且可能需要大量数据.另一方面,SVM 是一种非常强大的非线性内核方法,但在处理大量数据时可能效率低下。 XGBoost 和 LightGBM 是非常强大的梯度提升算法,已经赢得了多个 kaggle 比赛并且几乎在所有情况下都工作得很好,当然需要有一些预处理如 XGBoost 没有准备好使用分类特征(LightGBM 是)。我的建议是尝试这最后两种方法。从最坏到最后(在一般情况下)我会列出:
- LightGBM/XGBoost
- 随机森林/支持向量机/逻辑回归
最后但同样重要的是超参数调整:无论您选择哪种方法,总会有一些微调需要完成。 Sklearn offers gridsearch which comes in really handy. However you would need to understand how your classifiers are behaving in order to know what should you be looking for. I will not go in-depth in this as it will be off-topic and not suited for SO but you can definitely have a read here
我有一个项目要求根据大约 52 个特征和 2000 行数据对员工是否会离开公司进行二元分类。数据在 1200 neg 到 800 pos 之间有些平衡。我做了广泛的 EDA 和数据清理。我选择尝试 sklearn、对数回归、SVM 和随机森林中的几种不同模型。我从他们那里得到的结果非常糟糕和相似。我只使用了 52 个特征中的 15 个 运行,但结果与我使用所有 52 个特征时几乎相同。在 52 个特征中,有 6 个是分类的,我将其转换为虚拟对象(每个特征 3-6 个类别),3 个是日期时间,我将其转换为自纪元以来的天数。没有要填充的空值。
这是我最近 运行 随机森林的代码和混淆矩阵。
x_train, x_test, y_train, y_test = train_test_split(small_features, endreason, test_size=0.2, random_state=0)
RF = RandomForestClassifier(bootstrap = True,
max_features = 'sqrt',
random_state=0)
RF.fit(x_train, y_train)
RF.predict(x_test)
cm = confusion_matrix(y_test, rf_predictions)
plot_confusion_matrix(cm, classes = ['Negative', 'Positive'],
title = 'Confusion Matrix')
我可以采取哪些步骤来帮助更好地适应这个模型?
对于你提出的方法和你描述的数据的平衡,你所展示的结果确实有点令人沮丧。但是,从问题的描述来看,确实有很大的改进空间。
当您使用 train_test_split
时,确保传递 stratify=endreason
以确保在拆分数据集时没有关于标签的问题。继续讨论有助于改进模型的要点:
首先,降维:由于您正在处理许多特征,因此其中一些可能无用甚至污染您试图解决的分类问题。考虑将不同的 dimension reduction 技术拟合到您的数据并使用此拟合数据来提供您的模型非常重要。一些可能值得尝试的常见方法:
- PCA(主成分分析)
- 低方差和相关性过滤器
- 随机森林特征重要性
其次了解模型:虽然逻辑回归可能被证明是线性分类器的优秀基线,但它可能不一定是这个任务你需要什么。 随机森林在捕获非线性关系时似乎要好得多,但需要进行控制和修剪以避免过度拟合并且可能需要大量数据.另一方面,SVM 是一种非常强大的非线性内核方法,但在处理大量数据时可能效率低下。 XGBoost 和 LightGBM 是非常强大的梯度提升算法,已经赢得了多个 kaggle 比赛并且几乎在所有情况下都工作得很好,当然需要有一些预处理如 XGBoost 没有准备好使用分类特征(LightGBM 是)。我的建议是尝试这最后两种方法。从最坏到最后(在一般情况下)我会列出:
- LightGBM/XGBoost
- 随机森林/支持向量机/逻辑回归
最后但同样重要的是超参数调整:无论您选择哪种方法,总会有一些微调需要完成。 Sklearn offers gridsearch which comes in really handy. However you would need to understand how your classifiers are behaving in order to know what should you be looking for. I will not go in-depth in this as it will be off-topic and not suited for SO but you can definitely have a read here