数据科学和人工智能技术笔记 十二、逻辑回归

十二、逻辑回归

作者:Chris Albon

译者:飞龙

协议:CC BY-NC-SA 4.0

C 超参数快速调优

有时,学习算法的特征使我们能够比蛮力或随机模型搜索方法更快地搜索最佳超参数。

scikit-learn 的LogisticRegressionCV方法包含一个参数C。 如果提供了一个列表,C是可供选择的候选超参数值。 如果提供了一个整数,C的这么多个候选值,将从 0.0001 和 10000 之间的对数标度(C的合理值范围)中提取。

# 加载库
from sklearn import linear_model, datasets

# 加载数据
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 创建逻辑回归的交叉验证
clf = linear_model.LogisticRegressionCV(Cs=100)

# 训练模型
clf.fit(X, y)

'''
LogisticRegressionCV(Cs=100, class_weight=None, cv=None, dual=False,
           fit_intercept=True, intercept_scaling=1.0, max_iter=100,
           multi_class='ovr', n_jobs=1, penalty='l2', random_state=None,
           refit=True, scoring=None, solver='lbfgs', tol=0.0001, verbose=0) 
'''

在逻辑回归中处理不平衡类别

像 scikit-learn 中的许多其他学习算法一样,LogisticRegression带有处理不平衡类的内置方法。 如果我们有高度不平衡的类,并且在预处理期间没有解决它,我们可以选择使用class_weight参数来对类加权,确保我们拥有每个类的平衡组合。 具体来说,balanced参数会自动对类加权,与其频率成反比:

w_j = \frac{n}{kn_{j}}

其中 w_j 是类 j 的权重,n 是观察数,n_j 是类 j 中的观察数,k 是类的总数。

# 加载库
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
import numpy as np

# 加载数据
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 通过移除前 40 个观测,使类高度不均衡
X = X[40:,:]
y = y[40:]

# 创建目标向量,如果表示类别是否为 0
y = np.where((y == 0), 0, 1)

# 标准化特征
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 创建决策树分类器对象
clf = LogisticRegression(random_state=0, class_weight='balanced')

# 训练模型
model = clf.fit(X_std, y)

逻辑回归

