机器学习入门(一)

一、机器学习概述

1、人工智能

像人一样智能的综合与分析,机器模拟人类。
是一个系统,像人那样思考,像人那样理性思考。
是一个系统,像人那样活动,像人那样合理的系统

2、机器学习

让机器自动学习,而不是基于规则编程。(不依赖特定规则编程)

让机器在没有明确编程的情况下学习的研究领域

通过历史数据训练的一个模型,在新的数据输入后,该模型可以预测新数据的未知属性。

3、深度学习

深度神经网络,大脑方式,设计一层一层的神经元去模拟万事万物。

4、总结

机器学习是实现人工智能的一种途径

深度学习是机器学习的一种方法

二、机器学习三要素

1、数据

(一)、作用

决定了模型效果的上限。

(二)、常见术语

  • 样本:一条数据就是一个样本,多个样本组成数据集
  • 特征:一列数据一个特征,有时也被称为属性,特征是从数据中抽取出来的,对结果预测有用的信息
  • 标签:需要预测的信息
  • 数据集划分:可划分两部分:训练集、测试集 比例:8 : 2,7 : 3
    • 用来训练模型的数据集
    • 用来测试模型的数据集

2、算法

(一)、有监督学习–更加常见的一种算法学习

(1)定义

输入数据是由输入特征值和目标值所构成,即输入的训练数据有标签的。

输入实例X和输出正确答案Y来训练模型,在经过一定的训练后,模型可以将一个全新的输入相对应的预测出输出。

(2)数据集

需要人工标注数据

(3)两种有监督学习
  • 分类:目标值是不连续的

​ 分类种类:二分类、多分类任务

  • 回归:目标值是连续的

(二)、无监督学习–不太常见

(1)定义

输输入数据没有被标记,即样本数据类别未知,没有标签,根据样本间的相似性,对样本集聚类,以发现事物内部 结构及相互关系。

(2)数据集

不需要标注数据

(3)特点
  • 训练数据无标签
  • 根据样本间的相似性对样本集进行聚类,发现事物内部结构及相互关系
(4)常见类型
  • 聚类算法,将有相同或者类似属性的数据聚合到一起,虽然我们没有标签知道该类数据的具体类别,但是我们知道某块数据是同一类。
  • 异常检测,因为有聚类的效果,所以当一些异常数据出现时,可以很明显的看出来不在群组内。
  • 降维,可以将一个大的数据集压缩成尽量小的数据集,同时丢失尽量少的信息。

(三)、半监督学习

(1)工作原理
  • 让专家标注少量数据,利用已经标记的数据(也就是带有类标签)训练出一个模型

  • 再利用该模型去套用未标记的数据

  • 通过询问领域专家分类结果与模型分类结果做对比,从而对模型做进一步改善和提高

(2)特点

可大幅降低标记成本

(四)、强化学习

(1)定义

机器学习的一个重要分支

(2)应用场景

AlphaGo围棋、各类游戏、对抗比赛、无人驾驶等场景

(3)基本原理

通过构建四个要素:agent,环境状态,行动,奖励,agent根据环境状态进行行动获得最多的累计奖励。

例如小孩子学走路:

  • 小孩就是 agent,他试图通过采取(即行走)来操纵环境(地面),

  • 并且从一个状态转变到另一个状态(即他走的每一步),

  • 当他完成任务的子任务(即走了几步)时,孩子得到奖励(给巧克力吃),

  • 并且当他不能走路时,就不会给巧克力。

(五)、总结

Inout目的案例
监督学习有标签有反馈预测结果猫狗分类 房价预测
无监督学习无标签无反馈发现潜在结构物以类聚 人与群分
半监督学习部分有标签,部分无标签有反馈降低数据标记的难度
强化学习决策流程及激励系统一系列行动长期利益最大化围棋

3、算力

  • CPU:IO操作

  • GPU:并行计算

三、建模流程

1、获取数据

根据任务获取数据

2、数据基本处理

缺失值处理

异常值处理

3、特征工程

利用专业背景知识和技巧处理数据,让机器学习算法效果最好。这个过程就是特征工程

释义:特征工程是困难、耗时、需要专业知识。应用机器学习基础就是特征工程

【理解】数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已

(一)、特征提取

从原始数据中提取与任务相关的特征,构成特征向量

对于文本、图片这种非行列形式的数据行列形式转换,

一旦转换成行列形式一列就是特征

(二)、特征预处理

特征对模型产生影响;因量纲问题,有些特征对模型影响大、有些影响小

将不同的单位的特征数据转换成同一个范围内

使训练数据中不同特征对模型产生较为一致的影响

(三)、特征降维

将原始数据的维度降低,叫做特征降维

会丢失部分信息。降维就需要保证数据的主要信息要保留下来

原始数据会发生变化,不需要了解数据本身是什么含义,它保留了最主要的信息

(四)、特征选择

原始数据特征很多,但是对任务相关是其中一个特征集合子集

从特征中选择出一些重要特征(选择就需要根据一些指标来选择)

特征选择不会改变原来的数据

(五)、特征组合

把多个的特征合并成一个特征

通过加法、乘法等方法将特征值合并

4、模型训练

KNN(K近邻算法)

线性回归

逻辑回归

5、模型预测

6、模型评估

(一)、分类

准确率

(二)、回归

MAE、MSE

(三)、聚类

CH、SC

(四)、模型拟合

(1)三种情况
  • 正好拟合:用来表示模型对样本点的拟合情况
  • 过拟合
    • 模型在训练集上表现很好, 在测试集表现很差
    • 模型太过于复杂, 数据不纯, 训练数据太少
  • 欠拟合
    • 模型在训练集上表现很差, 在测试集表现也很差
    • 模型过于简单
(2)泛化

模型在新数据集(非训练数据)上的表现 好坏 的能力

(3)奥卡姆剃刀原则

给定两个具有相同泛化误差的模型, 较简单的模型比较复杂的模型更可取

四、KNN算法–近邻算法

1、KNN简介

一个样本最相似的 k 个样本中的大多数属于某一个类别,则该样本也属于这个类别

一般用来解决分类和回归问题。

样本的数量决定最终训练出来的模型好坏,当K值过小:用较小邻域中的训练实例进行预测,容易受到异常点的影响,K值的减小就意味着整体模型变得复杂,容易发生过拟合;K值过大:用较大邻域中的训练实例进行预测,受到样本均衡的问题,且K值的增大就意味着整体的模型变得简单,欠拟合。

而我们该如何区选择k值呢?
通常需要一些方法来寻找这个最合适的K值:交叉验证、网格搜索。

2、KNN的API介绍

(一)分类API

# sklearn.neighbors.KNeighborsClassifier(n_neighbors=5) 
# n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数
from sklearn.neighbors import KNeighborsClassifier
def dm01_knnapi_分类():estimator =  KNeighborsClassifier(n_neighbors=1)X = [[0], [1], [2], [3]]y = [0, 0, 1, 1]estimator.fit(X, y)myret = estimator.predict([[4]])print('myret-->', myret)

(二)回归API

# sklearn.neighbors.KNeighborsRegressor(n_neighbors=5)
from sklearn.neighbors import KNeighborsRegressor
def dm02_knnapi_回归():estimator =  KNeighborsRegressor(n_neighbors=2)X = [[0, 0, 1],[1, 1, 0],[3, 10, 10],[4, 11, 12]]y = [0.1, 0.2, 0.3, 0.4]estimator.fit(X, y)myret = estimator.predict([[3, 11, 10]])print('myret-->', myret)

3、距离度量方法

(一)、欧式距离

d 12 = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 d 12 = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 + ( z 1 − z 2 ) 2 d 12 = ∑ i = 1 N ( x 1 k − x 2 k ) 2 d_{12} = \sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\\ d_{12} = \sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2}\\ d_{12} = \sqrt{\sum_{i=1}^N(x_{1k}-x_{2k})^2} d12=(x1x2)2+(y1y2)2 d12=(x1x2)2+(y1y2)2+(z1z2)2 d12=i=1N(x1kx2k)2

(二)、曼哈顿距离

d 12 = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ d 12 = ∑ i = 1 N ∣ x 1 k − x 2 k ∣ d_{12} = |x_1 - x_2|+|y_1 - y_2|\\ d_{12} = \sqrt{\sum_{i=1}^N|x_{1k} - x_{2k}|} d12=x1x2+y1y2d12=i=1Nx1kx2k

(三)、切比雪夫距离

