【问题标题】:Is there a way to ensemble multiple logistic regression equations into one?有没有办法将多个逻辑回归方程组合成一个?
【发布时间】:2019-06-17 12:59:56
【问题描述】:

我正在研究响应率(不良)小于 1% 的二元分类问题。预测变量包括一组名义分类变量和连续变量。

最初,我尝试使用过采样技术 (SMOTE) 来平衡这两个类别。对过采样数据集执行逻辑回归会产生良好的整体准确度,但误报率非常高。

我现在计划进行欠采样并运行多个逻辑回归模型。我正在处理的基本python代码如下。需要指导将这些多元逻辑回归模型的结果合二为一。

import pandas as pd
import numpy as np
from sklearn import preprocessing
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
#Set i for the number of equations required
for i in range(10):
   #Create a sample of goods, good is pandas df containing goods
   sample_good=good.sample(n=300,replace=True)

   #Create a sample of bads, bad is pandas df containing bads. There are 
   #only 100 bads in the dataset
   sample_bad=bad.sample(n=100,replace=True)

   #Append the good and bad sample
   sample=sample_good.append(sample_bad)

   X = sample.loc[:, sample.columns != 'y']
   y = sample.loc[:, sample.columns == 'y']

   from sklearn.linear_model import LogisticRegression
   from sklearn import metrics
   X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, 
   random_state=0)
   logreg = LogisticRegression()
   logreg.fit(X_train, y_train)
   y_pred = logreg.predict(X_test)
   print('Accuracy of logistic regression classifier on test set: 
   {:.2f}'.format(logreg.score(X_test, y_test)))

上面的 for 循环运行了 10 次,构建了 10 个不同的模型。需要将这 10 个模型集成为一个模型的指导。我已经阅读了诸如装袋等可用技术。在这种情况下,由于响应率非常低,我创建的样本每次都需要有所有的坏处。

【问题讨论】:

    标签: python scikit-learn logistic-regression ensemble-learning


    【解决方案1】:

    我认为你应该使用 scikit-learn 的 BaggingClassifier。简而言之,它在数据的随机子样本上拟合多个分类器,然后让它们投票执行分类。这个元估计器将优雅地阻止您编写 for 循环。至于采样(我相信这是您编写循环的最初动机),您可以在 model.fit() 方法中调整权重。

    import numpy as np
    from sklearn.ensemble import BaggingClassifier
    from sklearn.linear_model import LogisticRegression
    from sklearn import datasets
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import balanced_accuracy_score
    
    breast_cancer = datasets.load_breast_cancer()
    X = breast_cancer.data
    y = breast_cancer.target
    X_train, X_test, y_train, y_test = train_test_split(X,y)
    

    如您所见,数据集是不平衡的(毕竟是医疗数据):

    len(y_train[y_train == 0]),len(y_train[y_train == 1]) # 163, 263
    

    因此,让我们添加样本权重

    y0 = len(y_train[y_train == 0])
    y1 = len(y_train[y_train == 1])
    
    w0 = y1/y0
    w1 = 1
    
    sample_weights = np.zeros(len(y_train))
    sample_weights[y_train == 0] = w0
    sample_weights[y_train == 1] = w1
    

    现在是 BaggingClassifier:

    model = BaggingClassifier(LogisticRegression(solver = 'liblinear'), 
                          n_estimators=10, 
                          bootstrap = True, random_state = 2019)
    model.fit(X,y,sample_weights)
    balanced_accuracy_score(y_test,model.predict(X_test)) # 94.2%
    

    请注意,如果我不适合样本权重,我只能得到 92.1% 的平衡准确率(平衡准确率 = 平均召回率,这对于不平衡问题非常方便)

    【讨论】:

    • 谢谢马克西姆,我一定会试一试的。还有几个问题,权重是如何工作的? w1=1 是否意味着将在每个 bagging 样本中选择训练集中的所有坏点? w0 = y0/y1 是如何工作的?每个装袋样品中有多少/什么比例的商品?
    • 假设你有 y0 = 100 和 y1 = 200。让 w0 和 w1 成为每个类的权重。我们必须有 y0.w0 = y1.w1。让我们任意设置 w1 =1(实际上你可以选择任何其他数字),那么你有 w0 = y1/y0。这意味着对于每个估计器,将使用这些权重从您的总数据中抽取随机样本(使用引导程序)。如果需要,可以将 max_features = 0.5 添加到 BaggingClassifier 函数中,这将限制每个子样本的大小为 50%。但是使用权重,它将确保每个子样本都有正确的分布
    • 感谢 Maxime 的解释。
    猜你喜欢
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 2011-06-21
    • 2019-06-09
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多