机器学习算法-逻辑回归

什么是逻辑回归

逻辑回归(Logistic Regression)是⼀种⽤于解决分类问题的统计学习⽅法。 尽管它的名称中包含"回归"⼀词,但它实际上是⼀种分类算法,⽤于将输⼊数据分 为两个或多个类别。逻辑回归通常⽤于⼆元分类问题,其中要将输⼊数据分为两个 类别,但它也可以扩展到多类别分类。

逻辑回归的基本思想是,通过将输⼊特征与权重进⾏线性组合,然后将线性组 合的结果通过⼀个称为逻辑函数(Logistic function)或 Sigmoid 函数的⾮线性 函数进⾏转换,将其映射到⼀个介于0和1之间的概率值。这个概率值表示属于某⼀ 类别的概率。

sepal_lengthsepal_widthpetal_lengthpetal_widthspecies
5.13.51.40.2setosa
4.931.40.2setosa
4.73.21.30.2setosa
4.63.11.50.2setosa
53.61.40.2?

我们就可以基于已知的数据集,建⽴模型,从⽽可以对未知的样本数据进⾏分类预测。

算法模型

对于逻辑回归,模型的前⾯与线性回归类似:

不过, z的值是⼀个连续的值,取值范围为 (-∞,∞),我们可以将阈值设置为中 间的位置,也就是 0,当 z>0时,模型将样本判定为⼀个类别(正例),当 z<=0 时,模型将样本判定为另外⼀个类别(负例)。这样,模型就实现了⼆分类的任务。

假设真实的分类 的值为1与0,则模型的预测结果为:

sigmoid函数

Sigmoid 函数(也称为 Logistic 函数)是⼀种常⻅的⾮线性激活函数,通常⽤于 将实数值映射到介于 0 和 1 之间的范围。它的数学形式如下:

其中:

  • sigmoid(z) 是 Sigmoid 函数的输出,它表示在输⼊ z的情况下,输出为 1 的概率。

Sigmoid 函数具有以下特性:

  1. 输出范围在 0 到 1 之间,因此它常被⽤于⼆元分类问题,其中输出可以被解释 为某个事件发⽣的概率。
  2. 当 z 接近正⽆穷⼤时,sigmoid(z)接近 1,当 z接近负⽆穷⼤时,sigmoid(z)接 近 0。
  3. Sigmoid 函数是单调递增的,这意味着输⼊值增加时,输出值也增加。

sigmoid函数图像

import matplotlib.pyplot as plt
import numpy as np 

plt.rcParams['font.size'] = 12
plt.figure(figsize=(10,5))
z = np.linspace(-10,10,200)
sig = 1/(1+np.exp(-z))

plt.plot(z,sig, 'g', linewidth=2, label=r'$\sigma(x)=\frac{1}{1+e^{-z}}$')
plt.legend(fontsize=20)
plt.axhline(y=1,ls='--',c='k')
plt.axhline(y=0,ls='--',c='k')

运行结果:

损失函数

损失函数是⽤于评估模型预测结果与实际结果之间差异的函数。

对数损失函数

在逻辑回归中,损失函数通常是对数损失函数(log loss),它根据模型的预测概 率和真实标签来计算损失。

为了⽅便求解,我们取对数似然函数,让累积乘积变成累积求和:

我们可以将上式的相反数作为逻辑回归的损失函数(对数损失函数):

损失函数与sigmoid

import matplotlib.pyplot as plt
s =np.linspace(0.01,0.99,200)
for y in [0,1]:
 loss = -(y*np.log(s)+(1-y)*np.log(1-s))
 plt.plot(s,loss,label=f"y={y}")

plt.legend()
plt.xlabel('s(z)')
plt.ylabel('J(w)')

运行结果

模型训练与预测

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
import warnings
warnings.filterwarnings("ignore")
iris = load_iris()
x,y = iris.data,iris.target
x = x[y!=0,2:]
y=y[y!=0]
y[y==1] = 0
y[y==2] = 1
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25,random
_state=20)
lr = LogisticRegression()
lr.fit(x_train,y_train)
y_hat = lr.predict(x_test)
print("权重:", lr.coef_)
print("偏置:", lr.intercept_)
print("真实值:", y_test)
print("预测值:", y_hat)

运行结果

权重: [[2.77710497 1.82744851]]
偏置: [-16.80892093]
真实值: [1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 1 0]
预测值: [1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0 1 0 1 0]

可视化

import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei'
c1 = x[y == 0]
c2 = x[y == 1]
plt.scatter(x=c1[:, 0], y=c1[:, 1], c="g", label="类别0")
plt.scatter(x=c2[:, 0], y=c2[:, 1], c="r", label="类别1")
plt.xlabel("花瓣⻓度")
plt.ylabel("花瓣宽度")
plt.title("鸢尾花样本分布")
plt.legend()

运行结果

接下来,我们来绘制在测试集中,样本的真实类别与预测类别。

