用Scikit-Learn进行Logistic回归

139 阅读4分钟

用Scikit-Learn进行Logistic回归

2022年5月22日数据 编码 机器学习 python

分享到。

目录

绪论

Logistic回归是一种机器学习模型,它有助于预测一个事件(称为 "类")的概率。

在本教程中,我们将使用Scikit-Learn及其逻辑回归基元,根据睡眠时间和觉醒次数来预测一夜好眠的可能性。

输入

1import numpy as np
2import pandas as pd
3import matplotlib.pyplot as plt
4from sklearn.model_selection import train_test_split
5from sklearn.preprocessing import MinMaxScaler
6from sklearn.linear_model import LogisticRegression
7
8plt.rcParams['figure.figsize'] = [8, 7]
9plt.rcParams['figure.dpi'] = 100

Logistic回归模型

逻辑回归是一种模型,与常规的线性回归不同,它有助于预测某一类(如下雨)为真的概率,为1和0之间的数字。

X -> y,其中1.0 >= y >= 0.0

在典型的二元或二项分类中,特征与真值假值有关,而不是连续值。结果从绝对真实(1.0)到绝对虚假(0.0)。

让我们开始行动吧。让我们考虑一个数据集,其中患有睡眠问题的病人报告他们睡了多少小时,晚上醒了多少次,然后,早上感觉如何,作为 "睡眠不好"(False)或 "睡眠好"(True)。

 1np.random.seed(3)
 2sleep_hours = np.linspace(1,9,100)
 3awakenings  = np.random.randint(1,6,size=1001) 
 4sleep_q     = [ 6 + h + (np.random.rand()*3) - a
 5                for (h,a) in zip(sleep_hours,awakenings) ]
 6X           = np.array([ [h,a] for (h,a) in zip(sleep_hours,awakenings) ])
 7y           = [ q >= 12 for q in sleep_q ]
 8
 9good = [ (h,a) for (h,a,y) in zip(sleep_hours,awakenings,y) if y]
10bad  = [ (h,a) for (h,a,y) in zip(sleep_hours,awakenings,y) if not y]
11
12plt.scatter([ t[0] for t in good ], [ t[1] for t in good ],color='b',label='Slept Well') 
13plt.scatter([ t[0] for t in bad ], [ t[1] for t in bad ],color='r',label='Slept Badly') 
14plt.legend(loc='upper left')
15plt.xlabel('Sleep Hours')
16plt.ylabel('Awakenings')
17plt.yticks([1,2,3,4,5])
18plt.show()

在这个例子中,我们不会把数据集分成训练集和测试集,而是在整个数据集上训练模型。

1model = LogisticRegression().fit(X, y)

就这样了。我们现在可以审问这个数字了。常规的predict() 方法返回类,在本例中是一个bool 答案,而不是一个float 值。我们使用precit_proba() ,而不是获得每个类别的实际概率(在我们的例子中是False ,和True )。

**例1:**病人睡了3.2小时,醒了0次。他的睡眠好吗?

1model.predict([[3.2,0]])
array([False])
1model.predict_proba([[3.2,0]])
array([[0.89892622, 0.10107378]])

**例2:**病人睡了8小时,但醒了10次。她的睡眠好吗?

1model.predict([[8.0,10]])
array([False])
1model.predict_proba([[8.0,10]])
array([[9.99984809e-01, 1.51910314e-05]])

**例3:**病人睡了10个小时,醒了0次。她的睡眠质量好吗?

1model.predict([[10.0,0]])
array([ True])
1model.predict_proba([[10.0,0]])
array([[2.42600004e-04, 9.99757400e-01]])

在这组数据中,尽管是合成的,但有趣的是注意到觉醒的次数是如何影响晚上睡得好的机会的。这就是predict_proba() 产生的概率值的闪光之处。

 1def probability(awakenings):
 2    zero = [ [h,model.predict_proba([[h,awakenings]])[0][1]] 
 3            for h in np.linspace(0,12,12) ]
 4    plt.plot([t[0] for t in zero], [t[1] for t in zero]) 
 5    if awakenings >= 3:
 6        plt.xlabel("Sleep hours")
 7    if awakenings in [0,3]:
 8        plt.ylabel("Sleep well probability")
 9    plt.yticks([0.0,0.2,0.4,0.6,0.8,1])
10    plt.xticks([0,2,4,6,8,10,12])
11    plt.title("# Awakenings = {}".format(awakenings))
12    
13for x in range (0,6):
14    plt.subplot(2, 3, x+1)    
15    probability(x)

正则化

逻辑回归使用的是线性模型,它可以被规范化,就像产生连续值的常规回归模型一样。让我们先看一下我们正在研究的模型的类别边界,没有任何附加的惩罚措施。

 1def show_class_boundary(models):
 2    plt.scatter([ t[0] for t in good ], [ t[1] for t in good ],color='b',label='Slept Well') 
 3    plt.scatter([ t[0] for t in bad ], [ t[1] for t in bad ],color='r',label='Slept Badly') 
 4    plt.xlabel('Sleep Hours')
 5    plt.ylabel('Awakenings')
 6    plt.yticks([1,2,3,4,5])
 7    for i,m in enumerate(models):
 8        class_boundary = [ (h,a) 
 9                            for h in np.linspace(0,10,200) 
10                            for a in np.linspace(0,6,200)
11                            if abs((m.predict_proba([[h,a]])[0][1])-0.5)
12                                  <= 0.001 ]
13        plt.plot([ t[0] for t in class_boundary ], [ t[1] for t in class_boundary ],label="Class Boundary {}".format(i+1))
14    plt.legend(loc='upper left')
15    
16show_class_boundary([model])
17

在上面的可视化图中,我们可以看到类的边界线至少包括一个红点。在现实世界中,这个模型实际上是几乎完美的,因为我们提供的合成数据集实际上是线性的。但是,假设我们希望这个逻辑回归的工作方式是,如果预测是真的,(病人睡得好),那么,就没有任何机会出现假阳性。

实现这一目标的方法是通过使用C 参数添加一个惩罚(默认为L2,但也可以选择L1)。在下面的例子中,我们设置了C=0.2 ,其效果是将类的边界向右推,使其不再覆盖红点。

1model2 = LogisticRegression(C=0.2).fit(X, y)
2show_class_boundary([model,model2])

我们提供的惩罚是很小的,所以它不会改变分数,因为它已经接近100%了。

1display(model.score(X, y))
2display(model2.score(X, y))
0.96



0.96

结论

Logistic回归是最简单的 "分类 "模型之一,当类之间的分离在某种程度上是线性的时候,它是最有用的。在未来的教程中,我们将探讨如何处理那些排列似乎更加随意的类。

在你离开之前

🤘 订阅我的100%无垃圾邮件的时事通讯!

电子邮件。