d 12 = m a x ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ) d 12 = m a x ( ∣ x 1 i − x 2 i ∣ ) d_{12} = max(|x_1 - x_2|, |y_1 - y_2)\\ d_{12} = max(|x_{1i} - x_{2i}|) d12=max(x1x2,y1y2)d12=max(x1ix2i)

(四)、闵式距离

d 12 = ∑ i = 1 N ∣ x 1 k − x 2 k ∣ p p d_{12} = \sqrt[p]{\sum_{i=1}^N|x_{1k} - x_{2k}|^p} d12=pi=1Nx1kx2kp

p是一个变参数:

  • p=1时,就是曼哈顿距离
  • p=2时,就是欧式距离
  • p->∞时,就是切比雪夫距离

4、特征预处理

特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级容易影响(支配)目标结果,使得一些模型(算法)无法学习到其它的特征。

(一)、归一化

X ‘ = x − m i n m a x − m i n X ‘ ‘ = X ‘ ∗ ( m x − m i ) + m i X^` = \frac{x - min}{max - min}\\ X^{``} = X^` * (mx - mi) + mi X=maxminxminX‘‘=X(mxmi)+mi

数据归一化的API实现

sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )

对原始数据做处理, 获取到1个 默认[mi, mx] => [0, 1] 区间的值

例如

# 导包
from sklearn.preprocessing import MinMaxScaler  # 归一化的类# 1. 准备特征数据.  每个子列表 = 1个样本(Sample)
data = [[90, 2, 10, 40], [60, 4, 15, 45], [75, 3, 13, 46]]# 2. 创建归一化对象.
transfer = MinMaxScaler()# 3. 具体的 归一化动作.
# fit_transform(): 训练 + 转换 => 适用于 训练集.
# transform(): 直接转换 => 适用于 测试集.
new_data = transfer.fit_transform(data)# 4. 打印 归一化后的结果
print(f'归一化后, 数据集为: {new_data}')

归一化受到最大值与最小值的影响,这种方法容易受到异常数据的影响, 鲁棒性较差,适合传统精确小数据场景

(二)、标准化

