机器学习——线性回归算法一、线性回归问题1。线性回归问题介绍(1)实例介绍数据:工资和年龄(2个特征)
目标:预测银行将贷出多少钱(标签)
考虑:工资和年龄都会影响最终银行贷款的结果,那么他们各自的影响有多大呢?(参数)
从图表中可以看出,随着工资和年龄的增长,贷款额也在增加。x1和X2的大小不同,需要加上两个因子:1×1 2×2=y,在X1,x2,y已知的情况下建立回归方程。方程的目标是找到最合适的1和2,这样我们就可以知道工资和年龄对贷款额的影响有多大。
(2)通俗的解释是,X1和X2是我们的两个特征(年龄和工资),Y是银行最终会借给我们多少钱。
找到最合适的线(想象一个高维度)来最好地拟合我们的数据点。(不能满足所有,尽可能满足多点)
图中的红点是样本数据,我们要根据给定的数据集拟合一个平面,使每个样本数据到达平面的误差最小。
这个数字是机器如何进行预测(回归)的。它会根据贷款的历史数据(年龄和工资分别对应X1和X2)找出最拟合的线(面)来做预测,这样新的数据来了之后就可以直接带入,你就可以算出给多少钱了。
(3)回归方程积分的进一步积分就是把偏倚项和权重参数项放在一起(加上0使它们都等于1)。
假设1是年龄的参数,2是薪资的参数。
拟合平面:h(x)=0 1×1 2×2。参数1和2是权重项,对结果有很大影响。0是一个偏移项。
集成:
2.理解偏差项传统的神经网络可以被视为“组合模型”,其中多个逻辑回归模型的输出被用作另一个逻辑回归模型的输入。
因此,讨论神经网络中偏倚项B的作用,近似等价于讨论logistic回归模型中偏倚项B的作用。
(1)有logistic回归偏倚的logistic回归模型的本质:用函数y=WX b画决策面,其中w是模型参数和函数的斜率;b是函数的截距。
一维情况:W=[1],b=2,y=WX b得到一条截距为2,斜率为1的直线如下:
二维情况:W=[1 1],b=2,则y=WX b得到截距为2,斜率为[1 1]的平面如下:
显然,函数y=WX b是2维/3维/更高维空间中的直线/平面/超平面。如果没有偏置项B,在空间上只能画一条通过原点的直线/平面/超平面。
因此,必须在逻辑回归中加入偏差项B,以确保分类器可以在空间的任意位置绘制决策面。
(2)神经网络的偏差项相同。对于多元logistic回归组成的神经网络,应加入偏倚项B。
如果隐层有三个节点,相当于三个logistic回归分类器。这三个分类器都画出了自己的决策面,所以它们的偏向项B一般会不一样。
复杂的决策边界由三个隐藏节点的神经网络绘制如下:
如何机智地给三个分类器(隐藏节点)分配不同的B?或者我们让模型在训练的过程中动态调整三个分类器的B来画出它们的最佳决策面会怎么样?
即在X前面加一个1作为偏置项的基,(此时X由N维向量变为N维向量,即[1,x1,x2…]),然后让每个分类器训练它的偏置项权重,这样每个分类器的权重就变成N个1维,即[w0,w1,…],其中w0为偏置。这样就把看似与斜率W不同的截距B统一成了一个框架,使得模型在训练的过程中不断调整参数w0,从而达到调整B的目的。
所以,如果在写神经网络的代码时省略了偏置项,那么神经网络很可能会变得很差,收敛速度慢,精度差,甚至可能会卡在“死”状态,无法收敛。
3.错误术语定义了银行的目标。误差越小越好,这样我们的结果才能更准确。
实际值和预测值之间肯定有差异。——误差用表示。
对于每个样本:y(i)=Tx(i) (i),y(i)为真值,Tx(i)为预测值,(i)为差值。
每个样本的误差值不同:
4.误差定律——独立可识别分布(iid)在概率统计理论中,它是指在随机过程中,任意时刻的值都是随机变量。如果这些随机变量服从同一分布,并且相互独立,那么这些随机变量就是独立同分布的。
误差(i)是独立的,具有相同的分布,服从均值为0、方差为2的高斯分布;
独立:张三和李四一起贷款。它们彼此无关,就是每个样本到拟合平面的距离不同;
相同分布:它们都来自我们假设的同一家银行,所以预测时也是这样,数据建模在同一分布下,尽可能来自同一分布;
高斯分布:银行可能会多给或少给,但绝大多数情况下,这种波动不会太大,极少数情况下,波动会比较大(有些多给或少给,粗略来说,平均值为0)。
误差在0附近浮动的可能性更大,正负差更大的可能性越来越小。符合概率统计中实际分布。
将公式(1)转化为:(i)=y(i)-Tx(i),即误差=实际值-预测值,然后将其带入高斯分布函数的公式(2),所有误差项用x,y代替。
p(x;)表示:给定的x的值;
p(y | x;)代表:给定x和某参数,y的概率密度函数。
由于x和是常数值,所以Tx(i)可以理解为常数值c。
5.似然函数似然函数是关于模型中参数的函数,用来表示模型中参数的似然性。
给定样本数据x(x1,x2,xn),应该用什么样的参数来组合样本数据得到真值?
使误差项尽可能小,使似然函数尽可能大,问题可以转化为求L()的最大值。
(1)引入似然函数。引入似然函数如下:(的乘积由.到.)
连续变量相互独立的充要条件是联合概率密度等于边际概率密度的乘积。因此,在变量服从独立同分布的前提下,建立了联合概率密度等于边际概率密度的乘积。
p(y(I)| x(I);):什么样的X和组合后,成为Y的可能性越大越好。m项的乘积很难理解和估计,要想办法相加。
对数似然
:乘法难解,加法相对容易。对数中的乘法可以转化为加法,所以在公式的左右两边取对数。
log(AB)=logA logB
(2)为什么取对数?首先,取对数不影响函数的单调性,保证输入对应的概率的最大值和最小值对应似然函数的最大值。
其次,减少计算量,比如联合概率的连续相乘会变成加法问题,指数也可以。
最后,概率的连续相乘会变成一个很小的值,可能会造成浮点数下溢,尤其是数据集很大的时候,联合概率会趋于0,对后续的计算非常不利。根据ln曲线,小概率(越接近0)会通过对数变换转换成较大的负数,从而解决下溢问题。
虽然取对数会改变极值,但不会改变极值点。任务还是求极值,所以L()和logL()是等价的。
6.参数求解(1)公式继续展开简化,处理继续:
,因为log a b=log a log b,所以可以把累加乘法转化为累加:
进一步观察表明,上述公式可视为
和
两部分的组合,即lo
基于高等数学中的自然常数E的函数。也是航模名词,全称是指数。因为对数取不同的底数只会影响极值,而不会影响极值点。
如果这部分的底数是E,那么就用E为底数的指数exp(x)来抵消,然后提取常数项,公式就可以转换成这个累积形式:
公式在这里不能再简化了。毕竟每个人的年龄(x)和各自有多少钱(y)都不一样。因此,我们必须从第一个样本迭代到第m个样本。最后简化为:
(2)目标:使似然函数尽可能大。前一个目标:X和组合后,成为Y的可能性越大越好。所以现在需要最大点。a是常数正,B包含等分,所以也是正数。所以这是两个正数之间的减法。
要求的值越大越好,所以b:
它必须尽可能小。
现在将目标转换为
求解最小二乘法。
2.求解最小二乘法从上面的推导可以得出一个结论:要求使似然函数尽可能大,这就可以转化为取某个值时J()最小化的问题。
求解最小二乘法一般有两种方法:矩阵法和梯度下降法。
1.矩阵求解数据集包含M个样本,并且当每个样本具有N个特征时:
数据x可以写成m *(n ^ 1)维的矩阵(1是加一列1,用于乘截断B);
是n 1维的列向量(1被截断B);
Y维的列向量表示每m个样本结果的预测值。
矩阵的推导如下:
设J()取的偏导数,当偏导数等于零时,这个就是极值点。代表X矩阵的转置,XT和X的乘积一定会得到一个对称矩阵。
另外还有一个公式:TXTX等于2XTX。
XT的逆矩阵是:(XTX)-1。将这个逆矩阵乘以偏导数结果方程的两边,左边的期望为零。据推断:
0=-(XTX)-1 XTY,方程转换为:=(XTX)-1XTy。
这种方法存在一些问题:没有学习过程;矩阵求逆不是必然成功(不可逆);
2.梯度下降法(GD)目标函数:
对于多元线性回归,拟合函数为:
由于目标函数是由M个样本累积而成的,因此损失函数可以通过平均来获得:
1)求损失函数的偏导数,批量梯度减小:
很容易得到最优解,但是每次都要考虑所有样本,执行速度很慢。
2)一次只使用一个样本,随机梯度减小:
去除累加运算,一次采样一个样本进行计算,速度快,结果不准确。
3)为每次更新选择一部分数据,小批量梯度下降法:
(1)为什么要用梯度下降?当得到一个目标函数时,通常不能直接求解。线性回归能得到结果是机器学习中的特例。
机器学习的套路:给机器一堆数据,然后告诉它用什么样的学习方法(目标函数),然后它就往这个方向学习。
优化:逐步完成迭代。每优化一点点,积累起来就能获得巨大的成功。
(2)梯度的概念在一元函数中叫导数,在多元函数中叫梯度。梯度下降是一种优化算法。一般来说就是沿着梯度下降方向求一个函数的最小值。比如一元函数,在加速度减小的方向,总会找到一个点,使速度最小。
通常数据不能完全满足我们的要求,很难用矩阵来解决,所以机器学习要用学习的方法。所以我们用梯度下降,不断迭代,沿着梯度下降方向移动,求最小值。
梯度下降法包括批量梯度下降法、随机梯度下降法(SGD)和迷你批量下降法(通常被认为与SGD相同,常用于深度学习)。
(3)梯度下降实验对于梯度下降,我们可以形象地理解一个人下山的过程。假设山上有一个人。现在他想往山下走,却不知道山脚是哪个方向。他该怎么办?显然,我们能想到的是,我们必须沿着山高下降的地方走,否则我们不是下山而是上山。山高下降的方向有很多。你应该选择哪一个?这个人比较爱冒险。他选择最陡的方向,也就是山高下降最快的方向。既然已经确定了方向,就该开始下山了。
还有一个问题。在下山的过程中,一开始选择的方向并不总是海拔下降最快的地方。这个人很聪明,他总是选择一定的距离,走了一定的距离后,会重新确定当前位置高度下降最快的地方。这样,这个人下降的方向就可以近似看作是每个距离段中身高下降最快的地方。
现在我们把这个思想引入到线性回归中,需要找到参数矩阵,使损失函数J()最小。如果我们把损失函数J()看成山,山的底部不就是损失函数最小的地方吗?那么求解参数矩阵的过程就是人走到山底的过程。
如图,这是一元线性回归中损失函数的图像(即假设函数h(x)=0 1x)。首先我们选择一个起点(通常是(0=0,1=0)),然后沿着这个起点出发,沿着这个点上损失函数下降最快的方向(即这个点的梯度负方向)走一小步,走一步就到了为什么是局部最低点?因为我们到达的点的梯度是0向量(通常在离0向量可接受的范围内),说明这个点是损失函数的极小点,不一定是极小点。
从梯度下降法的思路可以看出,最终得到的局部最低点与我们选择的起点有关。通常情况下,如果起点不同,最终的局部最低点也会不同。
(4)参数更新:每次更新参数的操作:
在…之中
作为学习率(步长),会对结果产生巨大的影响。学习率是一个超级参数,调整学习率是建模中的一个重要内容。
方法:从小做起,但永远不要变小。
批号:常用32,64,128,经常考虑内存和效率。
因为J()是凸函数,所以GD得到的最优解就是全局最优解。批量梯度下降法是寻找整个数据集的梯度,然后更新,所以每次迭代都是寻找全局最优解。
3.单一特征回归建模1。写一个数据预处理。
为训练做准备
函数,对数据进行函数变换、标准化等操作。最后,返回处理后的数据、平均值和标准偏差。
将numpy作为npfrom导入。规范化导入规范化自.生成_正弦曲线导入生成正弦曲线.'''生成多项式导入生成多项式' ' '数据预处理' ' ' ' def prepare_for_training(数据,多项式次数=0,正弦次数=0,normalize_data=True): #计算样本总数num _ examples=数据shape[0]data _ processed=NP。复制(数据)#预处理features_mean=0 features _ deviation=0 data _ normalized=data _ processed if normalize _ data:(data _ normalized,features _ mean,features _ deviation)=normalize(data _ processed)data _ processed=data _ normalized #特征变换sinusoid if sinusoid _ degree 0:sinusoids=generate _ sinusoids(data _ normalized,sinusoid _ degree)data _ processed=NP。concatenate((数据处理,正弦曲线),axis=1) #特征变换多项式如果多项式_次数0:多项式=生成_多项式(数据_归一化,多项式_次数)data _ processed=NP。concatenate((data _ processed,多项式),axis=1) #加一列1数据_已处理=NP。h栈((NP。one((num _ examples,1))、data_processed))返回数据处理,特征平均值,特征偏差2,线性回归模块写一个线性回归类,包含线性回归相关的方法。
'''将numpy作为公证人从utils。特色。为训练做准备导入' ' '为培训做准备' ' '线性回归' '类线性回归:def _ _ init _ _(self,data,labels,多项式次数=0,正弦次数=0,normalize_data=True): ''' 1 .对数据进行预处理操作2.先得到所有的特征个数3.初始化参数矩阵'(data_processed,features_mean,features _ deviation)=prepare _ for _ training(data,多项式_次数,正弦曲线_次数)自我。数据=数据_已处理的自身。标签=标签本身。features _ mean=features _ mean自我。特征_偏差=特征_偏差本身。多项式_次数=多项式_次数self.sinusoid _次数=正弦曲线_次数自我。规格化数据=规格化数据#获取多少个列作为特征量num _ features=自身。数据。形状[1]# 1是列个数,0是样本个数self=NP。零((数量特征,1)) #构建矩阵def train(self,alpha,num_iterations=500):' ' '训练模块,执行梯度下降:参数:为学习率(步长):参数数量迭代次数:迭代次数:return:' ' ' cost _ history=self。gradient _ descent(alpha,num_iterations)返回self,cost _ history def gradient _ descent(self,alpha,num _ iterations):' ' '梯度下降,实际迭代模块:参数阿尔法:学习率:参数数量_迭代次数:迭代次数:return: ''' cost_history=[] #保存损失值对于_在范围(迭代次数):#每次迭代参数更新自我。梯度_步长(alpha)成本_历史。追加(自我。cost _ function(自我。数据,自我。标签))return cost _ history def gradient _ step(self,alpha):' ' '梯度下降参数更新计算方法(核心代码,矩阵运算):参数阿尔法:学习率:return:“”num _ examples=self。数据。形状[0]#样本数预测=线性回归。假设(自我数据,自我)#预测值# 参差=预测值-真实值delta=预测-自我标签=自我#值更新,T是执行转置=-*(1/num _ examples)*(NP。点号(delta .t,self.data)).t自我。theta=theta def cost _ function(自身,数据,标签):' ' '损失计算:参数数据:数据集:参数标签:真实值:return:' ' ' num _ examples=data。形状[0]#样本个数# 参差=预测值-真实值delta=线性回归假设(self.data,self)-标签成本=(1/2)*np.dot(delta .t,delta)打印(成本。shape)print(cost)return cost[0][0]@静态方法定义假设(data,theta):' ' '预测函数:param data:param theta:return:' ' ' #如果处理的是一维数组,则得到的是两数组的內积;如果处理的是二维数组(矩阵),则得到的是矩阵积预测=np.dot(数据,)返回预测def get_cost(自身,数据,标签):' ' '计算当前损失:param data:param labels:return:' ' ' #经过处理了的数据data _ processed=prepare _ for _ training(data,self。多项式次数,自我。正弦次数,自我。normalize _ data)[0]返回自我。cost _ function(数据_已处理,标签)#返回损失值定义预测(自我,数据): '''用训练的数据模型,预测得到回归值结果:param data:return: ''' #经过处理了的数据data _ processed=prepare _ for _ training(data,self。多项式_次数,自我。正弦_次数,自我。normalize _ data)[0]预测=线性回归。假设(数据处理,self)返回预测#返回预测值3、训练线性回归模型对线性回归类进行建模、预测、计算损失等。
'''将numpy作为公证人导入熊猫作为警察局导入matplotlib.pyplot作为pltfrom线性回归导入' ' '线性回归' ' '单变量线性回归' ' ' data=pd.read_csv('/数据/世界-幸福-报告-2023。CSV ')#得到训练和测试数据集train _ data=数据。样本(分数=0.8)#样本:随机选取若干行测试数据=数据。drop(train _ data。索引)#将训练数据删除即为测试数据# 数据和标签定义输入参数名称='经济.人均GDP,'输出参数名称='幸福. score ' x _ train=train _ data[[输入参数名称]]。valuesy _ train=train _ data[[输出参数名称]]。valuesx _ test=测试数据[[输入参数名称]]。valuesy _ Test=Test _ data[[输出参数名称]]。价值PLT。scatter(x _ Train,y_train,label=' Train data ')PLT。scatter(x _ Test,y _ Test,label='测试数据')PLT。xlabel(输入参数名称)PLT。ylabel(输出参数名称)PLT。标题('快乐')#指定名字plt.legend()plt.show()#训练线性回归模型num _ iterations=500 learning _ rate=0.01 #学习率线性回归=线性回归(x _ train,y_train) #线性回归(,cost _ history)=线性_回归。训练(学习率,迭代次数)#执行训练打印('开始时的损失,成本_历史记录[0])打印('训练后的损失,cost_history[-1]) #最后一个plt.plot(范围(迭代次数),成本历史)xlabel(“迭代”)PLT。y标签(“成本”)PLT。标题('物品')工厂。显示()#测试预测数=100 x预测数=NP。林空间(x _ train。min()、x_train.max()、predictions _ num).shape(predictions _ num,1)y _ predictions=linear _ regression。预测(x _预测)PLT。scatter(x _ Train,y_train,label=' Train data ')PLT。scatter(x _ Test,y_test,label='测试数据')PLT。plot(x _ predictions,y _ predictions,' r 'label='预测值)PLT。xlabel(输入参数名称)PLT。ylabel(输出参数名称)PLT。标题('快乐测试)plt.legend()plt.show()运行结果如下:
开始时的损失1791.3527192463505训练后的损失26.382344732117332
输出图表:
损失值:
线性回归方程:
四、多特征回归模型多特征建模,观察与单特征建模效果对比。
1、阴谋地工具包Plotly是一款用来做数据分析和可视化的在线平台,功能非常强大,可以在线绘制很多图形比如条形图、散点图、饼图、直方图等等。而且还是支持在线编辑,以及多种语言python、javascript、matlab、R等许多API。使用Plotly可以画出很多媲美(舞台上由人扮的)静态画面的高质量图:
导入库:
来自plotly.graph_objs导入散点,布局导入plotly。脱机的作为pyimport数字作为npimport plotly.graph_objs作为开始#设置的直白地。离线。init _ notebook _ mode(连接=真)制作散点图:
trace1=go .Scatter( y=np.random.randn(500),mode='markers 'marker=dict( size=16,color=np.random.randn(500),colorscale='Viridis 'show scale=True))data=[trace 1]py。iplot(数据)把方式设置为标记就是散点图,然后标记里面设置一组参数,比如颜色的随机范围,散点的大小,还有图例等等。
推荐最好在朱皮特笔记本中使用,pycharm操作不是很方便。
2、代码实现将numpy作为进口熊猫作为pdimport matplotlib.pyplot作为pltimport plotly #交互式界面展示'将plotly.graph_objs作为goplot ly。离线。init _ notebook _ mode()从线性回归导入线性回归'''单变量线性回归' ' ' data=pd.read_csv('/数据/世界-幸福-报告-2023。CSV ')#得到训练和测试数据集train _ data=数据。样本(分数=0.8)#样本:随机选取若干行测试数据=数据。drop(train _ data。索引)#将训练数据删除即为测试数据# 数据和标签定义输入参数名称1='经济.GDP。人均input _ param _ name _ 2=' Freedom ' output _ param _ name='幸福. score ' x _ train=train _ data[[输入参数名称1,输入参数名称2]]。valuesy _ train=train _ data[[输出参数名称]]。valuesx _ test=测试数据[[输入参数名称1,输入参数名称2]]。valuesy _ test=test _ data[[输出参数名称]]。价值观#训练集plot_training_trace=go .Scatter3d( x=x_train[:0]).flatten(),y=x_train[:1].flatten(),z=y_train.flatten(),name='Training Set 'mode='markers 'marker={ 'size' 10,' opacity' 1,' line' { 'color' 'rgb(255,255,255)'' width' 1 } })#测试集绘图_测试_跟踪=开始.Scatter3d( x=x_test[:0]).flatten(),y=x_test[:1].flatten(),z=y_test.flatten(),name='Test Set 'mode='markers 'marker={ 'size' 10,'不透明度:1,' line' { 'color' 'rgb(255,255,255)'' width' 1 } })#布局plot_layout=go .Layout( title='Date Sets 'scene={ ' xaxis '{ ' title 'input _ param _ name _ 1 },' yaxis '{ ' title 'input _ param _ name _ 2 },' zaxis '{ ' title 'output _ param _ name } },margin={'l' 0,' r' 0,' b' 0,' t '0 })plot _ data=[plot _ training _ trace,plot_test_trace]plot_figure=go .图(data=plot_data,layout=plot _ layout)plotly。离线。plot(plot _ figure)#弹出浏览器网页展示num _ iterations=500 learning _ rate=0.01 #学习率多项式次数=0正弦次数=0线性回归=线性回归(x _火车,y _火车,多项式次数,正弦次数)(theta,cost _ history)=1线性回归。训练(学习率,迭代次数)打印('开始损失,成本_历史记录[0])打印('结束损失,Cost _ history[-1])。绘图(范围(迭代次数),成本历史)xlabel(“迭代”)PLT。y标签(“成本”)PLT。标题(“梯度下降进度”)PLT。show()predictions _ num=10x _ min=x _ train[:0].min()x_max=x_train[:0].max()y_min=x_train[:1].min()y_max=x_train[:1].max()x_axis=np.linspace(x_min,x_max,predictions _ num)y _ axis=NP。Lin空间(y _ min,y_max,predictions _ num)x _ predictions=NP。零((预测数*预测数,1))y _预测数=NP。zeros((predictions _ num * predictions _ num,1))x_y_index=0for x_index,x _ value in enumerate(x _ axis):for y _ index,y _ value in enumerate(y _ axis):x _ predictions scatter 3d(x=x _ predictions。flatten(),y=y_predictions.flatten(),z=z_predictions.flatten(),name='预测平面,marker={ 'size' 1,},不透明度=0.8,曲面轴=2)plot _ data=[plot _ training _ trace,plot_test_trace,plot _ predictions _ trace]plot _ figure=go .图(data=plot_data,layout=plot _ layout)。离线。绘图(plot _ figure)展示结果:
五、非线性回归模型'''非线性回归' ' import numpy as NP import pandas as PD import matplotlib。py绘图为PLT from linear _ regression导入线性回归数据=PD。read _ CSV('/data/non-linear-regression-x-y . CSV ')x=data[' x ']。价值观。形状((数据。shape[0],1))y=data[' y ']。价值观。形状((数据。shape[0],1))data.head(10)#可视化定型和测试数据集以查看dataplt.plot(x,y)plt.show()#设置线性回归参数。num _ iterations=50000 learning _ rate=0.02多项式_次数=15# linear _ regression=线性回归(x,y,normalize_date) #线性回归线性回归=线性回归(x,y,多项式次数,正弦次数,规格化日期)#火车线性回归(,cost _ history)=线性_回归。Train(learning _ rate,num_iterations)打印('开始损失:{:2f}”.format(cost_history[0]))print('结束损失:{:2f}”.format(cost _ history[-1]))theta _ table=PD .数据框({ '模型参数'theta。flatten()})# Plot渐变下降进度。PLT。绘图(范围(迭代次数),成本历史)xlabel(“迭代”)PLT。y标签(“成本”)PLT。标题(“梯度下降进度”)PLT。显示()#获取列车内部设置。预测数=1000 x预测数=NP。Lin space(x . min(),x.max(),predictions _ num).shape(predictions_num,1)y _ predictions=linear _ regression。预测(x _预测)#用predictions.plt.scatter(x,y,label='训练数据集')plt。Plot(x _ predictions,y _ predictions,' r 'label='Prediction')plt.show()执行效果:
开始损失: 580629.11
结束损失: 8777.68
非线性回归方程: