我的学记|刘航宇的博客 - 机器学习
type: channel
link: https://ee.ac.cn/index.php/tag/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/
items: 机器学习/深度学习-训练过程讲解acc/loss/val_acc/val_loss分析
items: 泛化能力，过拟合，欠拟合，不收敛，奥卡姆剃刀
items: AI: 机器学习必须懂的几个术语：Label、Feature、Model...
items: 机器学习/深度学习-10个激活函数详解
items: Python-BP神经网络实现单特征多分类
items: Python机器学习- 鸢尾花分类
items: Windows安装Jupyter Notebook及机器学习的库
items: 机器学习代码实现:线性回归与岭回归

机器学习/深度学习-训练过程讲解acc/loss/val_acc/val_loss分析
type: item
date: 2024-01-20T17:46:58+08:00
description: 计算loss是会把所有loss层的loss相加。那么如何选取一个较为理想的medel？单独观察训练集loss曲线loss出现NAN联合观察loss曲线和accTensorFlow中loss与val_loss、accuracy和val_accuracy含义震荡修复计算loss是会把所有loss层的loss相加。从验证集误差是和测试集误差的角度分析其实你这个问题就是个伪命题，如果我们刻意的去在训练集上拟合模型，使其准确率达到很高的高度，或者说尽量在验证集合上表现的好，都是相悖的。因为我们不能为了某一特定数据集来刻意拟合，因为模型预测数据是不一定就在这个训练或者验证集合的空间中。还有，如果这个model预测集合acc20% 训练集合acc19% （即训练集精度低于测试集精度），那么这个模型肯定是不好的。还有一点需要注意，就是千万不能为了拟合测试集合而去更改模型，测试集合应该每次都有不同。那么如何选取一个较为理想的medel？首先，要有一个期望的准确率，通过不同模型的实验，找到最能接近的；然后，选定模型后进行参数调优；那么我们要尽可能的提高model的准确率，同时提高其泛化的能力，不能单一看某一指标，此时可参考 准确率、召回率、虚警率、F1Score等指标综合评判。或者采用多重验证随机划分训练、预测、验证集合，多次随机后找到最优参数。有时候训练集合误差很低，但是泛化能力极差，产生过拟合，有时候验证集合误差很低，但是可能验证集合无法代表所有的样本，有特殊性或者其他异常点较多。所以模型问题不能单一从你这两点来评判。一般而言，训练集loss < 验证集loss <测试集loss因为网络 [已见过] 所有训练集samples，故最低。而网络用验证集作为反馈来调节参数，相当于参考了验证集samples中的信息（间接 [已见过]）。又因为网络没有任何测试集的信息，所以测试结果一般而言最差。不过这都不是绝对的，有不符合这个一般现象的task，而我们不可以说哪种情况更“好”。多数情况验证集上错误率更低一点。因为是选择在验证集上准确率最高的模型来进行测试。考虑到数据的随机性，在验证集上准确率最高的模型在测试集上不一定是最高的，所以算出来的指标通常验证集会比测试集上好一点。但是实际情况下都有可能，特别是数据量不太大的时候。样本集合的数据也只是近似整体的分布，肯定会有波动。一个好的网络，二者的差距应该是很低的。但一般情况下因为网络不可避免地存在一定程度上的过拟合，所以肯定是train_loss低于test_lost，但如果低太多，就得考虑是过拟合的问题还是因为样本的特征空间不统一的问题。一般训练集不大时，最终训练的网络及容易过拟合，也就是说train-loss一定会收敛，但是test-loss不会收敛；训练时的loss会低于test的loss大概1~2个数量级，通常是10倍左右。{lamp/}单独观察训练集loss曲线 1）如果你的 learning_rate_policy 是 step 或者其他变化类型的话, loss 曲线可以帮助你选择一个比较合适的 stepsize； 2）如果loss曲线表现出线性（下降缓慢）表明学习率太低； 3）如果loss不再下降，表明学习率太高陷入局部最小值； 4）曲线的宽度和batch size有关，如果宽度太宽，说明相邻batch间的变化太大，应该减小batch size。可能导致不收敛的问题（如loss为87.3365，loss居高不下等）的解决方案 1）在caffe中可以在solver里面设置：debug_info: true,看看各个层的data和diff是什么值，一般这个时候那些值不是NAN（无效数字）就是INF（无穷大）； 2）检查数据标签是否从0开始并且连续； 3）把学习率base_lr调低； 4）数据问题，lmdb生成有误； 5）中间层没有归一化，导致经过几层后，输出的值已经很小了，这个时候再计算梯度就比较尴尬了，可以尝试在各个卷积层后加入BN层和SCALE层； 5）把base_lr调低，然后batchsize也调高； 6）把data层的输入图片进行归一化，就是从0-255归一化到0-1，使用的参数是： transform_param { scale: 0.00390625//像素归一化，1/255 } 7）网络参数太多，网络太深，删掉几层看看，可能因为数据少，需要减少中间层的num_output； 8）记得要shuffle数据，否则数据不够随机，几个batch之间的数据差异很小。loss出现NAN 1）观察loss值的趋势，如果迭代几次以后一直在增大，最后变成nan，那就是发散了，需要考虑减小训练速率，或者是调整其他参数。 2）数据不能太少，如果太少的话很容易发散" 3）Gradient Clipp 处理g…

泛化能力，过拟合，欠拟合，不收敛，奥卡姆剃刀
type: item
date: 2024-01-19T17:26:00+08:00
description: 泛化能力欠拟合过拟合与不收敛解决手段一、模型训练拟合的分类和表现二、欠拟合三、过拟合总结：泛化能力{message type="success" content="泛化能力（generalization ability）是指机器学习算法对新鲜样本的适应能力，简而言之是在原有的数据集上添加新的数据集，通过训练输出一个合理的结果。学习的目的是学到隐含在数据背后的规律，对具有同一规律的学习集以外的数据，经过训练的网络也能给出合适的输出，该能力称为泛化能力。"/}欠拟合过拟合与不收敛用比较直白的话来讲，就是通过数据训练学习的模型，拿到真实场景去试，这个模型到底行不行，如果达到了一定的要求和标准，它就是行，说明泛化能力好，如果表现很差，说明泛化能力就差。为了更好的理解泛化能力，这里引入三种现象，欠拟合、过拟合以及不收敛。{message type="success" content="欠拟合（under-fitting），是指模型拟合程度不高，数据距离拟合曲线较远，或指模型没有很好地捕捉到数据特征，不能够很好地拟合数据。即，在训练数据集上表现差，在测试集数据也表现差。过拟合（over-fitting），是指模型在训练集上表现很好，在测试集上效果差。不收敛（non-convergence）,指误差函数一直在振荡，不能趋近一个定值，没有找到局部或者全局最小值。"/}举个例子来说明下，好比高考数学考试，为了在高考能有个好成绩，高一到高三，好多人会采用“题海战术”来训练自己的做题能力，但高考试卷上的题，都是新题，几乎没有一模一样的题，学生们为了掌握解题规律就不停的刷题，希望最后自己碰到类似的题，能够举一反三，能学以致用，这种规律掌握的适用性，就是泛化能力。有的人对相似题型的解题规律掌握的很好，并且解题效果也很好，这种就是泛化能力强，这种同学往往数学成绩就好。有的同学成绩不好，就是泛化能力差，可能有三种情况{message type="success" content="1.做了不少题，但没有找到解题规律，不管碰到老题和新题都不会做，这种就是欠拟合。2.做了很多题，自认为做过的每一类题型的解题规律都掌握了，而且在之前“题海战术”的题目中，确实表现的很好，但是一碰到新的题目，完全就不会，或者做错，这种学生就是那种喜欢死记硬背的，这种就是过拟合。3.平常也不做题，然后每次一做题就瞎蒙，导致偶尔对，偶尔错，这种就是不收敛。"/}为了更直观展示，引用了几张图来说明，如下图所示，真实曲线是正弦曲线，蓝色的点是训练数据，红色的线为拟合曲线。解决手段在深度学习的模型建立过程中，一般都是用已经产生的数据训练，然后使用训练得到的模型去拟合未来的数据，借此来预测一些东西。在机器学习和深度学习的训练过程中，经常会出现欠拟合和过拟合的现象。训练一开始，模型通常会欠拟合，所以会对模型进行优化，等训练到一定程度后，就需要解决过拟合的问题了。一、模型训练拟合的分类和表现如何判断过拟合呢？我们在训练的时候会定义训练误差，验证集误差，测试集误差（即泛化误差）。训练误差总是减少的，而泛化误差一开始会减少，到了一定程度后不减少反而开始增加，这时候便出现了过拟合的现象。如下图，直观理解，欠拟合就是还没有学习到数据的特征，还有待继续学习，所以此时判断的不准确；而过拟合则是学习的太彻底，以至于把数据的一些不需要的局部特征或者噪声所带来的特征都给学习到了，所以在测试的时候泛化误差也不佳。从方差和偏差的角度来说，欠拟合就是在训练集上高方差，高偏差，过拟合就是高方差，低偏差。为了更加直观，我们看下面的图对比上图，图一的拟合并没有把大体的规律给拟合出来，拟合效果不好，这个就是欠拟合，还需要继续学习规律，此时模型简单；图三的拟合过于复杂，拟合的过于细致，以至于拟合了一些没有必要的东西，这样在训练集上效果很好，但放到测试集和验证集就会不好。图二是最好的，把数据的规律拟合出来了，也没有更复杂，更换数据集后也不会效果很差。在上面的拟合函数中，可以想到，图三过拟合的拟合函数肯定是一个高次函数，其参数个数肯定比图二多，可以说图三的拟合函数比图二要大，模型更加复杂。这也是过拟合的一个判断经验，模型是否过于复杂。另外针对图三，我们把一些高次变量对应的参数值变小，也就相当于把模型变简单了。从这个角度上讲，可以减少参数值，也就是一般模型过拟合，参数值整体比较大。从模型复杂性上讲，可以是： ——模型的参数个数； ——模型的参数值的大小。 个数越多，参数值越大，模型越复杂。二、欠拟合欠拟合的表现有什么方法来判断模型是否欠拟合呢？其实一般都是依靠模型在训练集和验证集上的表现，有一个大概的判断就行了。如果要有一个具体的方法，可以参考机器学中，学习曲线来判断模型是否过拟合，如下图：欠拟合的解决方案（1）增加数据特征：欠拟合是由…

AI: 机器学习必须懂的几个术语：Label、Feature、Model...
type: item
date: 2023-12-26T14:15:51+08:00
description: 1.标签 Label2.特征 Feature3.样本 Example3.1有标签样本(labeled):3.2无标签样本(unlabeled)：4.模型 Model5.回归 Regression6.分类 Classification7.机器学习算法地图1.标签 Label标签：所预测的东东实际是什么（可理解为结论），如线性回归中的 y 变量，如分类问题中图片中是猫是狗（或图片中狗的种类）、房子未来的价格、音频中的单词等等任何事物，都属于Label。（如一组图片，已经表明了哪些是狗，哪些是猫，这里Label就是分类问题中每一个类）2.特征 Feature特征是事物固有属性，可理解为做出某个判断的依据，如人的特征有长相、衣服、行为动作等等，一个事物可以有N多特征，这些组成了事物的特性，作为机器学习中识别、学习的基本依据。特征是机器学习模型的输入变量。如线性回归中的 x 变量。例如在垃圾邮件分类问题中，特征可能包括：电子邮件中是否包含 “ 广告、贷款、交易” 等短语电子邮件文本中的字词发件人的地址发送电子邮件的时段其中机器学习重要步骤：特征提取就是通过多种方式，对数据的特征数据进行提取。一般，特征数据越多，训练的机器学习模型就会越精确，但处理难度也越大。3.样本 Example样本是指一组或几组数据，样本一般作为训练数据来训练模型样本分为以下两类：有标签样本无标签样本3.1有标签样本(labeled):同时包含特征和标签在监督学习中利用数据做训练时，有标签数据/样本（Labeled data）或叫有/无标记数据，就是指有没有将数据归为要预测的类别。例如以下房价数据集：其中包含特征：卧室数量等，最右边一列是标签：房价中间值（注，因为该问题要预测未来房价走势，所以Label就是某条房屋数据中的房价）3.2无标签样本(unlabeled)：包含特征，但不包含标签如以下数据集： 去掉了Label，但是一样有用（如用在测试训练后的模型，即训练好模型后，输入该数据，那到预测后的房价与原标签进行比较，得到模型误差）4.模型 Model模型定义了特征与标签之间的关系，就是我们机器学习的一组数据关系表示，也是我们学习机器学习的核心例如，垃圾邮件检测模型可能会将某些特征与“垃圾邮件”紧密联系起来。模型生命周期的两个重要阶段：训练 Training是指创建或学习模型。也就是说，向模型展示有标签样本，让模型逐渐学习特征与标签之间的关系。训练模型表示通过有标签样本来学习（确定）所有权重和偏差的理想值推断 Inference是指将训练后的模型应用于无标签样本。也就是说，使用经过训练的模型做出有用的预测 (y’)。例如，模型训练好后，就可以使用模型进行Inference ，可以针对新的无标签样本预测房价medianHouseValue。5.回归 Regression回归就是我们数学学习的线性方程，是一种经典函数逼近算法。在机器学习中，就是根据数据集，建立一个线性方程组，能够无线逼近数据集中的数据点，是一种基于已有数据关系实现预测的算法。回归模型可预测连续值（线性）例如，回归模型做出的预测可回答如下问题：某小区房价的趋势？用户点击此广告的概率是多少？当机器学习模型最终目标（模型输出）是求一个具体数值时，例如房价的模型输出为25000，则大多数可以通过回归问题来解决。线性回归的好处在与模型简单，计算速度快，方便应用在分布式系统对大数据进行处理。线性回归还有个姐妹：逻辑回归（Logistic Regression），主要应用在分类领域6.分类 Classification顾名思义，分类模型可用来预测离散值例如，分类模型做出的预测可回答如下问题：是/否问题，某个指定电子邮件是垃圾邮件还是非垃圾邮件？图片是动物还是人？垃圾分类当机器学习模型最终目标（模型输出）是布尔或一定范围的数时，例如判断一张图片是不是人，模型输出0/1：0不是，1是；又例如垃圾分类，模型输出1-10之间的整数，1代表生活垃圾，2代表厨余垃圾。。等等，这类需求则大多数可以通过分类问题来解决。7.机器学习算法地图机器学习算法多种多样，许多情况下，建模和算法设计是Designer所选择的，具体采用哪种算法也没有一定要求，根据实际具体问题具体分析。

机器学习/深度学习-10个激活函数详解
type: item
date: 2023-11-01T21:02:00+08:00
description: 综述1. Sigmoid 激活函数2. Tanh / 双曲正切激活函数3. ReLU 激活函数4. Leaky ReLU5. ELU6. PReLU（Parametric ReLU）7. Softmax8. Swish9. Maxout10. Softplus综述激活函数（Activation Function）是一种添加到人工神经网络中的函数，旨在帮助网络学习数据中的复杂模式。类似于人类大脑中基于神经元的模型，激活函数最终决定了要发射给下一个神经元的内容。在人工神经网络中，一个节点的激活函数定义了该节点在给定的输入或输入集合下的输出。标准的计算机芯片电路可以看作是根据输入得到开（1）或关（0）输出的数字电路激活函数。因此，激活函数是确定神经网络输出的数学方程式，本文概述了深度学习中常见的十种激活函数及其优缺点。首先我们来了解一下人工神经元的工作原理，大致如下：上述过程的数学可视化过程如下图所示：1. Sigmoid 激活函数Sigmoid 函数的图像看起来像一个 S 形曲线。函数表达式如下：$$\[\mathrm{f(z)=1/(1+e^{\wedge}-z)}\]$${alert type="success"}在什么情况下适合使用 Sigmoid 激活函数呢？Sigmoid 函数的输出范围是 0 到 1。由于输出值限定在 0 到 1，因此它对每个神经元的输出进行了归一化；用于将预测概率作为输出的模型。由于概率的取值范围是 0 到 1，因此 Sigmoid 函数非常合适；梯度平滑，避免「跳跃」的输出值；函数是可微的。这意味着可以找到任意两个点的 sigmoid 曲线的斜率；明确的预测，即非常接近 1 或 0。{/alert}{alert type="warning"}Sigmoid 激活函数有哪些缺点？倾向于梯度消失；函数输出不是以 0 为中心的，这会降低权重更新的效率；Sigmoid 函数执行指数运算，计算机运行得较慢。{/alert}2. Tanh / 双曲正切激活函数tanh 激活函数的图像也是 S 形，表达式如下：$$f(x)=tanh(x)=\frac{2}{1+e^{-2x}}-1$$tanh 是一个双曲正切函数。tanh 函数和 sigmoid 函数的曲线相对相似。但是它比 sigmoid 函数更有一些优势。首先，当输入较大或较小时，输出几乎是平滑的并且梯度较小，这不利于权重更新。二者的区别在于输出间隔，tanh 的输出间隔为 1，并且整个函数以 0 为中心，比 sigmoid 函数更好；在 tanh 图中，负输入将被强映射为负，而零输入被映射为接近零。注意：在一般的二元分类问题中，tanh 函数用于隐藏层，而 sigmoid 函数用于输出层，但这并不是固定的，需要根据特定问题进行调整。3. ReLU 激活函数ReLU 激活函数图像如上图所示，函数表达式如下：{alert type="success"}ReLU 函数是深度学习中较为流行的一种激活函数，相比于 sigmoid 函数和 tanh 函数，它具有如下优点：当输入为正时，不存在梯度饱和问题。计算速度快得多。ReLU 函数中只存在线性关系，因此它的计算速度比 sigmoid 和 tanh 更快{/alert}{alert type="warning"}当然，它也有缺点：Dead ReLU 问题。当输入为负时，ReLU 完全失效，在正向传播过程中，这不是问题。有些区域很敏感，有些则不敏感。但是在反向传播过程中，如果输入负数，则梯度将完全为零，sigmoid 函数和 tanh 函数也具有相同的问题；我们发现 ReLU 函数的输出为 0 或正数，这意味着 ReLU 函数不是以 0 为中心的函数。{/alert}4. Leaky ReLU它是一种专门设计用于解决 Dead ReLU 问题的激活函数：ReLU vs Leaky ReLU为什么 Leaky ReLU 比 ReLU 更好？$$f(y_i)=\begin{cases}y_i,&\text{if }y_i>0\\a_iy_i,&\text{if }y_i\leq0\end{cases}.$$1、Leaky ReLU 通过把 x 的非常小的线性分量给予负输入（0.01x）来调整负值的零梯度（zero gradients）问题；2、leak 有助于扩大 ReLU 函数的范围，通常 a 的值为 0.01 左右；3、Leaky ReLU 的函数范围是（负无穷到正无穷）。注意：从理论上讲，Leaky ReLU 具有 ReLU 的所有优点，而且 Dead ReLU 不会有任何问题，但在实际操作中，尚未完全证明 Leaky ReLU 总是比 ReLU 更好。5. ELUELU vs Leaky ReLU vs ReLUE…

Python-BP神经网络实现单特征多分类
type: item
date: 2023-10-17T23:04:00+08:00
description: 不同于图像处理，神经网络在处理其他不少领域，常常需要单特征分类，本例实现同半径的圆进行多分类（3分类），特征即为圆的半径。输入层12节点，一个6节点的隐藏层，输出层3个节点。1.目标2.开发环境3.准备数据4.处理数据5.构建BP神经网络总结1.目标通过BP算法实现对不同半径的圆的分类。2.开发环境Python3.10;jupyter notebook3.准备数据目的： 生成3类圆在第一象限内的坐标（圆心都是原点）第1类：半径范围为1~10，分类标识为‘0’第2类：半径范围为10~20，分类标识为‘1’第3类：半径范围为20~30，分类标识为‘2’代码如下：data_generate.pyimport numpy as np import math import random import csv # 只生成第一象限内的坐标即可。每个圆生成12个坐标(x,y)，相当于12个特征维度 def generate_circle(lower, upper): # 圆在第一象限内的坐标 data_ur = np.zeros(shape=(12, 2)) # 在上下限范围内，随机产生一个值作为半径 radius = random.randint(int(lower), int(upper)) # 在0~90度内，每隔7.5度取一次坐标，正好取12次 angles = np.arange(0, 0.5 * np.pi, 1 / 24 * np.pi) for i in range(12): temp_ur = np.zeros(2) x = round(radius * math.cos(angles[i]), 2) y = round(radius * math.sin(angles[i]), 2) temp_ur[0] = x temp_ur[1] = y data_ur[i] = temp_ur return data_ur, label # 将坐标保存到CSV文件中 def save2csv(data, batch, label): out = open("D:\\circles.csv", 'a', newline='') csv_write = csv.writer(out, dialect='excel') length = int(data.size / 2) for i in range(length): string = str(data[i][0]) + ',' + str(data[i][1]) + ',' + str(batch) + ',' + str(label) temp = string.split(',') csv_write.writerow(temp) out.close() if __name__ == "__main__": ''' 生成3类圆，标签（label）分别为：0、1、2 第1类圆的半径下限为1，上限为10 第2类圆的半径下限为10，上限为20 第3类圆的半径下限为20，上限为30 圆心都为原点 ''' lower = [1, 10, 20] # 半径随机值的下限 upper = [10, 20, 30] # 半径随机值的上限 label = ['0', '1', '2'] # 种类的标签 for i in range(len(label)): # 每类数据生成50组 for j in range(50): data, label = generate_circle(lower[i], upper[i]) batch = 50 * i + j + 1 # 数据的批次，用来区分每个坐标是属于哪个圆的 save2csv(data, batch, label[i])共3类圆，每类生成50个圆，每个圆有12个坐标，因此在输出文件D:\circles.csv中总共有3×50×12=1800行数据：通过生成的坐标绘制散点图如下：图中蓝色的点是label为0的圆，绿色的点是label为1的圆，红色的点是label为2的圆。4.处理数据目标： 根据第3步获得的坐标，计算每个圆的半径（勾股定理）作为神经网络的输入。代码如下：data_process.pyimport csv import math def process(file_name): # 要读取的CSV文件 csv_file = csv.reader(open(file_name, encoding='utf-8')) # 要生成的CSV文件 out_file = open("D:\\circles_data.csv", 'a', newline='') csv_write = csv.writer(out_file, dialect='exc…

Python机器学习- 鸢尾花分类
type: item
date: 2023-07-23T21:10:00+08:00
description: 1、描述2、code3、描述4、code1、描述请编写代码实现train_and_predict功能，实现能够根据四个特征对三种类型的鸢尾花进行分类。train_and_predict函数接收三个参数:train_input_features—二维NumPy数组，其中每个元素都是一个数组，它包含:萼片长度、萼片宽度、花瓣长度和花瓣宽度。train_outputs—一维NumPy数组，其中每个元素都是一个数字，表示在train_input_features的同一行中描述的鸢尾花种类。0表示鸢尾setosa，1表示versicolor，2代表Iris virginica。prediction_features—二维NumPy数组，其中每个元素都是一个数组，包含:萼片长度、萼片宽度、花瓣长度和花瓣宽度。该函数使用train_input_features作为输入数据，使用train_outputs作为预期结果来训练分类器。请使用训练过的分类器来预测prediction_features的标签，并将它们作为可迭代对象返回(如list或numpy.ndarray)。结果中的第n个位置是prediction_features参数的第n行。2、code# 导入numpy库，用于处理多维数组 import numpy as np # 导入sklearn库中的数据集、模型选择、度量和朴素贝叶斯模块 from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn import metrics from sklearn.naive_bayes import GaussianNB # 定义train_and_predict函数，接收三个参数:训练输入特征、训练输出标签和预测输入特征 def train_and_predict(train_input_features, train_outputs, prediction_features): # 创建一个高斯朴素贝叶斯分类器对象 clf = GaussianNB() # 使用训练输入特征和训练输出标签来训练分类器 clf.fit(train_input_features, train_outputs) # 使用预测输入特征来预测输出标签，并将结果返回 y_pred = clf.predict(prediction_features) return y_pred # 加载鸢尾花数据集，包含150个样本，每个样本有四个特征和一个标签 iris = datasets.load_iris() # 将数据集随机分成训练集和测试集，其中训练集占70%，测试集占30%，并设置随机种子为0 X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.3, random_state=0 ) # 调用train_and_predict函数，使用训练集来训练分类器，并使用测试集来预测标签，将结果赋值给y_pred y_pred = train_and_predict(X_train, y_train, X_test) # 如果y_pred不为空，打印预测标签和真实标签的准确率，即正确预测的比例 if y_pred is not None: print(metrics.accuracy_score(y_test, y_pred))3、描述机器学习库 sklearn 自带鸢尾花分类数据集，分为四个特征和三个类别，其中这三个类别在数据集中分别表示为 0, 1 和 2，请实现 transform_three2two_cate 函数的功能，该函数是一个无参函数，要求将数据集中 label 为 2 的数据进行移除，也就是说仅保留 label 为 0 和为 1 的情况，并且对 label 为 0 和 1 的特征数据进行保留，返回值为 numpy.ndarray 格式的训练特征数据和 label 数据，分别为命名为 new_feat 和 new_label。然后在此基础上，实现 train_and_evaluate 功能，并使用生成的 new_feat 和 new_label 数据集进行二分类训练，限定机器学习分类器只能从逻辑回归和决策树中进行选择，将训练数据和测试数据按照 8:2 的比例进行分割。要求输出测试集上的 accuracy_score，同时要求 accuracy_score 要不小于 0.95。4、code#导入numpy库，它是一个提供了多维数组和矩阵运算等功能的Python库 impo…

Windows安装Jupyter Notebook及机器学习的库
type: item
date: 2023-05-29T13:12:00+08:00
description: Jupyter Notebook安装（Windows）下载Jupyter Notebook（1）打开cmd（如果没有把Python安装目录添加到Path，需要切换到Python安装目录的Scripts目录下）；（2）输入pip install jupyter；（推荐在外网环境下安装）2.库安装下载下面文件{cloud title="requirements.txt" type="lz" url="https://wwek.lanzoub.com/iLI2S0xm6a3a" password=""/}然后执行：pip3 install -r requirements.txt启动Juypter Notebook（1）命令行窗口输入jupyter notebook；浏览器会打开Jupyter Notebook窗口，说明Jupyter Notebook安装成功。(2) 配置Jupyter Notebook1、行窗口输入jupyter notebook --generate-config，会发现C:\Users\用户名\ .jupyter下多出了一个配置文件jupyter_notebook_config.py；2、这个配置文件，找到下面这句#c.NotebookApp.notebook_dir = ''。可以把它修改成c.NotebookApp.notebook_dir = 'D:\jupyter-notebook'，当然具体的目录由自己创建的文件夹决定（需要自己创建）。配置文件修改完成后，以后在jupyter notebook中写的代码都会保存在该目录下。现在重新启动jupyter notebook，就进入了新的工作目录；5.添加代码自动补全功能（可选）（1）打开cmd，输入pip install jupyter_contrib_nbextensions，等待安装成功；（2）安装完之后需要配置nbextension（配置前要确保已关闭jupyter notebook），在cmd中输入jupyter contrib nbextension install --user --skip-running-check，等待配置成功；（3）在前两步成功的情况下，启动jupyter notebook，会发现在选项栏中多出了Nbextension的选项，点开该选项，并勾选Hinterland，即可添加代码自动补全功能。

机器学习代码实现:线性回归与岭回归
type: item
date: 2023-05-15T23:05:35+08:00
description: 1.线性回归模型线性回归模型是最简单的一种线性模型，模型的形式就是：$y=W^T x+b$我们可以通过对原本的输入向量x扩增一个为1的维度将参数W和b统一成一个参数W，即模型变成了$y=W^T x$这里的W是原本两个参数合并之后的而其损失函数的形式是残差平方损失RSS$L=\frac{1}{2 m} \sum_{i=1}^m\left(W^T x_i-y_i\right)^2=\frac{1}{2 m}\left(W^T X-y\right)^T\left(W^T X-y\right)$我们很容易就可以通过求导得到线性回归模型的关于W的梯度$\nabla_W L=\frac{1}{m} \sum_{i=1}^m\left(W^T x_i-y_i\right) x_i=\frac{1}{m} X^T\left(W^T X-y\right)$这样一来我们就可以通过梯度下降的方式来训练参数W，可以用下面的公式表示$W:=W-\alpha \frac{1}{m} X^T\left(W^T X-y\right)$但实际上线性模型的参数W可以直接求解出，即：$W=\left(X^T X\right)^{-1} X^T y$2.线性回归的编程实现具体代码中的参数的形式可能和上面的公式推导略有区别，我们实现了一个LinearRegression的类，包含fit，predict和loss三个主要的方法，fit方法就是求解线性模型的过程，这里我们直接使用了正规方程来解class LinearRegression: def fit(self, X: np.ndarray, y: np.ndarray) -> float: N, D = X.shape # 将每个样本的特征增加一个维度，用1表示，使得bias和weight可以一起计算 # 这里在输入的样本矩阵X末尾增加一列来给每个样本的特征向量增加一个维度 # 现在X变成了N*(D+1)维的矩阵了 expand_X = np.column_stack((X, np.ones((N, 1)))) self.w = np.matmul(np.matmul(np.linalg.inv(np.matmul(expand_X.T, expand_X)), expand_X.T), y) return self.loss(X, y)predict实际上就是将输入的矩阵X放到模型中进行计算得到对应的结果，loss给出了损失函数的计算方式：def loss(self, X: np.ndarray, y: np.ndarray): """ 线性回归模型使用的是RSS损失函数 :param X:需要预测的特征矩阵X，维度是N*D :param y:标签label :return: """ delta = y - self.predict(X) total_loss = np.sum(delta ** 2) / X.shape[0] return total_loss3.岭回归Ridge Regression与代码实现岭回归实际上就是一种使用了正则项的线性回归模型，也就是在损失函数上加上了正则项来控制参数的规模，即：$L=\frac{1}{2 m} \sum_{i=1}^m\left(W^T x_i-y_i\right)^2+\lambda\|W\|_2=\frac{1}{2 m}\left(W^T X-y\right)^T\left(W^T X-y\right)+\lambda W^T W$因此最终的模型的正规方程就变成了：$W=\left(X^T X+\lambda I\right)^{-1} X^T y$这里的\lambda是待定的正则项参数，可以根据情况选定，岭回归模型训练的具体代码如下class RidgeRegression: def fit(self, X: np.ndarray, y: np.ndarray): N, D = X.shape I = np.identity(D + 1) I[D][D] = 0 expand_X = np.column_stack((X, np.ones((N, 1)))) self.W = np.matmul(np.matmul(np.linalg.inv(np.matmul(expand_X.T, expand_X) + self.reg * I), expand_X.T), y) return self.loss(X, y)4.数据集实验这里使用了随机生成的二位数据点来对线性模型进行测试，测试结果如下：线性模型测试结果岭回归也使用同样的代码进行测试。