尽管其名称中存在“回归”,但逻辑回归实际上是广泛使用的二分类器(即,目标向量只有两个值)。 在逻辑回归中,线性模型(例如 \beta_{0} + \beta_ {1} x)包含在 logit(也称为 sigmoid)函数中,{\frac{1}{1 + e^{-z}},满足:

P(y_i=1 \mid X)={\frac{1}{1+e^{-(\beta_{0}+\beta_{1}x)}}}

其中 P(y_i=1 \mid X) 是第 i 个观测的目标值 y_i 为 1 的概率,X 是训练数据,\beta_0\beta_1 是要学习的参数,e 是自然常数。

# 加载库
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

# 加载只有两个类别的数据
iris = datasets.load_iris()
X = iris.data[:100,:]
y = iris.target[:100]

# 标准化特征
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 创建逻辑回归对象
clf = LogisticRegression(random_state=0)

# 训练模型
model = clf.fit(X_std, y)

# 创建新的观测
new_observation = [[.5, .5, .5, .5]]

# 预测类别
model.predict(new_observation)

# array([1]) 

# 查看预测的概率
model.predict_proba(new_observation)

# array([[ 0.18823041,  0.81176959]]) 

大量数据上的逻辑回归

scikit-learn 的LogisticRegression提供了许多用于训练逻辑回归的技术,称为求解器。 大多数情况下,scikit-learn 会自动为我们选择最佳求解器,或警告我们,你不能用求解器做一些事情。 但是,我们应该注意一个特殊情况。

虽然精确的解释超出了本书的范围,但随机平均梯度下降使得我们在数据非常大时,比其他求解器更快训练模型。 但是,对特征尺度也非常敏感,标准化我们的特征尤为重要。 我们可以通过设置solver ='sag'来设置我们的学习算法来使用这个求解器。

# 加载库
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

# 加载数据
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 标准化特征
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 创建使用 SAG 求解器的逻辑回归
clf = LogisticRegression(random_state=0, solver='sag')

# 训练模型
model = clf.fit(X_std, y)

带有 L1 正则化的逻辑回归

L1 正则化(也称为最小绝对误差)是数据科学中的强大工具。 有许多教程解释 L1 正则化,我不会在这里尝试这样做。 相反,本教程将展示正则化参数C对系数和模型精度的影响。

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

本教程中使用的数据集是着名的鸢尾花数据集。鸢尾花数据包含来自三种鸢尾花y,和四个特征变量X的 50 个样本。

数据集包含三个类别(三种鸢尾),但是为了简单起见,如果目标数据是二元的,则更容易。因此,我们将从数据中删除最后一种鸢尾。

# 加载鸢尾花数据集
iris = datasets.load_iris()

# 从特征中创建 X
X = iris.data

# 从目标中创建 y
y = iris.target

# 重新生成变量,保留所有标签不是 2 的数据
X = X[y != 2]
y = y[y != 2]

# 查看特征
X[0:5]

'''
array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3\. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2],
       [ 4.6,  3.1,  1.5,  0.2],
       [ 5\. ,  3.6,  1.4,  0.2]]) 
'''

# 查看目标数据
y

'''
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1]) 
'''

# 将数据拆分为测试和训练集
# 将 30% 的样本放入测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

因为正则化惩罚由系数的绝对值之和组成,所以我们需要缩放数据,使系数都基于相同的比例。

# 创建缩放器对象
sc = StandardScaler()

# 将缩放器拟合训练数据,并转换
X_train_std = sc.fit_transform(X_train)

# 将缩放器应用于测试数据
X_test_std = sc.transform(X_test)

L1 的用处在于它可以将特征系数逼近 0,从而创建一种特征选择方法。 在下面的代码中,我们运行带有 L1 惩罚的逻辑回归四次,每次都减少了C的值。 我们应该期望随着C的减少,更多的系数变为 0。

C = [10, 1, .1, .001]

for c in C:
    clf = LogisticRegression(penalty='l1', C=c)
    clf.fit(X_train, y_train)
    print('C:', c)
    print('Coefficient of each feature:', clf.coef_)
    print('Training accuracy:', clf.score(X_train, y_train))
    print('Test accuracy:', clf.score(X_test, y_test))
    print('')

'''
C: 10
Coefficient of each feature: [[-0.0855264  -3.75409972  4.40427765  0\.        ]]
Training accuracy: 1.0
Test accuracy: 1.0

C: 1
Coefficient of each feature: [[ 0\.         -2.28800472  2.5766469   0\.        ]]
Training accuracy: 1.0
Test accuracy: 1.0

C: 0.1
Coefficient of each feature: [[ 0\.         -0.82310456  0.97171847  0\.        ]]
Training accuracy: 1.0
Test accuracy: 1.0

C: 0.001
Coefficient of each feature: [[ 0\.  0\.  0\.  0.]]
Training accuracy: 0.5
Test accuracy: 0.5 
'''

注意,当C减小时,模型系数变小(例如,从C = 10时的4.36276075变为C = 0.1时的0.0.97175097),直到C = 0.001,所有系数都是零。 这是变得更加突出的,正则化惩罚的效果。

OVR 逻辑回归

逻辑回归本身只是二分类器,这意味着它们无法处理具有两个类别以上的目标向量。 但是,逻辑回归有一些聪明的扩展来实现它。 在 One-VS-Rest(OVR)逻辑回归中,针对每个类别训练单独的模型,预测观测是否是该类(因此使其成为二分类问题)。 它假定每个分类问题(例如是不是类 0)是独立的。

# 加载库
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

# 加载数据
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 标准化特征
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 创建 OVR 逻辑回归对象
clf = LogisticRegression(random_state=0, multi_class='ovr')

# 训练模型
model = clf.fit(X_std, y)

# 创建新的观测
new_observation = [[.5, .5, .5, .5]]

# 预测类别
model.predict(new_observation)

# array([2]) 

# 查看预测概率
model.predict_proba(new_observation)

# array([[ 0.0829087 ,  0.29697265,  0.62011865]]) 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容