plt.figure(figsize=(15,5))
plt.plot(y_test,marker="o",ls="",ms=15,c="r",label="真实类别")
plt.plot(y_hat,marker="X",ls="",ms=15,c="g",label="预测类别")
plt.legend()
plt.title("逻辑回归分类预测结果")
plt.show()

运行结果

逻辑回归实现二分类 

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
import warnings
warnings.filterwarnings('ignore')

iris = load_iris()
x,y = iris.data,iris.target
# 只取1和2这两个类别
x = x[y!=0,2:]   # 取类别不为0,然后取2列和3列
y = y[y!=0]      # 取y != 0 的类别
# print(y)
y[y==1] = 0  # 把原来为1的类别改为0 
y[y==2] = 1

# 数据集划分
x_train, x_test,y_train,y_test = train_test_split(x,y,test_size=0.25,random_state=2)

lr = LogisticRegression()
# 训练数据
lr.fit(x_train,y_train)
# 预测 
y_hat = lr.predict(x_test)
print("真实值", y_test)
print("预测值", y_hat)

运行结果

真实值 [1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 1 0 1]
预测值 [1 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 1 1 0 0 1 0 1]

绘制决策边界 

# np.meshgrid
x = np.arange(0,5,2)
y = np.arange(1,10,3)
print(x)
print(y)
plt.plot(x,y, color='red', marker='.',linestyle='',markersize='10')
plt.grid()

运行结果

x = np.arange(0,5,2)
y = np.arange(1,10,3)
X,Y = np.meshgrid(x,y)
plt.plot(X,Y, color='red', marker='.',linestyle='',markersize='10')
plt.grid()

运行结果

from matplotlib.colors import ListedColormap

def plot_decision_boundary(model,X,y):
 # 设置三个分类
 color = ['r','g','b']
 marker = ['o','v','x']
 # 获取标签
 class_label = np.unique(y)
 # 定义颜色图 
 cmap = ListedColormap(color[:len(class_label)])
 
 # 获取最小值和最大值
 x1_min,x2_min = np.min(X,axis=0)
 x1_max,x2_max = np.max(X,axis=0)
 print(X.shape)
 # 在原范围内取更多值
 x1 = np.arange(x1_min-1,x1_max+1,0.02)
 x2 = np.arange(x2_min-1,x2_max+1,0.02)
 #笛卡尔积
 X1,X2 = np.meshgrid(x1,x2)
 # print(X1.shape)  # (175,295)
 # print(X2.shape)  # (175,295)
 
 Z = model.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape)
 
 # 绘制等高线 
 plt.contourf(X1,X2,Z,cmap=cmap,alpha=0.5)
 
 #绘制 
 for i,class_ in enumerate(class_label):
  plt.scatter(x=X[y==class_,0], y=X[y==class_,1],c=cmap.colors[i],label=class_,marker=marker[i])
  plt.legend()

plt.figure(figsize=(10,6))
plot_decision_boundary(lr,x_train,y_train)

运行结果 

plot_decision_boundary(lr,x_test,y_test)

运行结果 

总结

逻辑回归(Logistic Regression)是⼀种⽤于⼆分类问题的监督学习算法。尽 管它带有“回归”⼀词,但实际上它⽤于分类问题。逻辑回归通过将线性组合的结果 通过⼀个sigmoid函数映射到[0, 1]的范围来进⾏分类。以下是逻辑回归算法的基本 实现步骤:

1. 导⼊必要的库:

import numpy as np
import matplotlib.pyplot as plt

2. 定义sigmoid函数:

def sigmoid(z):
 return 1 / (1 + np.exp(-z))

3.定义损失函数:

逻辑回归的损失函数通常使⽤交叉熵损失函数(cross-entropy loss):

def compute_loss(y, y_pred):
 m = len(y)
 loss = -1/m * np.sum(y * np.log(y_pred) + (1 - y) * np.log(1 - y_pred))
 return loss

4. 定义梯度下降函数:

def gradient_descent(X, y, y_pred, learning_rate):
 m = len(y)
 gradient = np.dot(X.T, (y_pred - y)) / m
 return learning_rate * gradient

5. 训练模型:

def train(X, y, epochs, learning_rate):
 m, n = X.shape
 # 初始化权重和偏置
 weights = np.zeros((n, 1))
 bias = 0
 for epoch in range(epochs):
 # 计算预测值
 z = np.dot(X, weights) + bias
 y_pred = sigmoid(z)
 # 计算损失
 loss = compute_loss(y, y_pred)
 # 计算梯度并更新参数
 gradient = gradient_descent(X, y, y_pred, learning_rate)
 weights -= gradient.reshape((n, 1))
 bias -= learning_rate * np.sum(y_pred - y) / m
 # 每迭代100次输出⼀次损失
 if epoch % 100 == 0:
 print(f'Epoch {epoch}, Loss: {loss}')
 return weights, bias

6. 测试模型:

def predict(X, weights, bias):
 z = np.dot(X, weights) + bias
 y_pred = sigmoid(z)
 return (y_pred >= 0.5).astype(int))

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值