线性回归分类python代码(不平衡数据加权逻辑回归)

逻辑回归不直接支持不平衡分类。所以,用于拟合逻辑回归模型的训练算法必须进行修改,以适用于偏态的类分布。这可以通过指定一个类权重参数来实现,该参数用来影响训练期间更新逻辑回归模型的系数。

加权可以减少对多数类样本误分的惩罚,而增加对少数类样本误分的惩罚。这样修改过的逻辑回归在不平衡数据分类上的表现会更好,通常称为成本敏感或加权逻辑回归。

在本教程中,您将发现用于不平衡分类的成本敏感逻辑回归。

本教程分为四个部分:

  • 不平衡分类数据集
  • 用于不平衡分类的加权逻辑回归
  • Scikit-Learn库中的加权逻辑回归
  • 网格搜索加权逻辑回归

线性回归分类python代码(不平衡数据加权逻辑回归)(1)

不平衡数据集

在我们修改逻辑回归以便用于不平衡分类之前,先定义一个非均衡分类数据集。我们可以用make_classification()函数来定义一个合成的不平衡的二分类数据集。我们将以1:100的比列生成10,000个少数类与多数类的样本。

# Generate and plot a synthetic imbalanced classification dataset from collections import counter from sklearn.datasets import make_classification from matplotlib import pyplot from numpy import where # define dataset X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=2) # summarize class distribution counter = Counter(y) print(counter) # scatter plot of examples by class label for label, _ in counter.items(): row_ix = where(y == label)[0] pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label)) pyplot.legend() pyplot.show()

Counter({0: 9900, 1: 100})

我们可以看到数据集的类分布近似为1:100,多数类的样本略小于10,000个,少数类的样本为100个。

接下来创建数据集的散点图,显示多数类(蓝色)的大量样本和少数类(橙色)的少量样本,其中有一些发生重叠。

线性回归分类python代码(不平衡数据加权逻辑回归)(2)

接下来,我们在数据集上拟合一个标准的逻辑回归模型。我们将使用重复交叉验证来评估模型,重复三次10倍交叉验证,模型性能指标选取ROC-AUC。

# fit a logistic regression model on an imbalanced classification dataset from numpy import mean from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.linear_model import logisticRegression # generate dataset X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=2) # define model model = LogisticRegression(solver='lbfgs') # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1) # summarize performance print('Mean ROC AUC: %.3f' % mean(scores))

运行示例对不平衡数据集上的标准逻辑回归模型进行评估,并报告ROC -AUC均值。我们可以看出,该模型有效,其ROC曲线下面积(AUC)在0.5以上,平均得分为0.985。

逻辑回归用于不平衡分类

逻辑回归是一种有效的二元分类任务模型,虽然在默认情况下,它对不平衡分类无效。但可以对Logistic回归进行修改,使其更适合于不平衡分类。

逻辑回归算法的系数是用一个优化算法来拟合的,该算法最小化模型在训练数据集上的负对数似然(损失)。即最小化sum i to n [-(log(yhat_i) * y_i log(1 - yhat_i) * (1 - y_i))]。这涉及到模型的迭代,根据减少模型损失的方向调整系数。

可以修改损失函数计算的方式,以将类别不平衡因素考虑在内。默认情况下,每个类的误分具有相同的权重,比如1.0。这些权重可以根据每个类别的重要性进行调整。

最小化sum i to n [ -(w0 * log(yhat_i) * y_i w1 * log(1 - yhat_i) * (1 - y_i))]

通过对损失函数进行加权,较小的权重值导致较小的损失,较少更新的模型系数。权重值越大,损失误差越大,对模型系数的更新也越大。

scikit-learn机器学习库提供了一个支持类加权逻辑回归的实现。LogisticRegression类提供了可以指定为模型超参数的class_weight参数。class_weight是一个字典,它定义了每个类标签(例如0和1)以及在拟合模型时应用于负对数似然计算的加权。

因此,逻辑回归的修正版本被称为加权逻辑回归、类别加权逻辑回归或成本敏感逻辑回归。权重有时被称为重要性权重。尽管实现起来很简单,但加权逻辑回归的挑战是为每个类选择权重。

加权逻辑回归

scikit-learn机器学习库提供了一个支持类加权逻辑回归的实现。LogisticRegression类提供了可以指定为模型超参数的class_weight参数。class_weight是一个字典,它定义了每个类标签(例如0和1)以及在拟合模型时应用于负对数似然计算的加权。

例如,每个类别0和1的1到1的权重可以按如下进行定义:

# define model weights = {0:1.0, 1:1.0} model = LogisticRegression(solver='lbfgs', class_weight=weights)

类别权重的定义方法有多种,例如:

  • 领域专家,通过与主题专家交谈确定。
  • 调优,由超参数搜索(如网格搜索)决定。
  • 启发式,使用最佳实践指定。

类加权的最佳实践是使用训练数据集中类分布比例的倒数。例如,训练数据集的类分布为少数类与多数类的比例是1:100。这个比例的倒数可以用做类权重,少数类:多数类为100:1。

