逻辑回归、Softmax回归 --- 鸢尾花分类

目录

1.逻辑回归

一些回归算法也可用于分类。
逻辑回归(Logistic回归,也称为Logit回归)被广泛用于估算一个实例属于某个特定类别的概率
比如,这封电子邮件属于垃圾邮件的概率是多少?
如果预估概率超过50%,则判定该邮件属于垃圾邮件,标记为“1”,反之,标记为“0”。这样它就成了一个二元分类器

与线性回归模型一样,逻辑回归模型也是计算输入特征的加权和(加上偏置项)
但是不同于线性回归模型直接输出结果,它输出的是结果的概率

σ(·)是一个sigmoid函数,输出一个介于0和1之间的数字。 该函数图像如下。
当t<0时,σ(t)<0.5,模型预测结果是0
当t≥0时,σ(t)≥0.5,模型预测结果是1

 

2.成本函数

当t接近于0时,-log(t)会变得非常大,所以如果模型估算一个正类实例的概率接近于0,成本将会变得很高。
同理估算出一个负类实例的概率接近1,成本也会变得非常高。
当t接近于1的时候,-log(t)接近于0,所以对一个负类实例估算出的概率接近于0。
对一个正类实例估算出的概率接近于1,而成本则都接近于0。

整个训练集的成本函数是所有训练实例的平均成本。 

这个函数没有已知的闭式方程来计算出最小化成本函数的θ值。
但是,这是个凸函数,所以通过梯度下降(或是其他任意优化算法)保证能够找出全局最小值。

成本函数关于第j个模型参数θj的偏导数方程 

对于每个实例,它都会计算预测误差并将其乘以第j个特征值,然后计算所有训练实例的平均值。一旦你有了包含所有偏导数的梯度向量就可以使用梯度下降算法了。 

3.举例:鸢尾植物数据集

这是一个著名的数据集,共有150朵鸢尾花,分别来自三个不同品种(山鸢尾、变色鸢尾和维吉尼亚鸢尾),数据里包含花的萼片以及花瓣的长度宽度

我们试试仅基于花瓣宽度这一个特征,创建一个分类器来检测维吉尼亚鸢尾花。 

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.linear_model import LogisticRegression

iris = datasets.load_iris() # 加载数据
list(iris.keys()) # ['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module']

X = iris["data"][:, 3:]  # 花瓣长度
y = (iris["target"] == 2).astype(np.int32)  # 标签,是维吉尼亚鸢尾花y就是1,否则为0

log_reg = LogisticRegression(solver="lbfgs", random_state=42)
log_reg.fit(X, y) # 训练模型

看看花瓣宽度在0到3cm之间的鸢尾花,模型估算出的概率

# 绘制预测图像
X_new = np.linspace(0, 3, 1000).reshape(-1, 1)
y_proba = log_reg.predict_proba(X_new)
plt.plot(X_new, y_proba[:, 1], "g-", linewidth=2, label="Iris virginica")
plt.plot(X_new, y_proba[:, 0], "b--", linewidth=2, label="Not Iris virginica")
plt.xlabel("Petal width (cm)", fontsize=14)
plt.ylabel("Probability", fontsize=14)
plt.legend(loc="center left", fontsize=14)
plt.show()

维吉尼亚鸢尾的花瓣宽度范围为1.4~2.5cm,而其他两种鸢尾花的花瓣宽度范围为0.1~1.8cm。注意,这里有一部分重叠。
在大约1.6cm处存在一个决策边界,这里“是”和“不是”的可能性都是50%,如果花瓣宽度大于1.6cm,分类器就预测它是维吉尼亚鸢尾花,否则就预测不是。

log_reg.predict([[1.7], [1.5]]) # 输出:array([1, 0], dtype=int32)

花瓣宽度花瓣长度这两个特征来预测新花朵是否属于维吉尼亚鸢尾

虚线表示模型估算概率为50%的点,即模型的决策边界。
每条平行线都分别代表一个模型输出的特定概率,从左下的15%到右上的90%。
根据这个模型,右上线之上的所有花朵都有超过90%的概率属于维吉尼亚鸢尾。 

from sklearn.linear_model import LogisticRegression

X = iris["data"][:, (2, 3)]  # 花瓣长度和宽度两个特征
y = (iris["target"] == 2).astype(np.int32)
log_reg = LogisticRegression(solver="lbfgs", C=10**10, random_state=42)
log_reg.fit(X, y) # 训练模型

