💥 项目专栏:【探索机器学习之旅】原理与实践,Python算法实现
文章目录
前言
🚀 欢迎莅临本专栏!在这里,我们将为机器学习的新手和初次尝试 sklearn
的用户群体提供一系列有趣的原生Python机器学习算法实现。我们的目标是让您轻松入门机器学习,并深入探索算法的内部奥秘。💡
在这个专栏中,我们专注于使用原生Python实现一些经典机器学习算法,比如决策树、逻辑回归等。通过自己亲手复现算法,我们将理论与实践紧密结合,让您对这些算法有更深入的理解。每篇文章都会附带完整的代码和详细讲解,助您逐步掌握算法的核心概念和运行原理。🔍📝
哪怕您是零基础,也不必担心!本专栏旨在为您提供一条通向机器学习世界的清晰路径。我们坚信,通过这些实践和理论指导,您将快速掌握机器学习的精髓,并在未来的学习和探索中展翅高飞!🌈🌟
来吧!让我们一起踏上机器学习之旅,探索这个神奇领域,畅游在算法的海洋中,感受数据科学的魅力吧!🌊💻🔬
🚨 欢迎来到我的机器学习探索项目环境!📊🐍
- 平台:Windows 11 🖥️
- 语言环境:Python 3.7 🐍
- 编译器:Jupyter Lab 📘🔬
- 数据处理:Pandas 1.3.5 🐼📈
- 数值计算:Numpy 1.19.3 🔢🧮
- 科学计算:Scipy 1.7.3 🧪📚
- 数据可视化:Matplotlib 3.1.3 📊🎨
在这个酷炫的项目环境里,我们将使用强大的Python语言,搭配Jupyter Lab编译器,为您带来一流的机器学习学习体验。Pandas将为我们处理数据,Numpy则助力高效的数值计算,而Scipy则为我们的科学计算保驾护航。
让数据更加生动的秘密武器是Matplotlib,它将以图表的形式展现复杂的信息,让您轻松洞悉数据的特征和趋势。📊📈🔍
让我们一起在这个有趣的机器学习之旅中探索新的可能性吧!🚀🌟💻
让我们一起启程,探索机器学习的奇妙世界!🚀💡🤖
💥 项目专栏:【探索机器学习之旅】原理与实践,Python算法实现
一、基于原生Python实现逻辑回归算法
逻辑回归是机器学习的明星算法之一!🌟专攻解决二元分类问题,预测二元输出变量,比如做股市预测、客户购买行为研究、疾病诊断等等,应用广泛到医学、金融、社交网络、搜索引擎等各领域。
而本篇文章,正式开启了这个专栏的机器学习冒险之旅!🚀🐍💡我们将使用Python语言,纯手工搭建逻辑回归算法,没有任何复杂的第三方库,让您轻松迈入机器学习的大门。
一步步为您呈现,从算法原理到实现细节,帮助新手小白们快速掌握机器学习训练的框架。💎🐍💡通过这篇文章,您将真正理解逻辑回归的精髓,掌握其实际应用。
让我们共同踏上逻辑回归之旅,为未来的学习和探索奠定坚实基础!📚🤖💻🌈 开启精彩的机器学习之旅吧!🚀📝🔍
二、逻辑回归模型的算法原理
🚀 🐍 逻辑回归(Logistic Regression
)是一位广受欢迎的分类算法!它的主要思想是将输入变量的线性组合经过一种魔法变换,映射到0到1的范围内,就像魔法帽里变出兔子一样预测二元输出变量的概率。🎩🐇
以下是逻辑回归模型的秘密配方:
- 假设我们有一个神秘的二元分类问题,要预测样本是萌萌哒还是酷酷炫。
- 逻辑回归模型使用一个神奇的函数,称为
sigmoid
函数,它像魔法咒语一样将输入变量的线性组合变成0到1之间的概率值。这概率表示了样本是超级正面还是微微负面的可能性。✨🔮 sigmoid
函数的数学咒语为: g ( z ) = 1 1 + e − z g(z) = \frac{1}{1 + e^{-z}} g(z)=1+e−z1这里,z
是输入变量的线性组合,就像点石成金一样: z = b + w 1 x 1 + w 2 x 2 + . . . + w n x n z = b + w_1x_1 + w_2x_2 + ... + w_nx_n z=b+w1x1+w2x2+...+wnxn其中, w i w_i wi是模型的权重(也就是神奇系数), x i x_i xi是输入变量的神秘魔法值。- 训练模型就像炼金术一样,通过最大化似然函数来估计权重。似然函数就是一个与权重相关的魔法公式,它描述了在已知模型的情况下,样本发生的可能性。在逻辑回归中,这个似然函数可以写成: L ( w ) = ∏ i = 1 n g ( z i ) y i ( 1 − g ( z i ) ) 1 − y i L(w) = \prod_{i=1}^n g(z_i)^{y_i}(1-g(z_i))^{1-y_i} L(w)=∏i=1ng(zi)yi(1−g(zi))1−yi其中, z i z_i zi是第i个样本的线性组合, y i y_i yi是对应的魔法标签(0或1)。🌟📜
- 为了
最大化似然函数
,我们需要用一种神奇的算法 -梯度下降
来调整权重。梯度下降算法就像魔法棒一样,通过反复挥舞找到最优解,最小化损失函数的魔法。直到模型变得足够酷炫,让我们心满意足!🧙♂️💫 - 损失函数是用来衡量模型好坏的魔法尺度,我们用
对数损失函数
(log loss)来衡量。它写成魔法诗句: J ( w ) = − 1 n ∑ i = 1 n y i log g ( z i ) + ( 1 − y i ) log ( 1 − g ( z i ) ) J(w) = -\frac{1}{n}\sum_{i=1}^n y_i \log g(z_i) + (1-y_i) \log (1-g(z_i)) J(w)=−n1∑i=1nyilogg(zi)+(1−yi)log(1−g(zi))其中, z i z_i zi是第i个样本的线性组合, y i y_i yi是对应的魔法标签(0或1)。🔍🎯 - 终极魔法时刻,训练完我们的模型,我们可以用它来预测新样本的命运。预测的魔法就是:将新样本的特征值代入
sigmoid
函数,计算输出概率,如果概率超过0.5,恭喜它成为了超级正面;反之,也别气馁,酷炫之路还很长!💃🕺
逻辑回归模型简直比魔法还神奇!简单易懂,广泛应用于各个领域,让我们一起探索这个充满魔力的算法,为机器学习世界增添一抹奇幻色彩!🎨🌈🤖
三、算法实现
🚀 本篇将带你亲身体验用原生Python驾驭逻辑回归算法的奇妙之旅!我们拒绝直接拿 sklearn
的现成模型,而是选择自己动手复现,因为只有亲自动手,才能领略算法内部的精妙流程。🐍🔍
嘘~告诉你个小秘密,这篇文章将给你呈现逻辑回归算法的阉割版。别惊讶!我们特意精简了算法,让新手小白也能轻松理解。相比起 sklearn
的庞然大物,我们留下了算法的核心精华,让你不至于迷失在算法的海洋中。🧭🌊
初学阶段,理解算法的主干才是重中之重!对于一些细枝末节、各种变体以及算法优化策略,留给日后深入探索。毕竟,骑车先学会平衡才能酷炫飙车,对吧?💨🚴♂️
咱们别再观望,一起动手实现逻辑回归算法,感受算法的魔力!别忘了带上你的好奇心和热情,让我们一同踏上这场炫酷的机器学习冒险之旅!🌟🔥🎢
3.1 导包
🚀 本项目将倚重几位超级好帮手,让我们一一介绍这些厉害的第三方库吧!🦸♀️📚
-
首先登场的是
numpy
,这个家伙可是科学计算界的大咖!它像数学公式一样强大,让我们在计算中游刃有余,从矩阵到向量,样样在掌握。💪🔢 -
紧随其后的是
matplotlib
,嘿!它是绘图的高手,就像一把画笔,让我们把数据转换成艺术品。无论是散点图、线图还是饼图,都在它的掌控中。🎨📈 -
接下来,我们有
sklearn.datasets
亮相,这可是数据的源泉!它把各种数据集送上门,为我们提供丰富的训练素材。训练集、测试集统统都有,让我们轻松上手。📦🎁 -
最后登场的是
train_test_split
,它是划分大师!想把数据一分为二?嗖嗖嗖,一刀分开,训练集和测试集各得其所。🔪🎯
这群了不起的库将为我们的项目助力,让我们一起发挥创意,打造一个充满惊喜和乐趣的机器学习世界吧!💡🔥🌟
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
3.2 定义随机数种子
🔢💡 在机器学习的大舞台上,随机数种子可谓是个重要的“魔法符号”!它的神奇之处在于,能让我们的实验结果闪电般地可复制,好似又变出了无限同款的魔法帽子!🎩✨
机器学习算法常常玩一把“随机性魔法”,比如“随机初始化参数”、“随机选择训练样本”,它们就像蹦蹦跳跳的小丑,让同样一份代码运行多次,竟然得出各种不同的结果。🎭🎲
嗯~所以我们需要一个“魔法保镖” —— 设定随机数种子
!它的任务就是捉住这些小丑,让同样一份代码在不同时空运行,也能得到相同的结果,就像照镜子般可重复!🔍🪄
这样做有个超酷的好处,能够让我们的算法评估和比较更准确,不会让随机性搞砸实验结果。对,我们是要“消灭”随机性带来的误差和不确定性,让实验结果更稳定又可信!🎯🎲
可记得,这位“魔法保镖”得和其他条件一致哦!数据集、算法、参数设置等都得守规矩,才能确保实验结果真的是可复制的。就像固定了剧本和演员,才能让魔术变得精彩无比!🎭🌟
现在你懂了吧?随机数种子是我们的魔法杀手锏,让我们的机器学习实验变得有模有样,让魔法不再神秘,而是稳如磐石!🧙♂️🌈🔮
# 设置随机种子
seed_value = 2023
np.random.seed(seed_value)
3.3 定义逻辑回归模型
🔍💻 为了帮小伙伴们更轻松理解,我们打造了逻辑回归模型的“通用魔法接口”,和 sklearn
封装的算法一模一样!就像同款魔法帽,操作简单,效果出众!🎩✨
咱们逻辑回归的魔法训练流程如下:
-
数据预处理:首先,得给数据来一场豪华洗礼!数据清洗、特征选择、特征缩放,让数据美美哒、干干净净!💧🧹
-
模型初始化:好的,让模型的“大门”敞开吧!根据特征数量,初始化模型的参数,就是权重和偏置,准备好出发!🚀💪
-
前向传播:接下来,我们进行前进大军!每个样本的特征向量都要参加“大军演习”,乘以权重,加上偏置,再进行sigmoid魔法变换,预测正例概率!🚶♀️✨
-
计算损失函数:我们的“魔法秤”上场啦!用对数损失函数来衡量我们模型的战斗力,将所有样本的损失值加起来,取平均,看看表现如何!📉⚖️
-
反向传播:若想更强大,那就来个“反击战”!梯度下降算法帮忙,计算出梯度,一步一步更新权重和偏置,让模型变得更强壮!🏹🏃♂️
-
重复步骤3-5:持续战斗,直到我们的模型变得精益求精,或者达到预定迭代次数!🔄🔁
-
模型评估:是时候验收成果了!用测试数据来看看我们的模型到底强不强大,是不是符合预期,毕竟训练有素的好战士!🎯📊
-
模型调优:我们的模型是灵活的,如果需要进一步优化,就调整学习率、迭代次数等参数,让战斗更顺利!🎛️🔧
嗯,这个训练过程还是有些复杂的,但没关系!先掌握基本“战术”,再慢慢丰富“战略”!咱们保留了核心部分,让初学者轻松入门,逐步揭开逻辑回归的神秘面纱!🕵️♂️🌟
加油,小伙伴们!一起探索这个魔幻世界,让机器学习的魔法带来无尽惊喜与乐趣!✨🧙♂️🌈
3.3.1 模型训练
🔍💻 在这个“魔法训练场”,逻辑回归模型终于要展现它的“大招”啦!让我们瞧瞧这个“绝世神功”是怎么练成的吧!🔥🥋
-
模型初始化:首先,我们得给模型一个“修炼基地”,根据数据集的特征数量,初始化模型的“武器” —— 权重和偏置!就像备战大军,准备好了所有装备!💪🏰
-
前向传播:接下来,咱们展开“绝学传承”!每个样本都要参与这场“武林大会”,把特征向量和模型的“武器” —— 权重,一一相乘,再加上偏置,得到“武艺大成”的线性组合!然后,通过“奇妙变换”(sigmoid魔法),嘿!我们揭晓了该样本的正例概率!🎭🎯
-
计算损失函数:啊哈,这是考验我们“功力深厚”的时候了!我们要用对数损失函数来“衡量武艺高低”!遍历所有样本,把它们的损失值相加,再取个“平均分”,看看我们的表现如何!📉⚖️
-
反向传播:当然了,绝世神功怎么能没有“绝招”!使用梯度下降算法,咱们计算损失函数对模型参数的“偏导数” —— 也就是“绝招秘籍”!然后,踏上“修罗之路”,一步一步更新模型的“武器” —— 权重和偏置!⚔️🏃♂️
-
重复步骤2-4:在“练习场”上,持续反复,直到咱们达到预定迭代次数或损失函数满足某个“境界”!哇,这样的修炼之旅,真是富有挑战又刺激!🔄🔁
好了,现在你了解了逻辑回归模型的“绝世秘笈”!掌握了这些训练的精髓,你将在机器学习的江湖中成为一名真正的“绝世高手”!🧙♂️💫🌟
3.3.1.1 初始化参数
📝💻 对于逻辑回归,我们来解读这个“神秘公式” y = b + w 1 x 1 + w 2 x 2 + . . . + w n x n y=b+w_1x_1+w_2x_2+...+w_nx_n y=b+w1x1+w2x2+...+wnxn,这其实是一个“武林秘笈”,它揭示了逻辑回归的真正核心!咱们得学会“练功”,研究权重系数 w w w 是怎么一步步练出来的!💪🔍
要开始“修炼”逻辑回归模型,我们得先准备好“练功器” —— 两个神奇参数:权重 w
和偏置 b
。就像江湖高手,必须得掌握这两项“绝技”!🧙♂️🏋️♂️
现在,让我们通过以下代码来“开启修炼模式”,初始化模型的可训练参数:
# 初始化参数
self.weights = np.random.randn(X.shape[1])
self.bias = 0
好了,这就像是给我们的“绝世高手”配备了“超能装备”!随机初始化的权重和零偏置,为我们的“修炼之路”铺就了第一步!现在,就让我们开始踏上逻辑回归的“功夫之旅”,探索更深奥的机器学习世界吧!🚀🌌🧭
3.3.1.2 正向传播
🎯🔢 逻辑回归,我们的“绝世神功”,可不止一般的二分类哦!我们要把计算的结果变成“神秘预言” —— 对应的概率值!要实现这个魔法,我们得把结果送入到 Sigmoid
的“法器”中!然后,咱们就可以得到那迷人的概率了!🔮🎩
让我们一起解密这个“神秘公式”: y ^ = s i g m o i d ( y ) = s i g m o i d ( w ∗ x + b ) = 1 ( 1 + e x p w ∗ x + b ) \hat y=sigmoid(y)=sigmoid(w * x + b)=\frac{1}{(1+exp^{w*x+b})} y^=sigmoid(y)=sigmoid(w∗x+b)=(1+expw∗x+b)1
这其实就是逻辑回归的“魔咒”,通过一系列神奇计算,将模型的线性组合送入 Sigmoid
的“宝库”,从而得到神奇的
y
^
\hat y
y^ —— 也就是那迷人的概率值!💫🔍
别小看了这个“小小魔法”,它可是让我们准确预测二分类结果的“宝贝”!在逻辑回归的世界里,这个神奇的公式是“必杀技”!现在,咱们已经揭开了一层神秘面纱,接下来,就让我们继续探索机器学习的魔幻之旅吧!🧙♂️🌌🚀
# 计算sigmoid函数的预测值, y_hat = sigmoid(w * x + b)
y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
3.3.1.3 损失函数
🎯💡 嘿!要让我们的“神奇预言”更接近真实,就得定义一把“捕梦网” —— 也就是损失函数
!这个函数可是我们用来衡量预测值和真实值之间的差异的“宝贝”!就像“魔法秤”一样,让我们看看预测的准不准!🔮⚖️
这里我们使用的是交叉熵函数(Cross Entropy),听起来很高深吧?其实,这是一把“魔法秘籍”,专门用来衡量我们预测的 y ^ \hat y y^ 和真实值 y y y 之间的“相爱相杀”!💔😢
让我们揭开这个“神秘公式”: l o s s = − 1 n ∑ y l n ( y ^ ) + ( 1 − y ) l n ( 1 − y ^ ) loss=-\frac{1}{n}\sum yln(\hat y)+(1-y)ln(1- \hat y) loss=−n1∑yln(y^)+(1−y)ln(1−y^)
哎呀,这个公式可是让我们血脉贲张,也有些难以理解!但别怕,这就像是我们“大魔导师”的法宝,通过一系列精巧运算,测量预测的准确度,为我们的修炼之路保驾护航!🧙♀️🌟
现在,我们已经有了“捕梦网”,就让我们开始“捉拿”预测和真实之间的“真凶”吧!让我们的模型在“损失战场”中不断进步,成为机器学习的“传奇战士”!💪🏹🛡️
# 计算损失函数
loss = (-1 / len(X)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
3.3.1.4 反向传播
🎯🌊 嗯哼!在逻辑回归的世界里,我们可是要采用一项超级武器来训练我们的“功夫”!那就是 —— 梯度下降法!这可不是什么“呆萌招数”,而是绝对“减肥神器”!让我们的模型在“梯度的海洋”中翱翔!🌊🏄♂️
通过梯度下降法,我们不断调整当前的“神奇参数”,就像是在找到“最佳航线”,让我们的模型朝着“减肥”的方向发展!向着损失减小的方向,我们将稳健前行!🚀🌈
让我们揭开这个“超级武器”的秘密:参数更新方法就是梯度下降法!简单说,我们不断将当前参数“减肥”,让模型向着“损失的大门”靠拢!就像是在逻辑回归的“舞台”上,我们跳起了梯度下降的“优雅舞步”,让模型的准确度逐步攀升!💃🏋️♀️🏆
是不是觉得这个“魔法舞步”很有意思?让我们的模型跟着节奏,越跳越高,成为机器学习的“梯度之星”!一起在这个精彩的舞台上展现真正的“舞技”吧!🌟🕺💫
🧠🚀 嘿!在逻辑回归的魔法世界里,我们使用了一把超级神器 —— sigmoid
函数,把线性输出变成了魔法的概率值!就像变魔术一样,我们把预测的范围限制在了 [0,1]
之间!🎩🐇🌟
而为了在这个神奇的世界里不断进步,我们使用了“超能力” —— 交叉熵代价函数!这个神秘的函数能告诉我们预测值和真实值之间的“差异”,帮助我们找到最优解,使“代价函数”最小化!🎯🔍🎯
具体来说,我们的“魔法流程”是这样的:首先,通过“前向传播”计算模型的预测值和代价函数的值,看看我们的魔法预测对不对!然后,通过“反向传播”算法计算代价函数相对于每个权重参数的导数,这样我们就知道哪些权重需要“变魔术”啦!最后,我们使用“梯度下降”算法,不断调整权重参数,让“代价函数”尽可能变小,找到最佳解!🕵️♀️💪💡
所以,就像在学校学数学一样,我们用“链式法则”来计算这些“神奇导数”,让我们的模型能够在这个神奇的魔法世界里越走越远,变得更加厉害!让我们的模型成为“梯度之星”,在这个奇妙的机器学习世界中闪耀光芒!🌟✨🚀
# 计算梯度
dw = (1 / len(X)) * np.dot(X.T, (y_hat - y))
db = (1 / len(X)) * np.sum(y_hat - y)
# 更新参数
self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db
3.3.2 模型预测
🔮🎉 看到了吗?在逻辑回归的预测舞台上,我们要用 魔法概率
来预测未来!就像是在掐指一算,我们要知道这个样本是属于哪一类的!🔮💫
然而,我们的魔法概率还不够直观,我们需要将它“二值化”,变成了我们熟悉的0和1!就像是魔术师用魔杖一挥,让数字世界立刻变得简单明了!🎩🪄🎱
看看我们的魔法代码,就能实现这个“二值化”的妙技!大于0.5,就变成了1;小于0.5,就变成了0!不仅仅是逻辑回归,这也是我们生活中的一种选择,是或者不是!简单而直观!🎯👏🧠
在这个“魔幻预测”舞台上,我们的模型会成为“魔法大师”,为每一个样本揭开神秘面纱!看看它是属于类别0还是类别1,你就是我们的“真心粉丝”!🌟👤🌈
现在,让我们的模型跟着我们的节奏,一起走进这个神奇的世界,看看它如何用“魔法概率”揭示真相,完成逻辑回归的华丽演出!🎇💃🎉
# 预测
def predict(self, X):
y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
y_hat[y_hat >= 0.5] = 1
y_hat[y_hat < 0.5] = 0
return y_hat
3.3.3 模型分数
📊🎯 哈哈!在逻辑回归的精彩表演后,我们要来看看它的“终极成绩单”!是不是想知道它的得分有多高呢?🤔📝
在这个“成绩单”上,我们有一位“准确率守护者”!🦸♂️🎖️就像是一位“守门员”,它要紧紧盯着每一个样本,判断它们是不是被正确分类了!如果分类正确,就给它打个“√”,否则给个“×”!🔍✅❌
然后,我们要数一数这些“√”的数量!🔢 这些可都是我们分类正确的样本哦!然后,再除以总样本数,得到“准确率”这个神秘的指标!就像是一个小小的考试,看看我们的模型在这个分类挑战中表现如何!🧠📊💯
当然,如果你觉得“准确率”还不够全面,我们还有其他“指标队员”可以派上用场!🚀🎖️比如“F1分数”,这位队员会综合考虑准确率和召回率,得出一个综合分数!还有“AUC”,这位队员是衡量模型预测能力的“面面观察员”!📈📉
所以,在这个机器学习竞技场上,我们有多重指标来考察我们的模型,看看它在各方面的表现!是不是觉得很有趣?让我们一起见证逻辑回归的“准确率之路”,一路高歌,直抵成功的彼岸!🎵🎤💥
# 精度
def score(self, y_pred, y):
accuracy = (y_pred == y).sum() / len(y)
return accuracy
3.3.4 Logistic Regression模型
📚🤖 某位名为“逻辑回归”的学霸闪亮登场!🚀💫 这位学霸在机器学习领域可是名声大噪,被誉为“二分类之王”!👑💪
听说逻辑回归有个独特的“签名技能”!它的魔法就是将输入的特征线性组合,然后通过神奇的“Sigmoid”函数,变出0到1之间的概率预测值!🎩🔮
它的超级任务是预测二元输出,就像在大冒险中,对每个样本说:“你是0还是1,我猜猜看!”🎲🔍 如果猜对了,就欢呼雀跃,把它标记为“√”,否则它就会默默流泪,打上一个“×”!😢✅❌
为了让它变得更强大,它经过艰苦的“训练”!就像一场冒险之旅,它需要面对代价函数的挑战,不断调整权重和偏置,用梯度下降攀登到最佳状态!🏔️🧗♂️
当然啦,逻辑回归不是一个人在战斗!它带着整个Python团队,一起奋战在数据预处理、正向传播、反向传播等环节!🐍🎯🏹 每个环节都是它成功的关键!💼💡
最后,逻辑回归不仅仅追求“准确率”的荣耀,还喜欢和其他指标队员一起探索!🤝🏆 有时候,会和“F1分数”、 “AUC”这些好友切磋技艺,获得更全面的表现!🤼📈📉
所以,这就是逻辑回归的故事!它是二分类领域的超级英雄,用逻辑和魔法为数据世界带来光明!🌟💻✨ 让我们为这位学霸喝彩,继续探索未知的领域!🎉🎊🚀
# 定义逻辑回归算法
class LogisticRegression:
def __init__(self, learning_rate=0.003, iterations=100):
self.learning_rate = learning_rate # 学习率
self.iterations = iterations # 迭代次数
def fit(self, X, y):
# 初始化参数
self.weights = np.random.randn(X.shape[1])
self.bias = 0
# 梯度下降
for i in range(self.iterations):
# 计算sigmoid函数的预测值, y_hat = w * x + b
y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
# 计算损失函数
loss = (-1 / len(X)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
# 计算梯度
dw = (1 / len(X)) * np.dot(X.T, (y_hat - y))
db = (1 / len(X)) * np.sum(y_hat - y)
# 更新参数
self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db
# 打印损失函数值
if i % 10 == 0:
print(f"Loss after iteration {i}: {loss}")
# 预测
def predict(self, X):
y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
y_hat[y_hat >= 0.5] = 1
y_hat[y_hat < 0.5] = 0
return y_hat
# 精度
def score(self, y_pred, y):
accuracy = (y_pred == y).sum() / len(y)
return accuracy
3.4 导入数据
🌺🌿 嘿,我是数据收集小精灵,今天给你带来一个神奇的数据集——鸢尾花数据集!🌸🎁
这个数据集是我们学习逻辑回归的好伙伴,一共有150个样本,其中有三个超级酷炫的鸢尾花品种:山鸢尾、变色鸢尾和维吉尼亚鸢尾!🦋🌺🌼
每个鸢尾花都很有个性,都带着四个特征:萼片长度、萼片宽度、花瓣长度和花瓣宽度。📏🌸 这些特征都是用厘米来衡量的,真是科技发达呀!📐💡
不过,我们的逻辑回归只能处理二分类问题,所以我们要把品种1和品种2合并成一类,形成两个类别:0和1。💪🌈
为了方便我们后续的可视化探险,我们只挑选了两个最重要的特征来建模,你也可以尝试使用全部四个特征,并使用PCA降维,展开一场绚丽多彩的特征世界!🌈🚀
所以,准备好了吗?让我们带着数据探险的心情,一起踏上逻辑回归的冒险之旅吧!🌟🚀🌿
# 导入数据
iris = load_iris()
X = iris.data[:, :2]
y = (iris.target != 0) * 1
3.5 划分训练集、测试集
🎯📚 机器学习的大门已经敞开,数据集划分是我们冒险的第一步!🚀🗺️
在这段旅程中,我们要将数据拆分成两个超级重要的伙伴:训练集和测试集!🤝🌟
训练集是我们的学习材料,用于教会模型认识世界,它就像是我们的训练场所!📚💪
而测试集是我们的考试试卷,用于考察模型的真正能力,看看它是否真的学会了分类的本领!🧪📝
为了完成这一壮举,我们使用了 sklearn
提供的 train_test_split
方法,就像是找了一位智慧之神来帮我们分割数据!🧙♂️🎉
有了这样的划分,我们的模型将在训练中不断成长,然后在测试中展现自己的才华!🌱💫
现在,让我们披荆斩棘,勇往直前,一起踏上机器学习之路吧!🚀🌈🌟
# 划分训练集、测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=seed_value)
3.6 模型训练
🎛️🧠 让我们打造一个无敌的模型对象吧!现在是时候让模型发挥它的超能力了!💪🤖
我们要做的第一件事就是赋予它两个强大的超参数:学习率
和 迭代次数
,这将是它在训练过程中的秘密武器!🛡️🌟
然后,我们将把我们精心准备的训练数据送到模型那里,让它尽情地吸收知识,调用模型的 fit
方法,实现训练的魔法!🎓🌈
这个模型就像是一位超级英雄,经过无数次的试炼,终将拥有强大的分类技能!🏆🚀
让我们一起见证这个奇迹的诞生,来探索机器学习的奇妙世界吧!🚀🌌💫
# 训练模型
model = LogisticRegression(learning_rate=0.03, iterations=1000)
model.fit(X_train, y_train)
3.7 打印结果
🎉🔍 训练完成后,是时候展示我们模型的华丽战绩啦!让我们调用一段神秘代码,看看我们的模型在 训练集
和 测试集
上的准确率表现!📈🎯
如果你是一个能力超群的小伙伴,还可以画上一条华丽的 AUC曲线
,深入探索模型的神秘本质,让我们的模型散发出更加迷人的光芒!✨🌈
嘿,你知道吗?模型训练好像一场盛大的冒险旅程,我们经历了许多的训练,不断追求更高的准确率,就像是在探索一个未知的星系一样!🚀🌌💫
现在,让我们揭开神秘的面纱,见证模型的辉煌成就!准备好了吗?一起来发现机器学习的魅力吧!🎉🔍💫
# 结果
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)
score_train = model.score(y_train_pred, y_train)
score_test = model.score(y_test_pred, y_test)
print('训练集Accuracy: ', score_train)
print('测试集Accuracy: ', score_test)
>>>训练集Accuracy: 1.0
>>>测试集Accuracy: 0.9565217391304348
3.8 可视化决策边界
🎨📈 当然,我们不能错过这个绘图的机会!让我们一起画出那个充满神秘感的 决策边界图
,看看我们的模型在分类任务中的表现!🌟🌐
你知道吗?绘制决策边界就像是将模型的智慧展现在纸上,就像画家将自己的灵感描绘在画布上一样,我们要用代码勾勒出模型的优雅之处!🎨🤖✨
现在,让我们握紧画笔,运用魔法绘制出那个神秘的决策边界图,让我们的模型展现出最美的一面!🌈🔍🎨
准备好了吗?来吧!让我们一起进入这个绘画的奇妙世界,发现机器学习的无限魅力!🚀🌌💫
# 可视化决策边界
x1_min, x1_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
x2_min, x2_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, 100), np.linspace(x2_min, x2_max, 100))
Z = model.predict(np.c_[xx1.ravel(), xx2.ravel()])
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.savefig('a.png', dpi=720)
plt.show()
完整源码
🚨🚨🚨 注意啦!这里有个特别声明 📢📢📢 :
我们的专栏可是为新手小白量身打造的,考虑到方便起见,我们采用了 Python
单文件实现的方式,让大家可以轻松一键复制、调试和运行,省去了复杂的项目构造步骤。😉🔧🐍
嗯,还有一点哦!我们的目标是帮助新人理解机器学习算法的基本训练预测过程,所以源码里只包含了算法的基本框架结构。虽然有些地方可能显得略显简陋,但也是为了让大家可以轻松理解。当然,有能力的小伙伴可以根据自己的能力在此基础上大展身手,尝试更多的参数和拓展功能,甚至可以进行分文件编写,搭建出完整的项目开发流程哦!🌟💪🔍
嗯嗯,我们始终坚信,学习是一步步积累的过程,我们陪你一起成长,助你成为机器学习的大神!🚀🌈💻
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# 设置随机种子
seed_value = 2023
np.random.seed(seed_value)
# Sigmoid激活函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 定义逻辑回归算法
class LogisticRegression:
def __init__(self, learning_rate=0.003, iterations=100):
self.learning_rate = learning_rate # 学习率
self.iterations = iterations # 迭代次数
def fit(self, X, y):
# 初始化参数
self.weights = np.random.randn(X.shape[1])
self.bias = 0
# 梯度下降
for i in range(self.iterations):
# 计算sigmoid函数的预测值, y_hat = w * x + b
y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
# 计算损失函数
loss = (-1 / len(X)) * np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
# 计算梯度
dw = (1 / len(X)) * np.dot(X.T, (y_hat - y))
db = (1 / len(X)) * np.sum(y_hat - y)
# 更新参数
self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db
# 打印损失函数值
if i % 10 == 0:
print(f"Loss after iteration {i}: {loss}")
# 预测
def predict(self, X):
y_hat = sigmoid(np.dot(X, self.weights) + self.bias)
y_hat[y_hat >= 0.5] = 1
y_hat[y_hat < 0.5] = 0
return y_hat
# 精度
def score(self, y_pred, y):
accuracy = (y_pred == y).sum() / len(y)
return accuracy
# 导入数据
iris = load_iris()
X = iris.data[:, :2]
y = (iris.target != 0) * 1
# 划分训练集、测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=seed_value)
# 训练模型
model = LogisticRegression(learning_rate=0.03, iterations=1000)
model.fit(X_train, y_train)
# 结果
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)
score_train = model.score(y_train_pred, y_train)
score_test = model.score(y_test_pred, y_test)
print('训练集Accuracy: ', score_train)
print('测试集Accuracy: ', score_test)
# 可视化决策边界
x1_min, x1_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
x2_min, x2_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, 100), np.linspace(x2_min, x2_max, 100))
Z = model.predict(np.c_[xx1.ravel(), xx2.ravel()])
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.show()