一文看懂线性回归(保姆级别 含源码)

news/2024/5/1 11:31:29/文章来源:https://blog.csdn.net/yinizhilianlove/article/details/126919811

来源: AINLPer 微信公众号(每日论文干货分享!!
编辑: ShuYini
校稿: ShuYini
时间: 2022- 9 -18

引言

最近作者网上看了很多关于线性回归的帖子,个人感觉比较乱,所以打算自己整理一版,希望能把线性回归说的更明白一些,为此我还整理了关于线性回归的脑图如下图所示,如果哪里有不对的地方,欢迎批评指正。

本文涉及源码下载:关注: AINLPer 回复:线性回归源码

线性回归

线性回归(英语:linear regression)是利用称为线性回归方程的最小二乘函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归(multivariable linear regression)。【来自维基】

线性回归的应用

线性回归有很多实际用途。分为以下两大类:

1、如果目标是预测或者映射,线性回归可以用来对观测数据集的和X的值拟合出一个预测模型。当完成这样一个模型以后,对于一个新增的X值,在没有给定与它相配对的y的情况下,可以用这个拟合过的模型预测出一个y值。

2、给定一个变量y和一些变量X1,...,XpX_1,...,X_pX1,...,Xp,这些变量有可能与y相关,线性回归分析可以用来量化y与XjX_jXj之间相关性的强度,评估出与y不相关的XjX_jXj,并识别出哪些XjX_jXj的子集包含了关于y的冗余信息。

我们大多数情况下是使用第一种方式做预测,即通过已知的x,y来预测模型,进而预测未来给x,输出y的值。

机器学习中的线性回归分类

1、单变量线性回归

2、多变量线性回归

3、多项式线性回归

线性回归求解方法

1、最小二乘法(x矩阵必须可逆)

θ=(xT⋅x)−1⋅xT⋅y\theta = (x^ {T}\cdot x)^ {-1}\cdot x^{T} \cdot y θ=(xTx)1xTy

详情可以参考:https://blog.csdn.net/u014445499/article/details/107209837/

2、梯度下降法

对于一个函数y=f(x),我们要求解该函数的极值点,高中的时候就学过,通过解方程f′(x)=0,就可以得到函数的极值点(x0,y0)。不过对于计算机来说,它可不会解方程。但是它可以凭借强大的计算能力,一步一步的去把函数的极值点『试』出来。

首先要知道需要优化的目标函数为:
J(θ)=12m∑i=1m(hθx(i)−y(i))2J(\theta)= \frac{1}{2m} \sum_{i=1}^{m}(h_{\theta}x^{(i)}-y^{(i)})^{2} J(θ)=2m1i=1m(hθx(i)y(i))2

其中:
hθh_ {\theta }hθ (x)= θT\theta ^ {T}θT x= θ0\theta _ {0}θ0 + θ1\theta _ {1}θ1 x1x_ {1}x1,对J(θ)J(\theta)J(θ)求导数得到(该公式对于多项式函数同样适用):

∂∂θjJ(θ)=2m∑i=1m(θT⋅x(i)−y(i))xj(i)=2mXT⋅(X⋅θ−y)\frac{\partial}{\partial\theta_{j}}J(\theta)=\frac{2}{m}\sum_{i=1}^{m}(\theta^{T}\cdot x^{(i)}-y^{(i)})x_{j}^{(i)}=\frac{2}{m}X^{T}\cdot(X\cdot\theta-y) θjJ(θ)=m2i=1m(θTx(i)y(i))xj(i)=m2XT(Xθy)

最后,梯度更新如下:

θj=θj−α∂∂θjJ(θ)\theta_{j}=\theta_{j}-\alpha\frac{\partial}{\partial\theta_{j}}J(\theta) θj=θjαθjJ(θ)

下图就是一个最经典的梯度下降示意图。


梯度下降法具体介绍可以参考:https://blog.csdn.net/u013898698/article/details/120720623

2.1、梯度下降分类

很多视频、文章都会提到,根据数据迭代的计算方式对梯度下降分类,主要可分为以下3类:

2.1.1、全批量梯度下降(BGD)

1、计算量大,参数更新慢,对内存的要求很高,不能以在线的形式训练模型,也就是运行时不能加入新样本2、可以得到全局最优解,参数更新比较稳定,收敛方向稳定。

2.1.2、随机梯度下降(SGD):

1、运算速度很快,同时能够在线学习。2、随机梯度下降参数更新的过程震荡很大,目标函数波动剧烈,参数更新方向有很大的波动。3、其较大的波动可能收敛到比批量梯度下降更小的局部极小值,因为会从一个极小值跳出来。

2.1.3、小批量梯度下降(MBGD):

1、降低了更新参数的方差,使得收敛过程更加的稳定2、能够利用高度优化的矩阵运算,很高效的求得每小批数据的梯度

梯度下降法和最小二乘法求解对比

梯度下降法:

– 缺点

---- 1、需要选择学习率 alpha

---- 2、需要多次的迭代

---- 3、特征值取值范围比较大需要进行特征缩放(归一化)

– 优点

---- 1、当特征数n很大的时候,效果比较好

最小二乘法

– 缺点

---- 1、不需要选择学习率 alpha

---- 2、没有多次的迭代

---- 3、没有特征缩放(归一化)

– 优点

---- 1、当特征数n很大的时候,运算的比较慢,求逆矩阵的复杂度为:n3n^3n3

两种算法选择:

在深度学习中,因为涉及参数特别多,动不动涉及的参数高达几十几百万,所以基本上全部都是通过梯度下降的方法求解。后面会有这种方法的代码实现,其实这块主要帮助大家加深对梯度下降的理解,在实际项目中,主要还是通过mini-batch的思想来更新梯度。以此衍生出来的方法也有很多,例如:SGD、SGDM(SGD+Momentum)、Adagrad、RMSProp、Adma(2015年)、swats(2017)、AMSGrad(2018)、AdaBound(2019)、Cycle-LR、OneCycle-LR,目前常用的主要有:SGDM、Adma、SWATS。这里就不展开来讨论了,后面会专门出一期方法对比的文章。

线性回归代码演示

单变量线性回归

# 【数据生成】根据函数y=4.7x+2 来构造的x、y数据,并画出来
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
x=2*np.random.rand(100,1)
y=2+4.7*x+np.random.rand(100,1)
plt.plot(x,y,'b.')
plt.xlabel('x')
plt.ylabel('y')
plt.axis([0,2,0,15])
plt.show()

在这里插入图片描述

# 【最小二乘法求解】通过回归公式来计算权重和偏置项theta,并画出求解得到的值
x_b=np.c_[np.ones((100,1)),x]
theta=np.linalg.inv(x_b.T.dot(x_b)).dot(x_b.T).dot(y)# 两个点画一条线
xx=np.array([[0],[2]])
xx_tmp=np.c_[np.ones((2,1)),xx]
yy=xx_tmp.dot(theta)
print('方程直接求解w、b的值分别为{0},{1}'.format(theta[1],theta[0]))
plt.plot(xx,yy,'r--')
plt.plot(x,y,'b.')
plt.xlabel('x')
plt.ylabel('y')
plt.axis([0,2,0,15])
plt.show()

在这里插入图片描述

# 【批量梯度下降求解】用梯度下降的方式求解出y、x之间的关系,用所有的样本进行训练
# 从下面结果可以看到,计算出来的theta值和上面直接计算出来的值是差不多的。
m=100
lr=0.05  # 学习率
iterate=1000
theta=np.random.rand(2,1)
x_b=np.c_[np.ones((100,1)),x]
for i in range(iterate):gradent=2/m*x_b.T.dot(x_b.dot(theta)-y)theta=theta-lr*gradent
print("theta:",theta) 

【批量梯度下降(BGD)】主要是在整个数据集,通过对所有的样本的计算来求解梯度的方向。
【学习率对梯度下降的影响】主要观察不同学习率对实际训练结果的影响,这里会设置的学习率有四个:0.01、0.05、0.1、0.5

theta_for_bgd=[]
# 批量梯度求解函数
def diff_lr_for_gradent(iterations,lr):j_save=[]x_b=np.c_[np.ones((100,1)),x]m=len(x_b)theta=np.random.rand(2,1)plt.plot(x,y,'b.')for iteration in range(iterations):y_pred=x_b.dot(theta)# 计算损失函数并存放到[]里面J=1/(2*m)*(y-y_pred).T.dot(y-y_pred)j_save.append(float(J[0]))   # 画出拟合直线plt.plot(x,y_pred,'r-')# 梯度计算及更新gradent=2/m*x_b.T.dot(x_b.dot(theta)-y)theta=theta-lr*gradentif lr==0.05:theta_for_bgd.append(theta)# 画出损失函数和训练次数的图像 plt.xlabel('X')plt.ylabel("Y")plt.axis([0,2,0,15])plt.title('lr={}'.format(lr)) return  j_save 

根据下方画图(红色线是拟合线、绿色线表示了迭代次数和损失函数的关系):

可以看出来lr越小,其拟合的直线向中间逼近的比较慢(损失函数收敛慢),随着lr的增加,逼近的速度也越快(损失函数收敛快)。

但是当lr很大的时候,反而不能趋向实际要拟合的直线(损失函数会变得发散),这说明了在训练过程中要选择合适的lr。

iterations=100
plt.figure(figsize=(15,4))plt.subplot(241)
j_save=diff_lr_for_gradent(iterations,0.01)
tmp=np.arange(iterations)
plt.subplot(245)
plt.plot(tmp,j_save,'g-')plt.subplot(242)
j_save=diff_lr_for_gradent(iterations,0.05)
tmp=np.arange(iterations)
plt.subplot(246)
plt.plot(tmp,j_save,'g-')plt.subplot(243)
j_save=diff_lr_for_gradent(iterations,0.1)
tmp=np.arange(iterations)
plt.subplot(247)
plt.plot(tmp,j_save,'g-')plt.subplot(244)
j_save=diff_lr_for_gradent(iterations,0.5)
tmp=np.arange(iterations)
plt.subplot(248)
plt.plot(tmp,j_save,'g-')
plt.show()

在这里插入图片描述
【随机梯度下降(SGD)】随机是指每个batch的数据是对整个数据空间的随机采样,只要采样够随机,随机梯度的期望和真实梯度是相等的。放在模型训练里,哪怕一个batch就一个数据点,只要多迭代几个batch,最终效果一定是一样的。

【自适应学习率】学习率我们希望是一开始的时候步长比较长,后来慢慢越走越小,进而达到损失函数收敛的最佳参数。

Tip:这里会有两个超参数:epoch、batch

Epoch:定义了学习算法在整个训练数据集中的工作次数,Batch:定义在更新内部模型参数之前要处理的样本数。

详情可以参考:https://blog.csdn.net/weixin_42137700/article/details/84302045

theta_for_sgd=[]
x_b=np.c_[np.ones((100,1)),x]
m=len(x_b)
epoches=50 #训练次数
theta=np.random.rand(2,1)
#batch=m # 假设batch的大小和训练数据的大小一样# lr学习率更新
def lr_update(iterations):return 5/(50+iterations)for epoch in range(epoches):for i in range(m):# 在训练数据中随机的选择x,ydata_index=np.random.randint(m)xi=x_b[data_index:data_index+1]yi=y[data_index:data_index+1]# 依据该条数据更新梯度gradent=2*xi.T.dot(xi.dot(theta)-yi)lr=lr_update(epoch*m+i)theta=theta-lr*gradenttheta_for_sgd.append(theta)# 画出部分图用来展示if epoch<5 and i< 10 :y_pred=x_b.dot(theta)plt.plot(x,y_pred,'r-')plt.plot(x,y,'b.')
plt.xlabel('X')
plt.ylabel('Y')
plt.axis([0,2,0,15])
plt.title('SGD')
plt.show()

在这里插入图片描述
【小批量梯度下降(MBGD)】 把数据分为若干个批,按批来更新参数,利用每一批的数据来计算梯度的方向,下降起来就不容易跑偏,减少了随机性。

在实际操作的时候,需要重新对训练数据做索引打乱操作(shuffle)

下面是代码展示:

theta_for_mbgd=[]
epoches=50  # 50次迭代训练
batch=5 # 每次训练批次为5
m=len(x_b)
# lr学习率更新函数
def lr_update(t):return 5/(50+t)
t=0
# 初始化theta
theta=np.random.rand(2,1)for epoch in range(epoches):# 对训练数据打乱--洗牌shuffle_indexes=np.random.permutation(m) x_b_shuffle=x_b[shuffle_indexes]y_shuffle=y[shuffle_indexes]for i in range(0,m,batch):t=t+1     x_b_tmp=x_b_shuffle[i:i+batch]y_tmp=y_shuffle[i:i+batch]# 计算梯度gradent=2/batch*x_b_tmp.T.dot(x_b_tmp.dot(theta)-y_tmp)theta=theta-lr_update(t)*gradenttheta_for_mbgd.append(theta)# 画出部分图像if epoch<5 and t< 10 :y_pred=x_b.dot(theta)plt.plot(x,y_pred,'r-')plt.plot(x,y,'b.')plt.axis([0,2,0,15])
plt.xlabel('X')
plt.ylabel('Y')
plt.title('MBGD')
plt.show()

在这里插入图片描述
【三种梯度下降方法对比】下面画出了theta在三种梯度下降方法中的变化。如下图所示:
BGD红色曲线,沿着曲线直接到达终点,没有出现起伏波动;
SGD蓝色曲线,最终达到终点,但是起伏比较大;
MBGD绿色曲线,达到终点,有起伏,但是起伏不大。

theta_for_bgd=np.array(theta_for_bgd)
theta_for_sgd=np.array(theta_for_sgd)
theta_for_mbgd=np.array(theta_for_mbgd)
plt.figure(figsize=(8,4))
plt.subplot(1,3,1)
plt.plot(theta_for_bgd[:,0],theta_for_bgd[:,1],'r-s',linewidth=1,label='bgd')
plt.legend(loc='upper left')
plt.subplot(1,3,2)
plt.plot(theta_for_sgd[:,0],theta_for_sgd[:,1],'b-*',linewidth=1,label='sgd')
plt.legend(loc='upper left')
plt.subplot(1,3,3)
plt.plot(theta_for_mbgd[:,0],theta_for_mbgd[:,1],'g-+',linewidth=1,label='mbgd')
plt.legend(loc='upper left')plt.show()

在这里插入图片描述
三种梯度算法总结:

全批量梯度下降(BGD)

1、计算量大,参数更新慢,对内存的要求很高,不能以在线的形式训练模型,也就是运行时不能加入新样本2、可以得到全局最优解,参数更新比较稳定,收敛方向稳定。

随机梯度下降(SGD):

1、运算速度很快,同时能够在线学习。2、随机梯度下降参数更新的过程震荡很大,目标函数波动剧烈,参数更新方向有很大的波动。3、其较大的波动可能收敛到比批量梯度下降更小的局部极小值,因为会从一个极小值跳出来。

小批量梯度下降(MBGD):

1、降低了更新参数的方差,使得收敛过程更加的稳定2、能够利用高度优化的矩阵运算,很高效的求得每小批数据的梯度

多项式线性回归

之前的时候,我们采用的直线方程:y=4.7x+2然后加上随机变量生成测试数据,这里,我们首先通过y=2x^2+x+5来生成测试数据。生成的数据图像如下图所示:

tip:实际应用要处理的数据可能还要离散、无规律,这里主要是用来解释多项式回归问题。

# 生成y=3x^3+2x^2+x+5数据测试数据
m=100 # x的维度
x_2=4*np.random.rand(m,1)
y_2=2*x_2**2+x_2+5+2*np.random.randn(m,1) # 后面添加了一个正态分布
plt.plot(x_2,y_2,'r.')
plt.show()

在这里插入图片描述

# 按照上面数据,我们还是通过一元线性函数进行求解如下:
epoches=20
batch_size=8
x_2_b=np.c_[np.ones((100,1)),x_2]
# print(x_2_b)
theta=np.random.rand(2,1)for epoch in range(epoches):# 数据shuffleshuffle_indexes=np.random.permutation(m) x_b_shuffle=x_2_b[shuffle_indexes]y_shuffle=y_2[shuffle_indexes]for i in range(0,m,batch_size):x_b_tmp=x_b_shuffle[i:i+batch_size]y_tmp=y_shuffle[i:i+batch_size]# 计算梯度gradent=2/batch_size*x_b_tmp.T.dot(x_b_tmp.dot(theta)-y_tmp)theta=theta-lr_update(t)*gradentplt.plot(x_2,y_2,'r.')
y_pred=x_2_b.dot(theta)
plt.plot(x_2,y_pred,'b*')
plt.show()      

在这里插入图片描述

# 通过上图可以发现,通过直线的方法并不能够很好的拟合出曲线,这个时候就要选择多元函数进行拟合,这就是前面介绍的多项式回归
# 即利用y=ax^2+bx+c进行拟合:
epoches=500
batch_size=16
x_2_c=np.c_[np.ones((100,1)),x_2,x_2**2] # 这里可以通过添加x_2**3\x_2**4\....来计算不同degree的结果
# print(x_2_b)
theta=np.random.rand(3,1)for epoch in range(epoches):# 数据shuffleshuffle_indexes=np.random.permutation(m) x_b_shuffle=x_2_c[shuffle_indexes]y_shuffle=y_2[shuffle_indexes]for i in range(0,m,batch_size):x_b_tmp=x_b_shuffle[i:i+batch_size]y_tmp=y_shuffle[i:i+batch_size]# 计算梯度gradent=2/batch_size*x_b_tmp.T.dot(x_b_tmp.dot(theta)-y_tmp)theta=theta-lr_update(t)*gradentplt.plot(x_2,y_2,'r.')
x2y_pred=x_2_c.dot(theta)
# print(xy_pred)
plt.plot(x_2,x2y_pred,'b.')
plt.show()      

在这里插入图片描述

多变量线性回归

当一个函数不仅仅和一参数有关系的时候(例如:吴恩达教程里面房价可能和房子面积、房子建设时间、房子位置等;李宏毅教程里面的神奇宝贝cp值可能和神奇宝贝的属性值、成长系数、防御值等),就涉及到了多项式回归。
这里以函数z=3x+6y+2创造数据集:

# 依据z=3x+6y+10加上随机数字来生成训练数据(x,y,z),后面以该组数据作为训练数据进行训练,让训练结果无线逼近z=3x+6y+10
# 画出z=3x+6y+10的视图 scatter  contour3D  scatter3D  plot_surface  plot_wireframe
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
m=50
x=np.linspace(1,20,m)
y=np.linspace(1,20,m)
x,y=np.meshgrid(x,y)
x1=x.reshape(-1,1)
y1=y.reshape(-1,1)
z1=3*x1+6*y1+2+5*np.random.randn(m*m,1)
z=z1.reshape(m,m) # 此时构造的训练数据集为:x1(m*m,1),x2(m*m,1),z1((m*m,1))# 设置图像大小
plt.figure(dpi=100)ax=plt.axes(projection='3d')
ax.plot_surface(x,y,z)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()

在这里插入图片描述
依据上面生成的数据,通过梯度下降的方法训练得到的结果为:y=3.03x+6.01y+1.48,会发现这和y=3x+6y+2是非常接近的,另外下面两张图分别也展示了实际生成的平面、以及随着迭代次数增加loss的变化曲线。在实际应用中,多变量线性回归可能不知两个特征x,y,可能还有更多的值,但是都可以通过类似的方法训练。

# 根据提取下降来计算theta,
epoches=100
batch_size=256
theta_recode=[]
theta=np.random.rand(3,1)
x_y_b=np.c_[np.ones((m*m,1)),x1,y1]
t=1
y_loss=[]# lr学习率更新函数,学习率一开始选择的比较大,后面逐渐变小。
def lr_update(t):return 5/(1000+t)
# 损失函数
def costFunction(X,y,theta):inner =np.power( X @ theta - y, 2)return np.sum(inner) / (2 * len(X))
for epoch in range(epoches):shuffle_indexes=np.random.permutation(m*m) x_y_b_shuffle=x_y_b[shuffle_indexes]z_shuffle=z1[shuffle_indexes]for i in range(0,m*m,batch_size):x_y_b_temp=x_y_b_shuffle[i:i+batch_size]z_temp=z_shuffle[i:i+batch_size]gradent=1/batch_size*x_y_b_temp.T.dot(x_y_b_temp.dot(theta)-z_temp)theta=theta-lr_update(t)*gradent t+=1loss=costFunction(x_y_b,z1,theta)y_loss.append(loss)
#     print('this is the {} epoch, the loss is {}'.format(epoch,loss))print('theta={}'.format(theta))
# plot_function(theta)
plt.figure(dpi=150)
ax=plt.subplot(1,2,1,projection='3d')
# ax=plt.axes(projection='3d')
z_end=theta[1]*x+theta[2]*y+theta[0]
# 画图对比,之前的图和现在图对比
ax.plot_surface(x,y,z)
ax.plot_surface(x,y,z_end,color='r')plt.subplot(1,2,2)
x_loss=np.linspace(1,epoches,epoches)
plt.plot(x_loss,y_loss,'g-')
plt.subplots_adjust(wspace =0.5, hspace =0)
plt.show()

在这里插入图片描述

推荐阅读

[1] 必看!!【AINLPer】自然语言处理(NLP)领域知识&&资料大分享

[2]【NLP论文分享&&机器翻译】多语言标记训练中NMT对语言失衡的鲁棒性

[3]【NLP论文分享&&语言表示】有望颠覆Transformer的图循环神经网络(GNN)

[4]【NLP论文分享&&中文命名实体识别】如何构建一个优秀的Gazetteer/地名词典(浙大&含源码)

[5]一文看懂线性回归【比较详细】(内含源码)

[6]一文看懂逻辑回归【比较详细】(含源码)

最后不是最后

关注 AINLPer 微信公众号(每日都有最新的论文推荐给你!!

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(41)STM32——外部SRAM实验笔记

目录 学习目标 成果展示 硬件知识 特点 功能框图 读时序 ​编辑写时序 FSMC驱动 寄存器 闪存片选控制寄存器 硬件 配置 代码 总结 学习目标 今天我们要学习的是有关外部SRAM实验&#xff0c;其实F&#xff14;内部也是有一个&#xff11;&#xff19;&#x…

本周大新闻|索尼PS VR2体验首次公开;Meta Quest Pro开箱视频曝光

本周大新闻&#xff0c;AR方面&#xff0c;沃尔玛App加入AR试穿功能&#xff1b;谷歌搜索AR新增60个行星、卫星模型&#xff1b;Niantic宣布与漫威娱乐合作打造新款LBS AR游戏&#xff1b;AR眼镜ActiveLook打通Apple Watch。 VR方面&#xff0c;索尼PS VR2体验首次公开&#x…

2022年笔试知识总结展望

应届生的笔试知识总结&#xff0c;温故而知新&#xff0c;看看知识加深印象&#xff0c;希望学得更好&#xff0c;有个好结果。 目录 1. TCP的拥塞控制 2. position属性 3. [‘1‘, ‘2‘, ‘3‘].map(parseInt) 输出结果 4. 排序算法的稳定性分析 1&#xff09;稳定的排…

事件研究法与其应用(2)---Excel实操步骤

我们借着学习事件研究法的应用,可以用Excel和Stata等软件进行操作。 今天这主要是利用EXCEL计算累积异常收益率。 在正式开展实操之前,我们先回顾一下事件研究法的步骤(尤其是我们写作论文的时候): 事件研究法计算步骤: 1. 获取数据,定义事件期 2.计算估计期间个股与市…

npm yarn 报错

目录npm yarn报错yarn: 无法加载文件 npm yarn报错 yarn: 无法加载文件 win10系统,yarn : 无法加载文件 C:\Users\丽丽小可爱\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 ... 导致此错误的原因是,PowerShell 执行策略,默认设置为Rest…

JSON 数据类型转换工具

简介 本文介绍一款数据类型转换工具&#xff0c;可以将JSON格式数据转换成YAML、MYSQL、XML、TOML、JavaScript等数据类型。 背景 在日常的开发工程中&#xff0c;我们经常使用JSON表达数据&#xff0c;但有些时候我们需要使用YAML、JavaScript等语言表达数据。因此&#xf…

HTML + HTTP请求 +CSS知识点

文章目录HTML1.HTML元素2.HTML页面3.常见元素1&#xff09;文本2&#xff09;多媒体3&#xff09;表单作用与语法常见表单项案例体验4.HTTP请求1&#xff09;请求组成2&#xff09; 请求方式与数据格式get 请求示例post 请求&#xff08;默认格式&#xff09;示例json 请求&…

Python必知必会 os 模块详解

文章目录Python os 模块os模块的常用操作os.path模块os.open()模块Python os 模块 os是“operating system”的缩写&#xff0c;os模块提供各种 Python 程序与操作系统进行交互的接口&#xff0c;使用os模块&#xff0c;一方面可以方便地与操作系统进行交互&#xff0c;另一方…

【SLAM】4李群李代数

文章目录4.1.基础群李代数的引出李代数李代数so(3)\mathfrak{so}(3)so(3)李代数se(3)\mathfrak{se}(3)se(3)4.2.指数与对数映射4.2.1.SO(3)SO(3)SO(3)指数映射4.2.2.SE(3)SE(3)SE(3)的指数映射4.3.李代数求导与扰动模型4.3.1.BCH公式&近似形式4.3.2.李代数求导4.3.4.扰动模…

redis下载与安装(Linux环境下)

用的是阿里云的深度os Linux系统 一&#xff0c;下载 键入命令&#xff1a; wget http://download.redis.io/releases/redis-6.2.1.tar.gz 检查时候有gcc环境 gcc --version 若有gcc环境会有类似于下图的提示 没有则执行&#xff1a; yum install gcc 下载完毕之后&…

JavaEE基础知识

文章目录前言计算机的基本组成CPUCPU运行程序的过程CPU的构造操作系统操作系统功能常见的操作系统操作系统的具体组成操作系统的进程管理(重点)操作系统安排程序进程PCB(进程管理块)进程调度关于进程的几个属性虚拟地址空间线程(thread [θred] )前言 之前已经学过很多的知识,…

企业薪资系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

PostgreSQL - 基于pg_basebackup实现主从流复制

PostgreSQL - 基于pg_basebackup实现主从流复制1 数据库节点2 安装PostgreSQL2.1 创建postgres用户2.2 安装PostgreSQL3 配置主节点4 配置从节点5 验证主从同步1 数据库节点 节点ip节点角色192.168.163.133主节点192.168.163.134从节点 2 安装PostgreSQL 2.1 创建postgres用户…

计算机网络——数据链路层(滑动窗口协议: 选择重传)(点对点协议 PPP)

目录 滑动窗口协议: 选择重传 选择重传协议 选择重传协议 点对点协议 PPP PPP 的主要特点 PPP 协议有三个组成部分 PPP 协议的帧格式 PPP 有一个 2 个字节的协议字段 透明传输问题 PPP 的字符填充 PPP 的工作状态 滑动窗口协议: 选择重传 选择重传协议 GBN相对简单&a…

【周末闲谈】谈谈数学转码这一年来的体会与反思

——我们走了太远&#xff0c;以至于忘了为何出发 前言 笔者本科读的是数学专业&#xff0c;就是每天和数学分析、高等代数、概率论、随机过程等等这些理论打交道的专业&#xff0c;这个专业出来工作好像一般有两个方向就是金融和计算机&#xff0c;我选择了计算机方向。主要…

2022 第五届 浙江省大学生网络与信息安全竞赛技能赛 预赛 Writeup,5题

文章目录1、Web&#xff1a;nisc_easyweb2、Web&#xff1a;nisc_学校门户网站3、Web&#xff1a;吃豆人吃豆魂4、MISC&#xff1a;好怪哦5、RE&#xff1a;ManyCheck1、Web&#xff1a;nisc_easyweb 题目描述&#xff1a; 打开网站&#xff0c;是一个php的初始页面。 思路…

springboot+微信小程序的点餐系统(开题报告+论文+答辩PPT+源码)

技术架构 SprongBootMysql微信小程序 简介 本点餐小程序是使用Java/JavaScript编程语言开发的&#xff0c;存储数据方面则用到了MySQL数据库。顾客可以使用小程序扫码功能扫描餐厅桌角的二维码就座&#xff0c;也可以点击排号等位由后台工作人员安排就座&#xff1b;通过首页…

通关GO语言10 Context:你必须掌握的多线程并发控制神器

在上一节课中我留了一个作业&#xff0c;也就是让你自己练习使用 sync.Map&#xff0c;相信你已经做出来了。现在我为你讲解 sync.Map 的方法。 Store&#xff1a;存储一对 key-value 值。 Load&#xff1a;根据 key 获取对应的 value 值&#xff0c;并且可以判断 key 是否存在…

GO面试题集锦

GO面试题集锦 目录GO面试题集锦slice 扩容机制slice 为什么不是线程安全的map 底层原理map 扩容机制map 遍历为什么无序map 为什么不是线程安全的Map 如何查找Map 冲突解决方式Map 负载因子为什么是 6.5Map 和 Sync.Map 哪个性能好Channel 底层实现原理Channel 有什么特点Chann…

docker实战教程(七):镜像的分层概念

联合文件系统(UnionFS) 联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。联合文件系统是docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像…