X ‘ = x − m e a n σ X^` = \frac{x - mean}{\sigma} X=σxmean

  • mean为特征的平均值
  • σ 为特征的标准差

数据标准化的API实现

sklearn.preprocessing. StandardScaler()

对原始数据做处理, 转换为均值为0, 标准差为1的标准正态分布序列.

例如

# 导包
from sklearn.preprocessing import StandardScaler  # 标准化的类# 1. 准备特征数据.  每个子列表 = 1个样本(Sample)
data = [[90, 2, 10, 40], [60, 4, 15, 45], [75, 3, 13, 46]]# 2. 创建 标准化 对象.
transfer = StandardScaler()# 3. 具体的 标准化 动作.
# fit_transform(): 训练 + 转换 => 适用于 训练集.
# transform(): 直接转换 => 适用于 测试集.
new_data = transfer.fit_transform(data)# 4. 打印 标准化 后的结果
print(f'标准化后, 数据集为: {new_data}')# 5. 打印每个特征列的 平均值 和 标准差
print(f'均值: {transfer.mean_}')
print(f'方差: {transfer.var_}')

对于标准化来说,如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,标准化适用于 大数据集的 特征预处理

5、超参数选择

(一)、交叉验证

交叉验证是一种数据集的分割方法,将训练集划分为 n 份,其中一份做验证集、其他n-1份做训练集集

交叉验证法原理:将数据集划分为 cv=10 份:

1.第一次:把第一份数据做验证集,其他数据做训练

2.第二次:把第二份数据做验证集,其他数据做训练

3… 以此类推,总共训练10次,评估10次。

4.使用训练集+验证集多次评估模型,取平均值做交叉验证为模型得分

5.若k=5模型得分最好,再使用全部训练集(训练集+验证集) 对k=5模型再训练一边,再使用测试集对k=5模型做评估

交叉验证法是划分数据集的一种方法,目的就是为了得到更加准确可信的模型评分。

(二)、网格搜索

模型有很多超参数,其能力也存在很大的差异,需要手动产生很多超参数组合,来训练模型;每组超参数都采用交叉评估验证,最后选出最优参数组合建立模型。

只需要将若干参数传递给网格搜索对象,它自动就会帮我们完成不同的超参数的组合,模型训练,模型评估。最终返回一组最优的超参数。

(三)、组合

交叉验证解决模型的数据输入(数据集划分)得到更可靠的模型,网格搜索解决超参数的组合,两个组合再一起形成一个模型参数调优的解决方案。

# 导包
from sklearn.datasets import load_iris                  # 加载鸢尾花测试集的.
from sklearn.model_selection import train_test_split, GridSearchCV    # 分割训练集和测试集的, 网格搜索 => 找最优参数组合
from sklearn.preprocessing import StandardScaler        # 数据标准化的
from sklearn.neighbors import KNeighborsClassifier      # KNN算法 分类对象
from sklearn.metrics import accuracy_score              # 模型评估的, 计算模型预测的准确率# 1. 加载数据.
iris_data = load_iris()
# 2. 数据预处理, 即: 划分 训练集, 测试集.
x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2, random_state=21)
# 3. 特征工程, 即: 特征的预处理 => 数据的标准化.
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)   # 训练 + 转换 => 适用于: 训练集.
x_test = transfer.transform(x_test)         # 直接转换 => 适用于: 测试集.# 4. 模型训练.
# 4.1 创建 估计器对象.
estimator = KNeighborsClassifier()
# 4.2 定义网格搜索的参数, 即: 样本可能存在的参数组合值 => 超参数.
param_dict = {'n_neighbors': [1, 2, 3, 5, 7]}
# 4.3 创建网格搜索对象, 帮我们找到最优的参数组合.
# 参1: 估计器对象, 传入1个估计器对象, 网格搜索后, 会自动返回1个功能更加强大(最优参数)的 估计器对象.
# 参2: 网格搜索的参数, 传入1个字典, 键: 参数名, 值: 参数值列表.
# 参3: 交叉验证的次数, 指定值为: 4
estimator = GridSearchCV(estimator, param_dict, cv=5)
# 4.4 调用 估计器对象的 fit方法, 完成模型训练.
estimator.fit(x_train, y_train)# 4.5 查看网格搜索后的参数
print(f'最优组合平均分: {estimator.best_score_}')
print(f'最优估计器对象: {estimator.best_estimator_}')  # 3
print(f'具体的验证过程: {estimator.cv_results_}')
print(f'最优的参数: {estimator.best_params_}')# 5. 得到超参数最优值之后, 再次对模型进行训练.
estimator = KNeighborsClassifier(n_neighbors=3)
# 模型训练
estimator.fit(x_train, y_train)
# 模型评估
print(estimator.score(x_test, y_test))  # 0.9666666666666667

五、线性回归

1、概述

利用 回归方程(函数) 对 1个或者多个自变量(特征) 和 因变量(目标值, 标签)进行 建模分析的 思路(算法)。一个特征和一个标签的是一元线性回归,多个特征和一个标签的是多元线性回归。通常在有特征有连续标签的情况下使用。

在一元线性回归中,y=kx+b,k: 斜率, 在机器学习中叫 权重(Weight), 简称: w,b: 截距, 在机器学习中叫 偏差/偏置(Bios), 简称: b;在多元线性回归中,y = w1x1 + w2x2 + w3x3… + b => w转置 * x + b。

2、损失函数

在线性回归中,调整w和b的值找到J函数的最小值,能获得这个最小值的w和b一般就是线性回归的最佳参数值。

用来衡量 预测值 和 真实值关系的, 分类如下:

  • 最小二乘法:
    每个样本的 预估值 - 真实值 的平方和
    J ( w , b ) = ∑ i = 0 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 J(w,b) =\sum_{i=0}^m(f_{w,b}(x^{(i)}) - y^{(i)})^2 J(w,b)=i=0m(fw,b(x(i))y(i))2

  • 均方误差(Mean Square Error => MSE):
    每个样本的 预估值 - 真实值 的平方和 / 样本数

J ( w , b ) = 1 m ∑ i = 0 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 J(w,b) = \frac{1}{m}\sum_{i=0}^m(f_{w,b}(x^{(i)}) - y^{(i)})^2 J(w,b)=m1i=0m(fw,b(x(i))y(i))2

  • 平均绝对误差(Mean Absolute Error => MAE)
    每个样本的 预估值 - 真实值 的绝对值的 和 / 样本数
    J ( w , b ) = 1 m ∑ i = 0 m ∣ f w , b ( x ( i ) ) − y ( i ) ∣ J(w,b) = \frac{1}{m}\sum_{i=0}^m|f_{w,b}(x^{(i)}) - y^{(i)}| J(w,b)=m1i=0mfw,b(x(i))y(i)

使用函数会帮助自动创建线性回归模型对象:

# 导包
from sklearn.linear_model import LinearRegression# 1. 准备数据 => 训练集.
x_train = [[160], [166], [172], [174], [180]]
y_train = [56.3, 60.6, 65.1, 68.5, 75]# 2. 创建 线性回归 模型对象.
estimator = LinearRegression()# 3. 模型训练.
estimator.fit(x_train, y_train)# 4. 查看下模型的参数, 即: 斜率 和 截距.
print(f'斜率 => 也叫: 权重(weight): {estimator.coef_}')  # 0.92942177
print(f'截距 => 也叫: 偏置(Bios): {estimator.intercept_}')  # -93.27346938775514# 5. 模型预测.
x_test = [[176]]  # 准备: 测试集的 特征.
y_predict = estimator.predict(x_test)  # 预测的结果值.
print(f'预测值结果为: {y_predict}')   # [70.3047619]

3、前置知识

(一)、多特征

在上述的线性回归模型中,我们只有一个特征,但是这在现实生活中的应用场景可以说是非常稀少,一般一件事物的结果都会受到好几种特征的共同影响,所以更为泛化的回归公式一般为:
f w , b ( x ) = w 1 x 1 + w 2 x 2 + w 3 x 3 + . . . . + w n x n + b f_{w,b}(x) = w_1x_1 + w_2x_2 + w_3x_3 + ....+w_nx_n + b fw,b(x)=w1x1+w2x2+w3x3+....+wnxn+b
公式中的各个x就是事物的不同特征,w可以理解为该特征所占权重,b依旧是常数项,这些特征的共同作用下获得最终的结果。

该公式可以简化表示为:
f w → , b ( X → ) = W → ⋅ X → + b f_{\overrightarrow{w},b}(\overrightarrow{X}) = {\overrightarrow{W}} ·{\overrightarrow{X}} + b fw ,b(X )=W X +b
也就是简化为两个向量矩阵相乘。

此处需要使用numpy来对向量进行运算,
f w → , b ( X → ) = ∑ i = 1 N w j x j + b f_{\overrightarrow{w},b}(\overrightarrow{X}) = \sum_{i=1}^Nw_jx_j + b fw ,b(X )=i=1Nwjxj+b
对每个相乘的结果进行求和运算,最终得到目标结果。

在单特征当中,权重和常数项的计算公式为:
w = w − α 1 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) x ( i ) b = b − α 1 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) w = w -\alpha\frac{1}{m}\sum_{i=1}^m(f_{w,b}(x^{(i)}) - y^{(i)})x^{(i)}\\ b = b -\alpha\frac{1}{m}\sum_{i=1}^m(f_{w,b}(x^{(i)}) - y^{(i)}) w=wαm1i=1m(fw,b(x(i))y(i))x(i)b=bαm1i=1m(fw,b(x(i))y(i))
但是多特征当中权重值有多个,分别代表不同特征的权重,最终求和,所以我们需要将不同的权重做一个标识。
w 1 = w 1 − α 1 m ∑ i = 1 m ( f w → , b ( x → ( i ) ) − y ( i ) ) x 1 ( i ) w n = w n − α 1 m ∑ i = 1 m ( f w → , b ( x → ( i ) ) − y ( i ) ) x n ( i ) b = b − α 1 m ∑ i = 1 m ( f w → , b ( x → ( i ) ) − y ( i ) ) w_1 = w_1 -\alpha\frac{1}{m}\sum_{i=1}^m(f_{\overrightarrow{w},b}(\overrightarrow{x}^{(i)}) - y^{(i)})x_1^{(i)}\\ w_n = w_n -\alpha\frac{1}{m}\sum_{i=1}^m(f_{\overrightarrow{w},b}(\overrightarrow{x}^{(i)}) - y^{(i)})x_n^{(i)}\\ b = b -\alpha\frac{1}{m}\sum_{i=1}^m(f_{\overrightarrow{w},b}(\overrightarrow{x}^{(i)}) - y^{(i)}) w1=w1αm1i=1m(fw ,b(x (i))y(i))x1(i)wn=wnαm1i=1m(fw ,b(x (i))y(i))xn(i)b=bαm1i=1m(fw ,b(x (i))y(i))
这标识多个权重全部一起计算,每次从1到n更新权重值,这就是多元回归的梯度下降。

(二)、特征缩放

在几个特征值差别较大时,会对梯度下降的速度造成影响,所以我们一般会对较大或者较小的数据进行缩放处理,一般来说缩放后的范围一般在-1到1之间。

(三)、选择合适的学习率

在上文我们能得出结论,在学习率过小的时候,我们需要的迭代次数会非常的大,在学习率过大的时候,又会导致数据无法收敛,所以在学习率的选择上,我们通常会选择0.001开始,然后0.003,再0.01,依次类推,直到学习率过大或者达到1为止,每次的学习率都是上一次学习率的3倍左右,这样可以达到一个相对节省资源的状态。

4、正规方程法求解

(一)、一元线性回归

损失函数为:
J ( w , b ) = ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 = ∑ i = 1 m ( w x ( i ) + b − y ( i ) ) 2 x ( i ) 代表第 i 个样本的特征值 y ( i ) 代表第 i 个样本的预测值 J(w,b) =\sum_{i=1}^m(f_{w,b}(x^{(i)}) - y^{(i)})^2=\sum_{i=1}^m(wx^{(i)} + b - y^{(i)})^2 \\x^{(i)}代表第i个样本的特征值 \\y^{(i)}代表第i个样本的预测值 J(w,b)=i=1m(fw,b(x(i))y(i))2=i=1m(wx(i)+by(i))2x(i)代表第i个样本的特征值y(i)代表第i个样本的预测值
对上面的式子进行偏导求解。
∂ J ( w , b ) ∂ w = ∑ i = 1 m ( 2 w ( x ( i ) ) 2 + 2 b x ( i ) − 2 x ( i ) y ( i ) = 0 ∂ J ( w , b ) ∂ b = ∑ i = 1 m ( 2 w ( x ( i ) ) 2 + 2 b − 2 y ( i ) = 0 \frac{\partial J(w,b)}{\partial w} = \sum_{i=1}^m(2w(x^{(i)})^{2} + 2bx^{(i)}-2x^{(i)}y^{(i)}=0\\ \frac{\partial J(w,b)}{\partial b} = \sum_{i=1}^m(2w(x^{(i)})^{2} + 2b-2y^{(i)}=0 wJ(w,b)=i=1m(2w(x(i))2+2bx(i)2x(i)y(i)=0bJ(w,b)=i=1m(2w(x(i))2+2b2y(i)=0
然后将特征值带入,计算出 w和b的值,最终得到y=wx+b的式子

(二)、多元线性回归

根据一元损失函数易得多元损失函数为:
J ( w , b ) = ∑ i = 1 m ( w i x i + b − y i ) 2 将上述公式转为矩阵形式: ∑ i = 1 m ( f ( x i ) − y i ) 2 = ∣ ∣ X w − y ∣ ∣ 2 2 数据集为 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . . , ( x n , y n ) } J(w,b) =\sum_{i=1}^m(w_ix_{i} + b - y_{i})^2\\ 将上述公式转为矩阵形式:\sum_{i=1}^m(f(x_i)-y_i)^2=||Xw - y||_2^2\\ 数据集为D = \{(x_1,y_1),(x_2,y_2),....,(x_n,y_n)\} J(w,b)=i=1m(wixi+byi)2将上述公式转为矩阵形式:i=1m(f(xi)yi)2=∣∣Xwy22数据集为D={(x1,y1),(x2,y2),....,(xn,yn)}
再计算损失函数的最小值:
2 ( X → w − y ) ∗ X → = 0 2 ( X → w − y ) ∗ ( X → X → T ) = 0 X → T 2 ( X → w − y ) ∗ ( X → X → T ) ∗ ( X → X → T ) − 1 = 0 X → T ∗ ( X → X → T ) − 1 2 ( X → w − y ) = 0 X → w = y X → T X → w = X → T y ( X → T X → ) − 1 ( X → T X → ) ∗ w = ( X → T X → ) − 1 ∗ X → T y w = ( X → T X → ) − 1 ∗ X → T y 2(\overrightarrow Xw-y)*\overrightarrow X = 0\\ 2(\overrightarrow Xw-y)*(\overrightarrow X \overrightarrow X^T)=0\overrightarrow X^T\\ 2(\overrightarrow Xw-y)*(\overrightarrow X \overrightarrow X^T)*(\overrightarrow X \overrightarrow X^T)^{-1}=0\overrightarrow X^T*(\overrightarrow X \overrightarrow X^T)^{-1}\\ 2(\overrightarrow Xw - y)=0\\ \overrightarrow Xw=y\\ \overrightarrow X^T\overrightarrow Xw = \overrightarrow X^Ty\\ (\overrightarrow X^T \overrightarrow X)^{-1}(\overrightarrow X^T \overrightarrow X)*w=(\overrightarrow X^T \overrightarrow X)^{-1}*\overrightarrow X^Ty\\ w = (\overrightarrow X^T \overrightarrow X)^{-1}*\overrightarrow X^Ty 2(X wy)X =02(X wy)(X X T)=0X T2(X wy)(X X T)(X X T)1=0X T(X X T)12(X wy)=0X w=yX TX w=X Ty(X TX )1(X TX )w=(X TX )1X Tyw=(X TX )1X Ty
得出正规方程的解析解答案

5、梯度下降

(一)、概述

单变量函数中,梯度就是某一点切线斜率(某一点的导数);有方向为函数增长最快的方向

多变量函数中,梯度就是某一个点的偏导数;有方向:偏导数分量的向量方向

(二)、求导

w = w − α ∂ ∂ w J ( w , b ) b = b − α ∂ ∂ b J ( w , b ) α : 学习率 ( 步长 ) 不能太大 , 也不能太小 . 机器学习中: 0.001 − 0.01 w = w - \alpha\frac{\partial}{\partial{w}}J(w, b)\\ b = b - \alpha\frac{\partial}{\partial{b}}J(w, b)\\ α: 学习率(步长) 不能太大, 也不能太小. 机器学习中:0.001 - 0.01 w=wαwJ(w,b)b=bαbJ(w,b)α:学习率(步长)不能太大,也不能太小.机器学习中:0.0010.01

每次走一小步,向下降最快的方向前进(在一小步范围内最优结果的方向,或者可以理解为曲率最大的方向前进),直到找到最优解的点。所以对于学习率的选取尤为重要,如果太小可能会导致优化次数的增加,如果太大可能会导致学习函数不收敛,导致一直找不到目标数值,从而获取不到目标的最优解。

(三)、分类

  • 全梯度下降算法FGD–每次迭代,使用全部样本的梯度值,所以速度较慢。

w i + 1 = w i − α ∑ j = 0 m ( f ( w , b ) θ ( x 0 ( j ) , x 1 ( j ) , . . . , x n ( j ) ) − y j ) x i ( j ) w_{i+1} = w_i-\alpha\sum_{j=0}^m(f(w,b)_\theta(x_0^{(j)},x_1^{(j)},...,x_n^{(j)})-y_j)x_i^{(j)} wi+1=wiαj=0m(f(w,b)θ(x0(j),x1(j),...,xn(j))yj)xi(j)

  • 随机梯度下降算法SGD–每次迭代,随机选择并使用一个样本梯度值。
    w i + 1 = w i − α ( f ( w , b ) ( ( x 0 ( j ) , x 1 ( j ) , . . . , x n ( j ) ) − y j ) x i ( j ) w_{i+1} = w_i -\alpha(f(w,b)((x_0^{(j)},x_1^{(j)},...,x_n^{(j)})-y_j)x_i^{(j)} wi+1=wiα(f(w,b)((x0(j),x1(j),...,xn(j))yj)xi(j)

  • 小批量梯度下降算法mini-bantch–每次迭代时,随机选择并使用小批量的样本梯度值,从m个样本中选择x个样本进行迭代(1<x<m)。目前使用最多

w i + 1 = w i − α ∑ j = t t + x − 1 ( f ( w , b ) θ ( x 0 ( j ) , x 1 ( j ) , . . . , x n ( j ) ) − y j ) x i ( j ) 如果 b a t c h s i z e = 1 ,就变成了 S G D ;如果 b a t c h s i z e = n ,就变成了 F G D w_{i+1} = w_i-\alpha\sum_{j=t}^{t+x-1}(f(w,b)_\theta(x_0^{(j)},x_1^{(j)},...,x_n^{(j)})-y_j)x_i^{(j)}\\ 如果batchsize=1,就变成了SGD;如果batchsize=n,就变成了FGD wi+1=wiαj=tt+x1(f(w,b)θ(x0(j),x1(j),...,xn(j))yj)xi(j)如果batchsize=1,就变成了SGD;如果batchsize=n,就变成了FGD

  • 随机平均梯度下降算法SAG–每次迭代时,随机选择一个样本的梯度值和以往样本的梯度值的均值,训练出去表现不佳,优化速度较慢。

w i + 1 = w i − α n ∑ j = 0 n ( f ( w , b ) θ ( x 0 ( j ) , x 1 ( j ) , . . . , x n ( j ) ) − y j ) x i ( j ) w_{i+1} = w_i-\frac{\alpha}{n}\sum_{j=0}^n(f(w,b)_\theta(x_0^{(j)},x_1^{(j)},...,x_n^{(j)})-y_j)x_i^{(j)} wi+1=winαj=0n(f(w,b)θ(x0(j),x1(j),...,xn(j))yj)xi(j)

6、正规方程与梯度下降对比

  • 正规方程

    • 不需要学习率
    • 一次运算得出,一蹴而就
    • 应用场景:小数据量场景、精准的数据场景
    • 缺点:计算量大、容易收到噪声、特征强相关性的影响
    • 注意:X^TX的逆矩阵不存在时,无法求解
    • 注意:计算X^TX的逆矩阵非常耗时
    • 如果数据规律不是线性的,无法使用或效果不好
  • 梯度下降

    • 需要选择学习率
    • 需要迭代求解
    • 特征数量较大可以使用应用场景:更加普适,迭代的计算方式,适合于嘈杂、大数据应用场景
    • 注意:梯度下降在各种损失函数(目标函数)求解中大量使用。深度学习中更是如此,深度学习模型参数很轻松就上亿,只能通过迭代的方式求最优解。

7、模型评估

我们希望衡量预测值和真实值之间的差距,我们会用到MAE、MSE、RMSE多种测评函数进行评价

(一)、均方误差MSE–Mean Squared Error

M S E = 1 n ∑ i = 1 n ( y i − y i ^ ) 2 n 为样本数量、 y 为实际值、 y ^ 为预测值 MSE = \frac{1}{n}\sum_{i=1}^n(y_i-\hat{y_i})^2\\ n为样本数量、y为实际值、\hat{y}为预测值 MSE=n1i=1n(yiyi^)2n为样本数量、y为实际值、y^为预测值

MSE越小模型预测越准确

from sklearn.metrics import mean_squared_error
mean_squared_error(y_test,y_predict)

(二)、平均绝对误差MAE–Mean Absolute Error

M A E = 1 n ∑ i = 1 n ∣ y i − y i ^ ∣ n 为样本数量、 y 为实际值、 y ^ 为预测值 MAE = \frac{1}{n}\sum_{i=1}^n|y_i - \hat{y_i}|\\ n为样本数量、y为实际值、\hat{y}为预测值 MAE=n1i=1nyiyi^n为样本数量、y为实际值、y^为预测值

MAE越小模型预测越准确

from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_test,y_predict)

(三)、均方根误差RMSE–Root Mean Squared Error

R M S E = 1 n ∑ i = 1 n ( y i − y i ^ ) 2 n 为样本数量、 y 为实际值、 y ^ 为预测值 RMSE = \sqrt{\frac{1}{n}\sum_{i=1}^n(y_i-\hat{y_i})^2}\\ n为样本数量、y为实际值、\hat{y}为预测值 RMSE=n1i=1n(yiyi^)2 n为样本数量、y为实际值、y^为预测值

RMSE越小模型预测越准确

RMSE 是 MSE 的平方根,某些情况下比MES更有用

(四)、三种指标对比

一般使用MAE 和 RMSE 这两个指标

  • MAE反应的是“真实”的平均误差,RMSE会将误差大的数据点放大

  • 大多数情况下RMSE>MAE,RMSE > MAE都能反应真实误差,但是RMSE会对异常点更加敏感

  • 如果RMSE指标训练的非常低,模型对异常点(对噪声)也拟合的非常好,这样模型就容易过拟合了。所以评价指标要综合的看

8、经典波士顿房价预估模型

(一)、正规方程

# 导包
# from sklearn.datasets import load_boston                # 数据
from sklearn.preprocessing import StandardScaler        # 特征处理
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.linear_model import LinearRegression       # 正规方程的回归模型
from sklearn.linear_model import SGDRegressor           # 梯度下降的回归模型
from sklearn.metrics import mean_squared_error, mean_absolute_error, root_mean_squared_error          # 均方误差评估
from sklearn.linear_model import Ridge, RidgeCV
import pandas as pd
import numpy as np# 1. 加载数据集.
# 数据集的URL地址
data_url = "http://lib.stat.cmu.edu/datasets/boston"
# pandas读取数据集
raw_df = pd.read_csv(data_url, sep="\\s+", skiprows=22, header=None)
# 从数据集中获取: 特征数据
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
# 从数据集中获取: 标签数据
target = raw_df.values[1::2, 2]
# 打印结果
print(len(data), len(target))       # 506, 506# 2. 数据的预处理, 把总数据506条 => 按照8:2的比例分为训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=21)# 3. 特征工程: 特征预处理(归一化, 标准化)
# 3.1 创建 标准化对象.
transfer = StandardScaler()
# 3.2 标准化 训练集.
x_train = transfer.fit_transform(x_train)
# 3.3 标准化 测试集.
x_test = transfer.transform(x_test)
print(len(x_train), len(x_test))# 4. 模型训练.
# 4.1 创建 线性回归模型对象 => 正规方程的方式.
# 参数: fit_intercept 意思是 是否需要计算截距值(偏置), 默认是: True
estimator = LinearRegression(fit_intercept=True)
# 4.2 模型训练.
estimator.fit(x_train, y_train)     # 训练集的特征, 训练集的标签
# 4.3 打印 模型的 权重和偏置.
print(f'权重: {estimator.coef_}')
print(f'偏置: {estimator.intercept_}')# 5. 模型预测.
y_predict = estimator.predict(x_test)   # 测试集的特征
print(f'模型预测结果: {y_predict}')# 6. 模型评估.
# 6.1 基于 预测值(y_predict) 和 真实值(y_test)计算, 模型的: 均方误差(Mean Square Error => MSE)
print(f'该模型的均方误差: {mean_squared_error(y_test, y_predict)}')     # 26.82540057393935
# 6.2 平均绝对误差
print(f'该模型的平均绝对误差: {mean_absolute_error(y_test, y_predict)}')
# 6.3 均方根误差
print(f'该模型的均方根误差: {root_mean_squared_error(y_test, y_predict)}')

(二)、梯度下降

# 导包
# from sklearn.datasets import load_boston                # 数据
from sklearn.preprocessing import StandardScaler        # 特征处理
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.linear_model import LinearRegression       # 正规方程的回归模型
from sklearn.linear_model import SGDRegressor           # 梯度下降的回归模型
from sklearn.metrics import mean_squared_error, mean_absolute_error, root_mean_squared_error          # 均方误差评估
from sklearn.linear_model import Ridge, RidgeCV
import pandas as pd
import numpy as np# 1. 加载数据集.
# 数据集的URL地址
data_url = "http://lib.stat.cmu.edu/datasets/boston"
# pandas读取数据集
raw_df = pd.read_csv(data_url, sep="\\s+", skiprows=22, header=None)
# 从数据集中获取: 特征数据
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
# 从数据集中获取: 标签数据
target = raw_df.values[1::2, 2]
# 打印结果
print(len(data), len(target))       # 506, 506# 2. 数据的预处理, 把总数据506条 => 按照8:2的比例分为训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(data,target, test_size=0.2, random_state=21)# 3. 特征工程: 特征预处理(归一化, 标准化)
# 3.1 创建 标准化对象.
transfer = StandardScaler()
# 3.2 标准化 训练集.
x_train = transfer.fit_transform(x_train)
# 3.3 标准化 测试集.
x_test = transfer.transform(x_test)
print(len(x_train), len(x_test))# 4. 模型训练.
# 4.1 创建 线性回归模型对象 => 梯度下降的方式.   简单理解梯度下降: 新的点 = 当前点 - 学习率 * 梯度
# 参数: fit_intercept 意思是 是否需要计算截距值(偏置), 默认是: True
# estimator = LinearRegression(fit_intercept=True)      # 正规方程-线性回归模型对象.
# constant: 常量, 即: 学习率的值.
estimator = SGDRegressor(fit_intercept=True,learning_rate='constant', eta0=0.001)
# 4.2 模型训练.
estimator.fit(x_train, y_train)     # 训练集的特征, 训练集的标签
# 4.3 打印 模型的 权重和偏置.
print(f'权重: {estimator.coef_}')
print(f'偏置: {estimator.intercept_}')# 5. 模型预测.
y_predict = estimator.predict(x_test)   # 测试集的特征
print(f'模型预测结果: {y_predict}')# 6. 模型评估.
# 6.1 基于 预测值(y_predict) 和 真实值(y_test)计算, 模型的: 均方误差(Mean Square Error => MSE)
print(f'该模型的均方误差: {mean_squared_error(y_test, y_predict)}')     # 26.82540057393935
# 6.2 平均绝对误差
print(f'该模型的平均绝对误差: {mean_absolute_error(y_test, y_predict)}')
# 6.3 均方根误差
print(f'该模型的均方根误差: {root_mean_squared_error(y_test, y_predict)}')

9、欠拟合和过拟合

(一)、概述

欠拟合:

模型在训练集上表现不好,在测试集上也表现不好。模型过于简单,在训练集和测试集上的误差都较大

过拟合:

模型在训练集上表现好,在测试集上表现不好。模型过于复杂,在训练集上误差较小,而测试集上误差较大

(二)、出现原因和解决方案

(1)、欠拟合

出现原因:

  • 学习到数据的特征过少

解决方案:

  • 添加其他特征

    • 有时出现欠拟合是因为特征项不够导致的,可以添加其他特征项来解决

    • “组合”、“泛化”、“相关性”三类特征是特征添加的重要手段

  • 添加多项式特征项

    • 模型过于简单时的常用套路,例如将线性模型通过添加二次项或三次项使模型泛化能力更强
(2)、过拟合

出现原因:

  • 原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点

解决方案:

  • 重新清洗数据
    • 对于过多异常点数据、数据不纯的地方再处理
  • 增大数据的训练量
    • 对原来的数据训练的太过了,增加数据量的情况下,会缓解
  • 正则化
    • 解决模型过拟合的方法,在机器学习、深度学习中大量使用
  • 减少特征维度,防止维灾难
    • 由于特征多,样本数量少,导致学习不充分,泛化能力差。

(三)、正则化

(1)、概述

在模型训练时,数据中有些特征影响模型复杂度、或者某个特征的异常值较多, 所以要尽量减少这个特征的影响(甚至删除某个特征的影响),这就是正则化

(2)、作用

在损失函数中增加正则化项分为L1正则化、L2正则化。分别可以筛出异常值和减小异常值影响。

①L1正则化

J ( w ) = M S E ( w ) + α ∑ i = 1 n ∣ w i ∣ α 叫做惩罚系数 J(w) = MSE(w) +\alpha\sum_{i=1}^n|w_i|\\ \alpha叫做惩罚系数 J(w)=MSE(w)+αi=1nwiα叫做惩罚系数

惩罚系数越大则权重调整的幅度就越大,即:表示对特征权重惩罚力度就越大

L1 正则化会使得权重趋向于 0,甚至等于 0,使得某些特征失效,达到特征筛选的目的

使用 L1 正则化的线性回归模型是 Lasso 回归,Lasso回归L1正则 会将高次方项系数变为0

from sklearn.linear_model import Lasso
②L2正则化

J ( w ) = M S E ( w ) + α ∑ i = 1 n w i 2 α 叫做惩罚系数 J(w)=MSE(w)+\alpha\sum_{i=1}^nw_i^2\\ \alpha叫做惩罚系数 J(w)=MSE(w)+αi=1nwi2α叫做惩罚系数

惩罚系数越大则权重调整的幅度就越大,即:表示对特征权重惩罚力度就越大

L2 正则化会使得权重趋向于 0,一般不等于 0

使用 L2 正则化的线性回归模型是岭回归,Ridge线性回归l2正则不会将系数变为0 但是对高次方项系数影响较大

from sklearn.linear_model import Ridge

在工程开发中一般倾向使用L2正则。

(四)、代码模拟

# 导包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error # 计算均方误差
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge, Lasso
(1)、欠拟合
# 1. 定义函数, 表示: 欠拟合.
def dm01_欠拟合():# 1. 准备数据.# 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.np.random.seed(21)# x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.x = np.random.uniform(-3, 3, size=100)# y: 表示标签(目标值), 线性关系: y = 0.5x² + x + 2 + 正态分布 +  噪声.#  np.random.normal(0, 1, size=100) 意思是: 均值为0, 标准差为1, 生成100个.y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)# 模型训练.# 2. 创建 线性回归-正规方程 模型对象.estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.# 3. 对数据集做处理.X = x.reshape(-1, 1)# print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]# print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]# 4. 模型训练.estimator.fit(X, y)     # 这里传的是, 处理后的x的值, 即: 二维数组.# 5. 模型预测.y_predict = estimator.predict(X)print(f'预测值为: {y_predict}')# 6. 模型评估.print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 2.0683653437315512# 7. 数据可视化, 绘制图像.plt.scatter(x, y)             # 基于: 原始的x(特征), y值(真实值)绘制 散点图.plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)plt.show()
(2)、过拟合
# 2. 定义函数, 表示: 过拟合.
def dm02_过拟合():# 1. 准备数据.# 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.np.random.seed(21)# x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.x = np.random.uniform(-3, 3, size=100)# y: 表示标签(目标值), 线性关系: y = 0.5x² + x + 2 + 正态分布 +  噪声.#  np.random.normal(0, 1, size=100) 意思是: 均值为0, 标准差为1, 生成100个.y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)# 模型训练.# 2. 创建 线性回归-正规方程 模型对象.estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.# 3. 对数据集做处理.# 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]X = x.reshape(-1, 1)# 3.2 拼接: x, x的平方, x的立方, x的四次方..., 把数据从 [[1], [2], [3]] => [[1, 1....], [2, 4, 8, 16, 32, 64...], [3, 9, 27...]]   一元线性回归 => 二元线性回归X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])   # 继续增加 最高次项print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]print(f'处理后 X2 => {X3}')    # 处理后: X = [[1], [2], [3]]# 4. 模型训练.estimator.fit(X3, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 多元线性回归# 5. 模型预测.y_predict = estimator.predict(X3)print(f'预测值为: {y_predict}')# 6. 模型评估.print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 0.9646255969834893# 7. 数据可视化, 绘制图像.plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.# 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.# plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)# np.sort(x): 按照x的值 升序排列.# np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)plt.show()
(3)、刚好拟合
# 3. 定义函数, 表示: 正好拟合.
def dm03_正好拟合():# 1. 准备数据.# 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.np.random.seed(21)# x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.x = np.random.uniform(-3, 3, size=100)# y: 表示标签(目标值), 线性关系: y = 0.5x² + x + 2 + 正态分布 +  噪声.#  np.random.normal(0, 1, size=100) 意思是: 均值为0, 标准差为1, 生成100个.y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)# 模型训练.# 2. 创建 线性回归-正规方程 模型对象.estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.# 3. 对数据集做处理.# 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]X = x.reshape(-1, 1)# 3.2 拼接: x 和 x的平方, 把数据从 [[1], [2], [3]] => [[1, 1], [2, 4], [3, 9]]   一元线性回归 => 二元线性回归X2 = np.hstack([X, X ** 2])   #print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]print(f'处理后 X2 => {X2}')    # 处理后: X = [[1], [2], [3]]# 4. 模型训练.estimator.fit(X2, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 二元线性回归# 5. 模型预测.y_predict = estimator.predict(X2)print(f'预测值为: {y_predict}')# 6. 模型评估.print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 1.0009503498374301# 7. 数据可视化, 绘制图像.plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.# 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.# plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)# np.sort(x): 按照x的值 升序排列.# np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)plt.show()
(4)、L1正则化–Lasso回归
# 4. 定义函数, 表示: L1正则化 => 解决 过拟合问题的, 降低模型复杂度, 可能会使得权重变为0 => 特征选取.
def dm04_L1正则化():# 1. 准备数据.# 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.np.random.seed(21)# x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.x = np.random.uniform(-3, 3, size=100)# y: 表示标签(目标值), 线性关系: y = 0.5x² + x + 2 + 正态分布 +  噪声.#  np.random.normal(0, 1, size=100) 意思是: 均值为0, 标准差为1, 生成100个.y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)# 模型训练.# 2. 创建 线性回归-正规方程 模型对象.# estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.# 2. 创建 线性回归-L1正则化 模型对象.estimator = Lasso(alpha=0.1)    # alpha: 正则化参数, 其值越大, 则正则化程度越高, 即: 权重值越小, 则越容易被截断为0.# 3. 对数据集做处理.# 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]X = x.reshape(-1, 1)# 3.2 拼接: x, x的平方, x的立方, x的四次方..., 把数据从 [[1], [2], [3]] => [[1, 1....], [2, 4, 8, 16, 32, 64...], [3, 9, 27...]]   一元线性回归 => 二元线性回归X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])   # 继续增加 最高次项print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]print(f'处理后 X2 => {X3}')    # 处理后: X = [[1], [2], [3]]# 4. 模型训练.estimator.fit(X3, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 多元线性回归# 5. 模型预测.y_predict = estimator.predict(X3)print(f'预测值为: {y_predict}')# 6. 模型评估.print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 1.026270345364126# 7. 数据可视化, 绘制图像.plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.# 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.# plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)# np.sort(x): 按照x的值 升序排列.# np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)plt.show()
(5)、L2正则化–Ridge回归
# 5. 定义函数, 表示: L2正则化 => 解决 过拟合问题的, 降低模型复杂度. 会使得权重趋向于0, 不会变为0.
def dm05_L2正则化():# 1. 准备数据.# 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.np.random.seed(21)# x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.x = np.random.uniform(-3, 3, size=100)# y: 表示标签(目标值), 线性关系: y = 0.5x² + x + 2 + 正态分布 +  噪声.#  np.random.normal(0, 1, size=100) 意思是: 均值为0, 标准差为1, 生成100个.y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)# 模型训练.# 2. 创建 线性回归-正规方程 模型对象.# estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.# 2. 创建 线性回归-L2正则化 模型对象.estimator = Ridge(alpha=0.1)    # alpha: 正则化参数, 其值越大, 则正则化程度越高, 即: 权重值越小, 则越容易被截断为0.# 3. 对数据集做处理.# 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]X = x.reshape(-1, 1)# 3.2 拼接: x, x的平方, x的立方, x的四次方..., 把数据从 [[1], [2], [3]] => [[1, 1....], [2, 4, 8, 16, 32, 64...], [3, 9, 27...]]   一元线性回归 => 二元线性回归X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])   # 继续增加 最高次项print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]print(f'处理后 X2 => {X3}')    # 处理后: X = [[1], [2], [3]]# 4. 模型训练.estimator.fit(X3, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 多元线性回归# 5. 模型预测.y_predict = estimator.predict(X3)print(f'预测值为: {y_predict}')# 6. 模型评估.print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 0.964988964298911# 7. 数据可视化, 绘制图像.plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.# 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.# plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)# np.sort(x): 按照x的值 升序排列.# np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)plt.show()

六、逻辑回归

1、概述

一种分类模型,将线性回归的输出作为逻辑回归的输入,利用sigmoid函数做转换,输出(0,1)之间的值。

利用线性模型
f ( x ) = w T x + b f(x)=w^Tx + b f(x)=wTx+b
根据特性的重要性计算出一个值,再使用sigmoid函数将f(x)的输出值映射出概率值,设置阈值为0.5,输出概率值大于0.5,则将未知样本输出为1类,否则为0类。
逻辑回归的假设函数 : h ( w ) = s i g m o i d ( w T x + b ) 逻辑回归的假设函数:h(w) = sigmoid(w^Tx + b) 逻辑回归的假设函数:h(w)=sigmoid(wTx+b)

2、损失函数

L o s s ( L ) = − ∑ i = 1 m ( y i l o g ( p i ) + ( 1 − y i ) l o g ( 1 − p i ) ) p i = s i g m o i d ( w T x + b ) 是逻辑回归的输出结果 Loss(L)=-\sum_{i=1}^m(y_ilog(p_i)+(1-y_i)log(1-p_i))\\ p_i=sigmoid(w^Tx + b)是逻辑回归的输出结果 Loss(L)=i=1m(yilog(pi)+(1yi)log(1pi))pi=sigmoid(wTx+b)是逻辑回归的输出结果

损失函数的工作原理:每个样本预测值有A、B两个类别,真实类别对应的位置,概率值越大越好。

当只有一个样本时,他的概率为:
L = { p i f y = 1 1 − p i f y = 0 L=\begin{cases}p\ \ \ \ if\ \ \ \ y=1 \\1-p\ \ \ \ if\ \ \ \ y=0 \end{cases} L={p    if    y=11p    if    y=0
当样本时1类别时模型预测的p越大越好,当样本时0类别时模型预测的(1-p)越大越好

当有n个样本时,他的概率为:
p = p ( y 1 ∣ x 1 ) p ( y 2 ∣ x 2 ) . . . p ( y n ∣ x n ) = ∏ i = 1 n p y i ( 1 − p ) 1 − y i p i 表示每个样本被分类正确时的概率 y i 表示每个样本真实类别 ( 0 或 1 ) p=p(y_1|x_1)p(y_2|x_2)...p(y_n|x_n)=\prod_{i=1}^{n}p^{y_i}(1-p)^{1-{y_i}}\\ p_i表示每个样本被分类正确时的概率\\ y_i表示每个样本真实类别(0或1) p=p(y1x1)p(y2x2)...p(ynxn)=i=1npyi(1p)1yipi表示每个样本被分类正确时的概率yi表示每个样本真实类别(01)
问题转化为:让联合概率时间最大时,估计w,b的权重参数,这就是极大似然估计。

极大似然损失转为对数似然损失,取log优化损失函数。
L o s s ( L ) = ∑ i = 1 m ( y i l o g ( p i ) + ( 1 − y i ) l o g ( 1 − p i ) ) p i = 1 1 − e w T x + b Loss(L)=\sum_{i=1}^m(y_ilog(p_i) + (1 - y_i)log(1-p_i))\\ p_i=\frac{1}{1-e^{w^Tx+b}} Loss(L)=i=1m(yilog(pi)+(1yi)log(1pi))pi=1ewTx+b1
最大化问题转化为最小问题
L o s s ( L ) = − ∑ i = 1 m ( y i l o g ( p i ) + ( 1 − y i ) l o g ( 1 − p i ) ) Loss(L)=-\sum_{i=1}^m(y_ilog(p_i)+(1 -y_i)log(1-p_i)) Loss(L)=i=1m(yilog(pi)+(1yi)log(1pi))
再使用梯度下降优化算法,更新逻辑回归算法的权重系数。

3、分类评估

(一)、混淆矩阵

正例假例
正例真正例TP伪反例FN
假例伪正例FP真反例TN

上侧为预测结果,左侧为真实结果

  • 真实值是 正例 的样本中,被分类为 正例 的样本数量有多少,叫做真正例(TP,True Positive)
  • 真实值是 正例 的样本中,被分类为 假例 的样本数量有多少,叫做伪反例(FN,False Negative)
  • 真实值是 假例 的样本中,被分类为 正例 的样本数量有多少,叫做伪正例(FP,False Positive)
  • 真实值是 假例 的样本中,被分类为 假例 的样本数量有多少,叫做真反例(TN,True Negative)
from sklearn.metrics import confusion_matrix

(二)、精确率–precision

查准率,对正例样本的预测准确率。

计算方式:
P = T P T P + F P P = \frac{TP}{TP+FP} P=TP+FPTP
也就是预测结果中确实为正例的比例。

精确率是指预测为正例中实际为正例的比例

from sklearn.metrics import precision_score

(三)、召回率–Recall

查全率,预测真正例样本占所有真实正例样本的比例。

计算方式:
P = T P T P + F N P=\frac{TP}{TP+FN} P=TP+FNTP
也就是预测结果中能对实际正例判断正确的比例。

召回率是指实际为正例中被预测为正例的比例

from sklearn.metrics import recall_score

(四)、F1-score

对模型的精度、召回率都有要求,计算模型在这两个评估方向的综合预测能力
p = 2 ∗ p r e c i s i o n ∗ r e c a l l p r e c i s i o n + r e c a l l p = \frac{2*precision*recall}{precision+recall} p=precision+recall2precisionrecall
F1 值是精确率和召回率的调和平均数

from sklearn.metrics import f1_score

(五)、ROC曲线

在ROC曲线中,我们需要考虑正负样本的情况:

  • 正样本中被预测为正样本的概率,即:TPR (True Positive Rate)
  • 负样本中被预测为正样本的概率,即:FPR (False Positive Rate)

是一种常用于评估分类模型性能的可视化工具。ROC曲线以模型的真正率TPR为纵轴,假正率FPR为横轴,它将模型在不同阈值下的表现以曲线的形式展现出来。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ROC 曲线图像中,4 个特殊点的含义:

  1. (0, 0) 表示所有的正样本都预测为错误,所有的负样本都预测正确
  2. (1, 0) 表示所有的正样本都预测错误,所有的负样本都预测错误
  3. (1, 1) 表示所有的正样本都预测正确,所有的负样本都预测错误
  4. (0, 1) 表示所有的正样本都预测正确,所有的负样本都预测正确

从图像上看,曲线越靠近 (0,1) 点则模型对正负样本的辨别能力就越强

(六)、AUC指标

AUC 是 ROC 曲线下面的面积,该值越大,则模型的辨别能力就越强,AUC 范围在 [0, 1] 之间

当AUC=0.5时,表示分类器的性能等同于随机猜测

当AUC=1时,表示分类器的性能完美,能够完全正确地将正负例分类

(七)、例子

# 导包
import pandas as pd
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score# 1. 准备 样本集(10条), 6个 => 恶性肿瘤,  4个 => 良性肿瘤.    即: 训练集的标签.
y_train = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性', '良性', '良性', '良性']
# 2. 准备标签.
label = ['恶性', '良性']
dataframe_label = ['恶性(正例)', '良性(假例)']# 3. 准备预测值, 即: 模型A => 预测对了3个恶性肿瘤, 预测对了4个良性肿瘤.
y_predict_A = ['恶性', '恶性', '恶性', '良性', '良性', '良性', '良性', '良性', '良性', '良性']# 4. 准备预测值, 即: 模型B => 预测对了6个恶性肿瘤, 预测对了1个良性肿瘤.
y_predict_B = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性']# 5. 基于模型A, 构建: 混淆矩阵(confusion_matrix)
# 参1: 真实值, 参2: 预测值, 参3: 模型标签
confusion_matrix_A = confusion_matrix(y_train, y_predict_A, labels=label)
print(f'混淆矩阵A: \n {confusion_matrix_A}')# 6. 把上述的混淆矩阵, 转成 DataFrame即可.
df_A = pd.DataFrame(confusion_matrix_A, index=dataframe_label, columns=dataframe_label)
print(f'DataFrame对象A: \n {df_A}')# 7. 基于模型B, 构建: 混淆矩阵(confusion_matrix), 然后转成DF对象.
confusion_matrix_B = confusion_matrix(y_train, y_predict_B, labels=label)
print(f'混淆矩阵B: \n {confusion_matrix_B}')# 把上述的混淆矩阵, 转成 DataFrame即可.
df_B = pd.DataFrame(confusion_matrix_B, index=dataframe_label, columns=dataframe_label)
print(f'DataFrame对象B: \n {df_B}')# 8. 分别计算 模型A 和 模型B的 精确率
# 参1: 真实值, 参2: 预测值, 参3: 正例标签
print(f'模型A的精确率: {precision_score(y_train, y_predict_A, pos_label="恶性")}')  # 1.0
print(f'模型B的精确率: {precision_score(y_train, y_predict_B, pos_label="恶性")}')  # 0.6666666666666666# 9. 分别计算 模型A 和 模型B的 召回率
print(f'模型A的召回率(查全率): {recall_score(y_train, y_predict_A, pos_label="恶性")}')  # 1.0
print(f'模型B的召回率(查全率): {recall_score(y_train, y_predict_B, pos_label="恶性")}')  # 0.6666666666666666# 10. 分别计算 模型A 和 模型B的 F1值.
print(f'模型A的F1-Score(F1值): {f1_score(y_train, y_predict_A, pos_label="恶性")}')  # 0.6666666666666666
print(f'模型B的F1-Score(F1值): {f1_score(y_train, y_predict_B, pos_label="恶性")}')  # 0.8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1559124.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

公司防泄密软件哪个好?6款公司内部文件防泄密软件,2024超好用推荐!

企业的核心机密就如同生命之源&#xff0c;然而&#xff0c;数据泄露的风险也随之而来&#xff0c;让不少企业头疼不已。 面对这一挑战&#xff0c;选择一款高效、可靠的防泄密软件显得尤为重要。 那么&#xff0c;公司防泄密软件哪个好&#xff1f; 接下来&#xff0c;就让我…

posix接口与system V接口及其异同

POSIX接口和System V接口是用于多线程和进程间通信的两种主要编程接口。它们各自有不同的特点、功能和适用场景。以下是对这两种接口的详细介绍及其异同点。 POSIX接口 特点 标准化: POSIX&#xff08;可移植操作系统接口&#xff09;是由IEEE制定的标准&#xff0c;旨在提供统…

​ ​视觉任务大一统!图像生成,编辑,翻译三合一!全能视觉助手PixWizard来袭!

文章链接&#xff1a;https://arxiv.org/pdf/2409.15278 github链接&#xff1a;https://github.com/AFeng-x/PixWizard 亮点直击 任务统一&#xff1a;针对视觉任务的多样性&#xff0c;提出将其框架化为图像到图像的转换问题&#xff0c;并通过后处理将生成的可视化效果转化…

瑞华技术募资额巨降过半:业绩大幅下滑,信用期外应收账款占比高

《港湾商业观察》黄懿 上市的节奏有快有慢&#xff0c;常州瑞华化工工程技术股份有限公司&#xff08;下称“瑞华技术”&#xff0c;920099.BJ&#xff09;自2023年3月被北交所受理后&#xff0c;于2024年8月29日获得注册批文&#xff0c;9月25日正式挂牌上市。 据了解&#…

大学生课程设计报告--基于JavaGUI的贪吃蛇

前言 ​ 贪吃蛇游戏是一个基础且经典的视频游戏,它适合作为学习编程的人进行一些更深入的学习,可以更加了解关于循环,函数的使用,以及面向对象是如何应用到实际项目中的; ​ 不仅如此,贪吃蛇游戏的规则在思考后可以拆分,有利于学生将更多精力去设计游戏的核心逻辑,而…

前端性能优化全面指南

前端性能优化是提升用户体验的关键&#xff0c;页面加载速度、响应时间和交互流畅度直接影响用户的留存率和满意度。以下是常用的前端性能优化方法&#xff0c;从网络层、资源加载、JavaScript 执行、渲染性能等方面进行全方位优化。 减少 HTTP 请求 合并文件&#xff1a;将多…

文献下载/影响因子查询/文献检索/文献翻译平台推荐

文献下载平台 科研通 文献互助平台 - 科研通(AbleSci.com) 每天签到可领10积分&#xff0c;右上角求助文献&#xff0c;一篇10积分&#xff0c;基本实现免费下载。 尽量输入doi&#xff08;类似文献id&#xff09;&#xff0c;如果没有doi则输入标题作者摘要等信息&#xff0…

YOLO11模型推理 | 目标检测与跟踪 | 实例分割 | 关键点估计 | OBB旋转目标检测

前言 本文分享YOLO11的模型推理&#xff0c;检测任务包括物体分类、目标检测与跟踪、实例分割 、关键点估计、旋转目标检测等。 首先安装YOLO11 官方默认安装方式 通过运行 pip install ultralytics 来快速安装 Ultralytics 包 安装要求&#xff1a; Python 版本要求&…

南京大学《软件分析》李越, 谭添——1. 导论

导论 主要概念: soundcompletePL领域概述 动手学习 本节无 文章目录 导论1. PL(Programming Language) 程序设计语言1.1 程序设计语言的三大研究方向1.2 与静态分析相关方向的介绍与对比静态程序分析动态软件测试形式化(formal)语义验证(verification) 2. 静态分析:2.1莱斯…

这个问题做项目的时给某些客户普及过,这里再给你普及一下

有些因素不是地理概念&#xff0c;没错&#xff01;但与地理有关&#xff01;可以通过地理位置将他们链接起来&#xff0c;再结合其它业务数据&#xff0c;完成数据分析&#xff01;例如百度地图会将&#xff1a;餐饮、文化、交通、住宿、甚至价格、天气与位置关联分析&#xf…

超越单线程:Web Worker 在前端性能中的角色

在当今快速发展的数字时代&#xff0c;用户对网页性能的期待已经达到了前所未有的高度&#xff0c;想象一下&#xff0c;当你打开一个网站&#xff0c;瞬间加载、流畅操作&#xff0c;没有任何卡顿和延迟&#xff0c;这种体验无疑会让你倍感惊喜。然而在前端开发中&#xff0c;…

@Service代替@Controller注解来标注到控制层的场景?

在SpringBoot开发中&#xff0c;Controller和Service基本上是日常开发中使用的最频繁的两个注解。但你有没考虑过Service代替Controller注解来标注到控制层的场景&#xff1f;换言之&#xff0c;经过Service标注的控制层能否实现将用户请求分发到服务层的功能&#xff1f; 前言…

【斯坦福CS144】Lab5

一、实验目的 在现有的NetworkInterface基础上实现一个IP路由器。 二、实验内容 在本实验中&#xff0c;你将在现有的NetworkInterface基础上实现一个IP路由器&#xff0c;从而结束本课程。路由器有几个网络接口&#xff0c;可以在其中任何一个接口上接收互联网数据报。路由…

搜狗翻译体验,2024四大翻译工具解析!

为了满足广大用户的需求&#xff0c;市面上涌现出了众多优秀的翻译工具&#xff0c;福昕在线翻译、福昕翻译客户端、海鲸AI翻译、搜狗翻译等。今天&#xff0c;我们就来对比一下这些翻译工具&#xff0c;看看它们各自的特点和优势。 福昕在线翻译&#xff1a;专业精准&#xf…

高效开发,低代码平台如何助力构建内部工具

Zoho Creator是低代码平台&#xff0c;助力快速构建内部工具&#xff0c;如审批、订单、销售管理等&#xff0c;提升生产力、客户满意度&#xff0c;并减轻管理负担。平台提供拖放界面、集成数据库等功能&#xff0c;入选Gartner低代码平台“魔力象限”。 一、什么是内部工具&a…

虚拟机没有网络怎么解决

CentOS7为例 进入虚拟网络编辑器 1.更改设置 2.选中NAT模式点击3点击移除网络 4添加网络&#xff0c;随便选一个 5.点开NAT设置&#xff0c;记住网关 6.DHCP设置&#xff0c;注意虚拟机设置ip必须在起始ip和结束ip范围内 进入虚拟机网络适配器&#xff0c;自定义选中第4步操作…

五、Python基础语法(程序的输入和输出)

一、输入 输入&#xff1a;输入就是获取键盘输入的数据&#xff0c;使用input()函数。代码会从上往下执行&#xff0c;当遇到input()函数&#xff0c;就会暂停执行&#xff0c;输入内容后&#xff0c;敲回车键&#xff0c;表示本次的输入结束。input函数得到的数据类型都是字符…

python none代表什么

python中None代表一个特殊的空值&#xff0c;即为一个空对象&#xff0c;没有任何的值。 一般用于assert&#xff0c;判断&#xff0c;函数无返回时的默认&#xff0c;具体如下&#xff1a; 1、assert断言&#xff1a; mylist [a, b, c] >>> assert len(mylist) is…

用包目录结构Python脚本,简陋而强大

模块清晰易于管理&#xff0c;模块代码以*.py脚本呈现&#xff0c;方便维护和扩展。 (笔记模板由python脚本于2024年10月09日 18:21:52创建&#xff0c;本篇笔记适合喜欢Python和编程的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ …

java内存控制

Java 内存控制是一个相对复杂但至关重要的主题&#xff0c;它涉及到如何高效地管理Java应用程序中的内存资源。在Java中&#xff0c;内存管理主要由Java虚拟机&#xff08;JVM&#xff09;负责&#xff0c;包括内存的分配和回收。尽管如此&#xff0c;作为开发者&#xff0c;我…