x0, x1 = np.meshgrid(
        np.linspace(2.9, 7, 500).reshape(-1, 1),
        np.linspace(0.8, 2.7, 200).reshape(-1, 1),
    )
X_new = np.c_[x0.ravel(), x1.ravel()]
y_proba = log_reg.predict_proba(X_new)

plt.figure(figsize=(10, 4))
plt.plot(X[y==0, 0], X[y==0, 1], "bs")
plt.plot(X[y==1, 0], X[y==1, 1], "g^")

zz = y_proba[:, 1].reshape(x0.shape)
contour = plt.contour(x0, x1, zz, cmap=plt.cm.brg)
# 模型的决策边界。这是点x的集合,使得θ0+θ1x1+θ2x2=0,它定义了一条直线。
left_right = np.array([2.9, 7])
boundary = -(log_reg.coef_[0][0] * left_right + log_reg.intercept_[0]) / log_reg.coef_[0][1]

plt.clabel(contour, inline=1, fontsize=12)
plt.plot(left_right, boundary, "k--", linewidth=3)
plt.text(3.5, 1.5, "Not Iris virginica", fontsize=14, color="b", ha="center")
plt.text(6.5, 2.3, "Iris virginica", fontsize=14, color="g", ha="center")
plt.xlabel("Petal length", fontsize=14)
plt.ylabel("Petal width", fontsize=14)
plt.axis([2.9, 7, 0.8, 2.7])
plt.show()

4.Softmax回归

逻辑回归模型经过推广,可以直接支持多个类别,而不需要训练并组合多个二元分类器。这就是Softmax回归,或者叫作多元逻辑回归

原理:给定一个实例x,Softmax回归模型首先计算出每个类k的分数s_{k}(),然后对这些分数应用softmax函数(也叫归一化指数),估算出每个类的概率。

通过softmax函数来估计实例属于类k的概率\widehat{p} 
s_{k}()函数x计算了实例属于k类的分数,然后计算每个分数的指数,然后对其进行归一化(除以所有指数的总和)。

 

Softmax回归分类器预测具有最高估计概率的类 

 

argmax运算符返回使函数最大化的变量值。
在此等式中,它返回使估计概率σ(s(x))k最大化的k值。 
Softmax回归分类器一次只能预测一个类。

成本函数(也叫作交叉熵)

交叉熵经常被用于衡量一组估算出的类概率目标类匹配程度,训练目标就是最小化交叉熵

 

y_{k}^{(i)}是属于类k的第i个实例的目标概率。一般而言等于1或0,具体取决于实例是否属于该类。
当只有两个类(K=2)时,此成本函数等效于逻辑回归的成本函数(公式见上)

现在,你可以计算每个类的梯度向量,然后使用梯度下降(或任何其他优化算法)来找到最小化成本函数的参数矩阵Θ。

X = iris["data"][:, (2, 3)]  # 花瓣长度, 花瓣宽度
y = iris["target"]
# 设置超参数multi_class为"multinomial",指定一个支持Softmax回归的求解器,默认使用l2正则化,可以通过超参数C进行控制
softmax_reg = LogisticRegression(multi_class="multinomial", solver="lbfgs", C=10, random_state=42)
softmax_reg.fit(X, y)

如果一朵鸢尾花,花瓣长5cm宽2cm,模型可以告诉你它的种类是每个种类的概率

softmax_reg.predict([[5, 2]]) # 输出:array([2])
softmax_reg.predict_proba([[5, 2]]) 
# 输出:array([[6.38014896e-07, 5.74929995e-02, 9.42506362e-01]])
# 分别对应:山鸢尾、变色鸢尾和维吉尼亚鸢尾

 绘图

x0, x1 = np.meshgrid(
        np.linspace(0, 8, 500).reshape(-1, 1),
        np.linspace(0, 3.5, 200).reshape(-1, 1),
    )
X_new = np.c_[x0.ravel(), x1.ravel()]

y_proba = softmax_reg.predict_proba(X_new)
y_predict = softmax_reg.predict(X_new)

zz1 = y_proba[:, 1].reshape(x0.shape)
zz = y_predict.reshape(x0.shape)

plt.figure(figsize=(10, 4))
plt.plot(X[y==2, 0], X[y==2, 1], "g^", label="Iris virginica")
plt.plot(X[y==1, 0], X[y==1, 1], "bs", label="Iris versicolor")
plt.plot(X[y==0, 0], X[y==0, 1], "yo", label="Iris setosa")