# define model weights = {0:1.0, 1:100.0} model = LogisticRegression(solver='lbfgs', class_weight=weights)

我们可以使用前一节定义的相同的评估过程来评估类加权逻辑回归算法。我们期望类加权逻辑回归比标准的逻辑回归表现更好。

# weighted logistic regression model on an imbalanced classification dataset from numpy import mean from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.linear_model import LogisticRegression # generate dataset X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=2) # define model weights = {0:0.01, 1:1.0} model = LogisticRegression(solver='lbfgs', class_weight=weights) # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1) # summarize performance print('Mean ROC AUC: %.3f' % mean(scores))

Mean ROC AUC: 0.989

报告ROC-AUC平均得分,在这种情况下,加权逻辑回归比标准的逻辑回归表现更好,分别为0.989和0.985。

scikit-learn库提供了类加权的启发式实现。它是通过compute_class_weight()函数实现的,计算方法如下:

n_classes / (n_classes * n_samples_with_class)

我们可以在数据集上手动测试这个计算。例如,我们在数据集中有10,000个示例,类0有9900个,类1有100个。

第0类的权重计算如下:

weights = n_samples / (n_classes * n_samples_with_class)

权重= 10000 / (2 * 9900)

权重= 10000 / 19800

权重= 0.5

第1类的权重计算如下:

weights = n_samples / (n_classes * n_samples_with_class)

权重= 10000 / (2 * 100)

权重= 10000 / 200

权重= 50

我们可以通过调用compute_class_weight()函数并将class_weight指定为“balanced”来确认这些计算。例如:

# calculate heuristic class weighting from sklearn.utils.class_weight import compute_class_weight from sklearn.datasets import make_classification # generate 2 class dataset X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=2) # calculate class weighting weighting = compute_class_weight('balanced', [0,1], y) print(weighting)

[ 0.50505051 50. ]

运行这个例子,我们可以看到我们可以为类0实现约0.5的权重,为类1实现约50的权重。这些值与我们的手工计算相匹配。

我们还可以直接在LogisticRegression类中,直接通过将class_weight参数设置为' balanced ', 从而设置类权重。

# weighted logistic regression for class imbalance with heuristic weights from numpy import mean from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.linear_model import LogisticRegression # generate dataset X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=2) # define model model = LogisticRegression(solver='lbfgs', class_weight='balanced') # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1) # summarize performance print('Mean ROC AUC: %.3f' % mean(scores))

运行上面代码,发现结果与我们手动设置类别比的倒数所获的ROC AUC均值相同。

网格搜索加权逻辑回归

使用不同的类权重可能会获得更好的性能,这也取决于用于评估模型性能指标的选择。

在本节中,我们将对加权逻辑回归对不同类别权重进行网格搜索,并找出哪一种权重可以获得最佳的ROC曲线下面积(AUC)。

我们将为0和1类尝试以下权重:

{0:100, 1:1}

{0:10, 1:1}

{0:1, 1:1}

{0:1, 1:10}

{0:1, 1:10 0}

这些可以定义为GridSearchCV类的网格搜索参数,如下:

# define grid balance = [{0:100,1:1}, {0:10,1:1}, {0:1,1:1}, {0:1,1:10}, {0:1,1:100}] param_grid = dict(class_weight=balance)

我们可以使用重复交叉验证(RepeatedStratifiedKFold)对这些参数进行网格搜索,并使用ROC AUC估计模型性能:

# grid search class weights with logistic regression for imbalance classification from numpy import mean from sklearn.datasets import make_classification from sklearn.model_selection import GridSearchCV from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.linear_model import LogisticRegression # generate dataset X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=2) # define model model = LogisticRegression(solver='lbfgs') # define grid balance = [{0:100,1:1}, {0:10,1:1}, {0:1,1:1}, {0:1,1:10}, {0:1,1:100}] param_grid = dict(class_weight=balance) # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # define grid search grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=cv, scoring='roc_auc') # execute the grid search grid_result = grid.fit(X, y) # report the best configuration print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_)) # report all configurations means = grid_result.cv_results_['mean_test_score'] stds = grid_result.cv_results_['std_test_score'] params = grid_result.cv_results_['params'] for mean, stdev, param in zip(means, stds, params): print("%f (%f) with: %r" % (mean, stdev, param))

Best: 0.989077 using {'class_weight': {0: 1, 1: 100}} 0.982498 (0.016722) with: {'class_weight': {0: 100, 1: 1}} 0.983623 (0.015760) with: {'class_weight': {0: 10, 1: 1}} 0.985387 (0.013890) with: {'class_weight': {0: 1, 1: 1}} 0.988044 (0.010384) with: {'class_weight': {0: 1, 1: 10}} 0.989077 (0.006865) with: {'class_weight': {0: 1, 1: 100}}

在这种情况下,我们可以看到1:100多数对少数类加权获得了最好的ROC平均得分。这与一般启发式的配置相匹配。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页