python:如何在sklearn中使用逻辑回归系数构建决策边界

Posted

技术标签:

【中文标题】python:如何在sklearn中使用逻辑回归系数构建决策边界【英文标题】:python: how to use logistic regression coefficients to construct decision boundary in sklearn 【发布时间】:2018-04-30 17:58:47 【问题描述】:

我正在尝试在 sklearn 中做更多的事情。在这里,我试图生成一个不平衡的分类集,运行逻辑回归,绘制数据点并绘制决策边界线。

为了绘制决策边界线,我先得到系数:

coef = clf.best_estimator_.coef_
intercept = clf.best_estimator_.intercept_

然后我构造这条线:

x1 = np.linspace(-8, 10, 100)
x2 = -(coef[0][0] * x1 + intercept[0]) / coef[0][1]
plt.plot(x1, x2, color='#414e8a', linewidth=2)

但是,这条线没有绘制,因为 x2 都是 inf 因为 coef[0][1] 等于 0。这是我遇到的问题。为什么这些系数的第二项是0?

完整代码如下:

from sklearn.datasets import make_classification
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import KFold, train_test_split
import numpy as np
import pandas as pd
import warnings

warnings.filterwarnings('ignore')
%pylab inline
pylab.rcParams['figure.figsize'] = (12, 6)
plt.style.use('fivethirtyeight')
from IPython.core.display import display, html
display(HTML("<style>.container  width:100% !important; </style>"))

# Generate data with two classes
X, y = make_classification(class_sep=1.2, weights=[0.1, 0.9], n_informative=3, n_redundant=1, n_features=5, n_clusters_per_class=1, n_samples=10000, flip_y=0, random_state=10)
pca = PCA(n_components=2)
X = pca.fit_transform(X)

y = y.astype('str')
y[y=='1'] ='L'
y[y=='0'] ='S'

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, random_state=0)

X_1, X_2 = X_train[y_train=='S'], X_train[y_train=='L']

# Fit a Logistic Regression model
clf_base = LogisticRegression()
grid = 'C': 10.0 ** np.arange(-2, 3),'penalty': ['l1', 'l2']
cv = KFold(X_train.shape[0], n_folds=5, shuffle=True, random_state=0)
clf = GridSearchCV(clf_base, grid, cv=cv, n_jobs=8, scoring='f1_macro')
clf.fit(X_train, y_train)

# Get coefficients
coef = clf.best_estimator_.coef_
intercept = clf.best_estimator_.intercept_

# Create separation line
x1 = np.linspace(-8, 10, 100)
x2 = -(coef[0][0] * x1 + intercept[0]) / coef[0][1]

plt.scatter(X_1[:,0], X_1[:,1], color='#1abc9c')
plt.scatter(X_2[:,0], X_2[:,1], color='#e67e22')
x_coords = np.concatenate([X_1[:,0],X_2[:,0]])
y_coords = np.concatenate([X_1[:,1],X_2[:,1]])
plt.axis([min(x_coords), max(x_coords), min(y_coords), max(y_coords)])
plt.title("Original Dataset - Fitted Logistic Regression")
plt.plot(x1, x2, color='#414e8a', linewidth=2)
plt.show()

print(coef)

如你所见,coef 中的第二项是 0。

我在这里做错了什么?

谢谢!

编辑

似乎网格搜索参数导致第二个系数为零。例如:

当我将网格参数设置为:

grid = 'C': 10.0 ** np.arange(-2, 3),'penalty': ['l1', 'l2'],'class_weight': ['balanced']

这给了我两个非零系数

当我删除类权重参数时:

grid = 'C': 10.0 ** np.arange(-2, 3),'penalty': ['l1', 'l2']

这给了我 coef 中第二个元素的零。

希望能简化问题。有人有想法吗?谢谢!

【问题讨论】:

逻辑回归 我不关注? 【参考方案1】:

您的第一系数为零,因为您使用了 strong L1 正则化,它从模型中删除了所有不那么有用的特征。

您可以使用 clf.best_params_ 查看它 - 它等于 'C': 0.01, 'penalty': 'l1'。切换到“l2”惩罚,您将获得所有非零系数。

如果你想绘制任意一行Ax+By+C=0,你可以使用这个函数:

import matplotlib.pyplot as plt
import numpy as np

def plot_normal_line(A, B, C, ax=None, **kwargs):
    """ Plot equation of Ax+By+C=0"""
    if ax is None:
        ax = plt.gca()
    if A == 0 and B == 0:
        raise Exception('A or B should be non-zero')
    if B == 0:
        # plot vertical
        ax.vlines(-C / A, *ax.get_ylim(), **kwargs)
    else:
        # plot functoon
        x = np.array(ax.get_xlim())
        y = (A*x+C) / -B
        ax.plot(x, y, **kwargs)

然后命令plot_normal_line(*coef[0], intercept) 将绘制您的决策边界。

但是,由于您的数据集是平衡的,因此对于几乎所有点,最可能的类别是第二类(橙色)。因此 50% 概率的决策边界(粗黑线)位于散点图的左侧:

【讨论】:

以上是关于python:如何在sklearn中使用逻辑回归系数构建决策边界的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中使用 sklearn 对连续数据进行逻辑回归

sklearn Python 和逻辑回归

Python Sklearn 线性回归产生不正确的系数值

使用 sklearn 在 python 中执行逻辑回归分析

Python SKLearn 逻辑回归中的虚拟变量

python使用sklearn中的make_regression函数生成回归分析需要的仿真数据使用pandas查看生成数据的特征数据目标数据(target)以及数据每个特征的实际系数值