from matplotlib.colors import ListedColormap
custom_cmap = ListedColormap(['#fafab0','#9898ff','#a0faa0'])

plt.contourf(x0, x1, zz, cmap=custom_cmap)
contour = plt.contour(x0, x1, zz1, cmap=plt.cm.brg)
plt.clabel(contour, inline=1, fontsize=12)
plt.xlabel("Petal length", fontsize=14)
plt.ylabel("Petal width", fontsize=14)
plt.legend(loc="center left", fontsize=14)
plt.axis([0, 7, 0, 3.5])
plt.show()

任何两个类之间的决策边界都是线性的。 
在所有决策边界相交的地方,所有类的估算概率都为33% 。

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你在学习Python数据分析的时候,是否遇到过在这些问题? 别慌!这些都是数据科学入门常见问题。从入门到上手再到解决实际问题,数据科学看似复杂,但如果你掌握了正确的学习方法,完全可以极速入门。 【职场人进阶必备  数据分析/挖掘一点通】 如今的职场上,90%以上的岗位都会涉及数据问题。 以产品文案岗位为例,在一个新产品推向市场之前,文案需要考虑: 此时,可以关注一下市场上已有的相关产品推广数据,如:哪些文案打开率更高?哪些文案转化更好?目标用户的购买习惯如何? 以此作为下一步工作开展的依据,对产品文案工作者来说,可以少走很多弯路。 学会数据分析/挖掘,等于站巨人的肩膀上工作,轻松且高效。 【爬虫、数据分析、数据挖掘知识点三合一】数据问题一网打尽 本课程将知识点悉数融入实战项目,不空谈语法,帮助学员在实践中获取知识,目标是:让学员能自主完成数据采集、数据分析与数据挖掘。 学习完本课程,你可以熟练掌握: 【实战案例超实用,轻松拥有“睡后收入”!】 本课程以股票案例为主线,串联爬虫、数据分析以及数据挖掘多个知识点。 通过实战案例演练,你可以全面掌握股票收益的分析和预判方法,在收获新技能的同时,也有机会获得“睡后收入”! 四大优势: 三重权益:
softmax回归是一种常用的多分类算法,可以用于尾花分类问题。softmax回归假设每个类别的概率与输入特征的线性函数相关,并使用softmax函数将线性输出转换为概率分布。下面是使用softmax回归进行尾花分类的示例代码: ```python import numpy as np from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 加载数据集 iris = load_iris() X = iris.data y = iris.target # 数据预处理 scaler = StandardScaler() X = scaler.fit_transform(X) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # softmax回归模型 class SoftmaxRegression: def __init__(self, lr=0.1, num_iter=1000): self.lr = lr self.num_iter = num_iter def fit(self, X, y): # 初始化权重 self.W = np.zeros((X.shape[1], len(np.unique(y)))) self.b = np.zeros(len(np.unique(y))) # 梯度下降 for i in range(self.num_iter): z = X.dot(self.W) + self.b exp_z = np.exp(z) sum_exp_z = np.sum(exp_z, axis=1, keepdims=True) softmax = exp_z / sum_exp_z loss = -np.mean(np.log(softmax[range(X.shape[0]), y])) dsoftmax = softmax dsoftmax[range(X.shape[0]), y] -= 1 dW = X.T.dot(dsoftmax) / X.shape[0] db = np.sum(dsoftmax, axis=0) / X.shape[0] self.W -= self.lr * dW self.b -= self.lr * db def predict(self, X): z = X.dot(self.W) + self.b exp_z = np.exp(z) sum_exp_z = np.sum(exp_z, axis=1, keepdims=True) softmax = exp_z / sum_exp_z return np.argmax(softmax, axis=1) # 训练模型 model = SoftmaxRegression(lr=0.01, num_iter=10000) model.fit(X_train, y_train) # 预测测试集 y_pred = model.predict(X_test) # 计算准确率 accuracy = np.mean(y_pred == y_test) print('Accuracy:', accuracy) ``` 这段代码中,首先加载尾花数据集并进行数据预处理。然后将数据集划分为训练集和测试集。接着定义了一个SoftmaxRegression类,其中fit方法使用梯度下降算法训练模型,predict方法用于预测新样本的类别。最后使用训练好的模型对测试集进行预测,并计算准确率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漂流の少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值