Python 全栈体系【四阶】(七)

第四章 机器学习

六、多项式回归

1. 什么是多项式回归

线性回归适用于数据呈线性分布的回归问题。如果数据样本呈明显非线性分布,线性回归模型就不再适用(下图左),而采用多项式回归可能更好(下图右)。例如:

在这里插入图片描述

2. 多项式模型定义

与线性模型相比,多项式模型引入了高次项,自变量的指数大于 1,例如一元二次方程:

y = w 0 + w 1 x + w 2 x 2 y = w_0 + w_1x + w_2x^2 y=w0+w1x+w2x2

一元三次方程:

y = w 0 + w 1 x + w 2 x 2 + w 3 x 3 y = w_0 + w_1x + w_2x^2 + w_3x ^ 3 y=w0+w1x+w2x2+w3x3

推广到一元 n 次方程:

y = w 0 + w 1 x + w 2 x 2 + w 3 x 3 + . . . + w n x n y = w_0 + w_1x + w_2x^2 + w_3x ^ 3 + ... + w_nx^n y=w0+w1x+w2x2+w3x3+...+wnxn

上述表达式可以简化为:

y = ∑ i = 1 N w i x i y = \sum_{i=1}^N w_ix^i y=i=1Nwixi

3. 与线性回归的关系

多项式回归可以理解为线性回归的扩展,在线性回归模型中添加了新的特征值。例如,要预测一栋房屋的价格,有 x 1 , x 2 , x 3 x_1, x_2, x_3 x1,x2,x3三个特征值,分别表示房子长、宽、高,则房屋价格可表示为以下线性模型:

y = w 1 x 1 + w 2 x 2 + w 3 x 3 + b y = w_1 x_1 + w_2 x_2 + w_3 x_3 + b y=w1x1+w2x2+w3x3+b

对于房屋价格,也可以用房屋的体积,而不直接使用 x 1 , x 2 , x 3 x_1, x_2, x_3 x1,x2,x3三个特征:

y = w 0 + w 1 x + w 2 x 2 + w 3 x 3 y = w_0 + w_1x + w_2x^2 + w_3x ^ 3 y=w0+w1x+w2x2+w3x3

相当于创造了新的特征 x , x x, x x,x = 长 _ 宽 _ 高。

以上两个模型可以解释为:

房屋价格是关于长、宽、高三个特征的线性模型

房屋价格是关于体积的多项式模型

因此,可以将一元 n 次多项式变换成 n 元一次线性模型。

4. 多项式回归实现

对于一元 n 次多项式,同样可以利用梯度下降对损失值最小化的方法,寻找最优的模型参数 w 0 , w 1 , w 2 , . . . , w n w_0, w_1, w_2, ..., w_n w0,w1,w2,...,wn。可以将一元 n 次多项式,变换成 n 元一次多项式,求线性回归。以下是一个多项式回归的实现。

# 多项式回归示例
import numpy as np
# 线性模型
import sklearn.linear_model as lm
# 模型性能评价模块
import sklearn.metrics as sm
import matplotlib.pyplot as mp
# 管线模块
import sklearn.pipeline as pl
import sklearn.preprocessing as sptrain_x, train_y = [], []   # 输入、输出样本
with open("poly_sample.txt", "rt") as f:for line in f.readlines():data = [float(substr) for substr in line.split(",")]train_x.append(data[:-1])train_y.append(data[-1])train_x = np.array(train_x)  # 二维数据形式的输入矩阵,一行一样本,一列一特征
train_y = np.array(train_y)  # 一维数组形式的输出序列,每个元素对应一个输入样本
# print(train_x)
# print(train_y)# 将多项式特征扩展预处理,和一个线性回归器串联为一个管线
# 多项式特征扩展:对现有数据进行的一种转换,通过将数据映射到更高维度的空间中
# 进行多项式扩展后,我们就可以认为,模型由以前的直线变成了曲线
# 从而可以更灵活的去拟合数据
# pipeline连接两个模型
model = pl.make_pipeline(sp.PolynomialFeatures(3), # 多项式特征扩展,扩展最高次项为3lm.LinearRegression())# 用已知输入、输出数据集训练回归器
model.fit(train_x, train_y)
# print(model[1].coef_)
# print(model[1].intercept_)# 根据训练模型预测输出
pred_train_y = model.predict(train_x)# 评估指标
err4 = sm.r2_score(train_y, pred_train_y)  # R2得分, 范围[0, 1], 分值越大越好
print(err4)# 在训练集之外构建测试集
test_x = np.linspace(train_x.min(), train_x.max(), 1000)
pre_test_y = model.predict(test_x.reshape(-1, 1)) # 对新样本进行预测# 可视化回归曲线
mp.figure('Polynomial Regression', facecolor='lightgray')
mp.title('Polynomial Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(train_x, train_y, c='dodgerblue', alpha=0.8, s=60, label='Sample')mp.plot(test_x, pre_test_y, c='orangered', label='Regression')mp.legend()
mp.show()

打印输出:

0.9224401504764776

执行结果:

在这里插入图片描述

5. 过拟合与欠拟合

5.1 什么是欠拟合、过拟合

在上一小节多项式回归示例中,多项特征扩展器 PolynomialFeatures()进行多项式扩展时,指定了最高次数为 3,该参数为多项式扩展的重要参数,如果选取不当,则可能导致不同的拟合效果。下图显示了该参数分别设为 1、20 时模型的拟合图像:

在这里插入图片描述

这两种其实都不是好的模型。前者没有学习到数据分布规律,模型拟合程度不够,预测准确度过低,这种现象称为“欠拟合”;后者过于拟合更多样本,以致模型泛化能力(新样本的适应性)变差,这种现象称为“过拟合”。欠拟合模型一般表现为训练集、测试集下准确度都比较低;过拟合模型一般表现为训练集下准确度较高、测试集下准确度较低。 一个好的模型,不论是对于训练数据还是测试数据,都有接近的预测精度,而且精度不能太低。

【思考 1】以下哪种模型较好,哪种模型较差,较差的原因是什么?

训练集 R2 值测试集 R2 值
0.60.5
0.90.6
0.90.88

【答案】第一个模型欠拟合;第二个模型过拟合;第三个模型适中,为可接受的模型。

【思考 2】以下哪个曲线为欠拟合、过拟合,哪个模型拟合最好?

在这里插入图片描述

【答案】第一个模型欠拟合;第三个模型过拟合;第二个模型拟合较好。

5.2 如何处理欠拟合、过拟合

欠拟合:提高模型复杂度,如增加特征、增加模型最高次幂等等;

过拟合:降低模型复杂度,如减少特征、降低模型最高次幂等等。

七、线性回归模型变种

1. 正则化

1.1 什么是正则化

过拟合还有一个常见的原因,就是模型参数值太大,所以可以通过抑制参数的方式来解决过拟合问题。如下图所示,右图产生了一定程度过拟合,可以通过弱化高次项的系数(但不删除)来降低过拟合。

在这里插入图片描述

例如,可以通过在 θ 3 , θ 4 \theta_3, \theta_4 θ3,θ4的系数上添加一定的系数,来压制这两个高次项的系数,这种方法称为正则化。但在实际问题中,可能有更多的系数,我们并不知道应该压制哪些系数,所以,可以通过收缩所有系数来避免过拟合。

1.2 正则化的定义

正则化是指,在目标函数后面添加一个范数,来防止过拟合的手段,这个范数定义为:

∣ ∣ x ∣ ∣ p = ( ∑ i = 1 N ∣ x ∣ p ) 1 p ||x||_p = (\sum_{i=1}^N |x|^p)^{\frac{1}{p}} ∣∣xp=(i=1Nxp)p1

当 p=1 时,称为 L1 范数(即所有系数绝对值之和):

∣ ∣ x ∣ ∣ 1 = ( ∑ i = 1 N ∣ x ∣ ) ||x||_1 = (\sum_{i=1}^N |x|) ∣∣x1=(i=1Nx)

当 p=2 是,称为 L2 范数(即所有系数平方之和再开方):

∣ ∣ x ∣ ∣ 2 = ( ∑ i = 1 N ∣ x ∣ 2 ) 1 2 ||x||_2 = (\sum_{i=1}^N |x|^2)^{\frac{1}{2}} ∣∣x2=(i=1Nx2)21

通过对目标函数添加正则项,整体上压缩了参数的大小,从而防止过拟合。

2. Lasso 回归与岭回归

Lasso 回归和岭回归(Ridge Regression)都是在标准线性回归的基础上修改了损失函数的回归算法。 Lasso 回归全称为 Least absolute shrinkage and selection operator,又译“最小绝对值收敛和选择算子”、”套索算法”,其损失函数如下所示:

E = 1 n ( ∑ i = 1 N y i − y i ′ ) 2 + λ ∣ ∣ w ∣ ∣ 1 E = \frac{1}{n}(\sum_{i=1}^N y_i - y_i')^2 + \lambda ||w||_1 E=n1(i=1Nyiyi)2+λ∣∣w1

岭回归损失函数为:

E = 1 n ( ∑ i = 1 N y i − y i ′ ) 2 + λ ∣ ∣ w ∣ ∣ 2 E = \frac{1}{n}(\sum_{i=1}^N y_i - y_i')^2 + \lambda ||w||_2 E=n1(i=1Nyiyi)2+λ∣∣w2

从逻辑上说,Lasso 回归和岭回归都可以理解为通过调整损失函数,减小函数的系数,从而避免过于拟合于样本,降低偏差较大的样本的权重和对模型的影响程度。

线性模型变种模型:在损失函数后面 + 正则项

  • 损失函数 + L1 范数 -> Lasso 回归
  • 损失函数 + L2 范数 -> 岭回归

以下关于 Lasso 回归于岭回归的 sklearn 实现:

# Lasso回归和岭回归示例
import numpy as np
# 线性模型
import sklearn.linear_model as lm
# 模型性能评价模块
import sklearn.metrics as sm
import matplotlib.pyplot as mpx, y = [], []  # 输入、输出样本
with open("abnormal.txt", "rt") as f:for line in f.readlines():data = [float(substr) for substr in line.split(",")]x.append(data[:-1])y.append(data[-1])x = np.array(x)  # 二维数据形式的输入矩阵,一行一样本,一列一特征
y = np.array(y)  # 一维数组形式的输出序列,每个元素对应一个输入样本
# print(x)
# print(y)# 创建线性回归器
model = lm.LinearRegression()
# 用已知输入、输出数据集训练回归器
model.fit(x, y)
# 根据训练模型预测输出
pred_y = model.predict(x)# 创建岭回归器并进行训练
# Ridge: 第一个参数为正则强度,该值越大,异常样本权重就越小
model_2 = lm.Ridge(alpha=200, max_iter=1000)  # 创建对象, max_iter为最大迭代次数
model_2.fit(x, y)  # 训练
pred_y2 = model_2.predict(x)  # 预测# lasso回归
model_3 = lm.Lasso(alpha=0.5,  # L1范数相乘的系数max_iter=1000)  # 最大迭代次数
model_3.fit(x, y)  # 训练
pred_y3 = model_3.predict(x)  # 预测# 可视化回归曲线
mp.figure('Linear & Ridge & Lasso', facecolor='lightgray')
mp.title('Linear & Ridge & Lasso', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(x, y, c='dodgerblue', alpha=0.8, s=60, label='Sample')
sorted_idx = x.T[0].argsort()mp.plot(x[sorted_idx], pred_y[sorted_idx], c='orangered', label='Linear')  # 线性回归
mp.plot(x[sorted_idx], pred_y2[sorted_idx], c='limegreen', label='Ridge')  # 岭回归
mp.plot(x[sorted_idx], pred_y3[sorted_idx], c='blue', label='Lasso')  # Lasso回归mp.legend()
mp.show()

以下是执行结果:

在这里插入图片描述

八、模型保存与加载

可以使用 Python 提供的功能对模型对象进行保存。使用方法如下:

import pickle
# 保存模型
pickle.dump(模型对象, 文件对象)
# 加载模型
model_obj = pickle.load(文件对象)

保存训练模型应该在训练完成或评估完成之后,完整代码如下:

# 模型保存示例
import numpy as np
import sklearn.linear_model as lm # 线性模型
import picklex = np.array([[0.5], [0.6], [0.8], [1.1], [1.4]])  # 输入集
y = np.array([5.0, 5.5, 6.0, 6.8, 7.0])  # 输出集# 创建线性回归器
model = lm.LinearRegression()
# 用已知输入、输出数据集训练回归器
model.fit(x, y)print("训练完成.")# 保存训练后的模型
with open('linear_model.pkl', 'wb') as f:pickle.dump(model, f)print("保存模型完成.")

执行完成后,可以看到与源码相同目录下多了一个名称为 linear_model.pkl 的文件,这就是保存的训练模型。使用该模型代码:

# 模型加载示例
import numpy as np
import sklearn.linear_model as lm  # 线性模型
import sklearn.metrics as sm  # 模型性能评价模块
import matplotlib.pyplot as mp
import picklex = np.array([[0.5], [0.6], [0.8], [1.1], [1.4]])  # 输入集
y = np.array([5.0, 5.5, 6.0, 6.8, 7.0])  # 输出集# 加载模型
with open('linear_model.pkl', 'rb') as f:model = pickle.load(f)print("加载模型完成.")# 根据加载的模型预测输出
pred_y = model.predict(x)# 可视化回归曲线
mp.figure('Linear Regression', facecolor='lightgray')
mp.title('Linear Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(x, y, c='blue', alpha=0.8, s=60, label='Sample')mp.plot(x, pred_y, c='orangered', label='Regression')mp.legend()
mp.show()

执行结果和训练模型预测结果一样。

九、总结

1. 什么是线性模型

线性模型是自然界最简单的模型之一,反映自变量、因变量之间的等比例增长关系。

2. 什么时候使用线性回归

线性模型只能用于满足线性分布规律的数据中。

3. 如何实现线性回归

给定一组样本,给定初始的 w 和 b,通过梯度下降法求最优的 w 和 b。

十、补充知识

1. R2 系数详细计算

R2 系数详细计算过程如下:

若用 y i y_i yi表示真实的观测值,用 y ˉ \bar{y} yˉ表示真实观测值的平均值,用 y i ^ \hat{y_i} yi^表示预测值,则有以下评估指标:

回归平方和(SSR)

S S R = ∑ i = 1 n ( y i ^ − y ˉ ) 2 SSR = \sum_{i=1}^{n}(\hat{y_i} - \bar{y})^2 SSR=i=1n(yi^yˉ)2

  • 估计值与平均值的误差,反映自变量与因变量之间的相关程度的偏差平方和。

残差平方和(SSE)

S S E = ∑ i = 1 n ( y i − y i ^ ) 2 SSE = \sum_{i=1}^{n}(y_i-\hat{y_i} )^2 SSE=i=1n(yiyi^)2

  • 即估计值与真实值的误差,反映模型拟合程度。

总离差平方和(SST)

S S T = S S R + S S E = ∑ i = 1 n ( y i − y ˉ ) 2 SST =SSR + SSE= \sum_{i=1}^{n}(y_i - \bar{y})^2 SST=SSR+SSE=i=1n(yiyˉ)2

  • 即平均值与真实值的误差,反映与数学期望的偏离程度.
R2_score 计算公式

R2_score,即决定系数,反映因变量的全部变异能通过回归关系被自变量解释的比例。计算公式:

R 2 = 1 − S S E S S T R^2=1-\frac{SSE}{SST} R2=1SSTSSE

即:

R 2 = 1 − ∑ i = 1 n ( y i − y ^ i ) 2 ∑ i = 1 n ( y i − y ˉ ) 2 R^2 = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)2}{\sum_{i=1}{n} (y_i - \bar{y})^2} R2=1i=1n(yiyˉ)2i=1n(yiy^i)2

进一步化简为:

R 2 = 1 − ∑ i ( y i − y i ) 2 / n ∑ i ( y i − y ^ ) 2 / n = 1 − R M S E V a r R^2 = 1 - \frac{\sum\limits_i(y_i - y_i)^2 / n}{\sum\limits_i(y_i - \hat{y})^2 / n} = 1 - \frac{RMSE}{Var} R2=1i(yiy^)2/ni(yiyi)2/n=1VarRMSE

分子就变成了常用的评价指标均方误差 MSE,分母就变成了方差,对于 R 2 R^2 R2可以通俗地理解为使用均值作为误差基准,看预测误差是否大于或者小于均值基准误差。

R2_score = 1,样本中预测值和真实值完全相等,没有任何误差,表示回归分析中自变量对因变量的解释越好。

R2_score = 0,此时分子等于分母,样本的每项预测值都等于均值。

2. 线性回归损失函数求导过程

线性函数定义为:

y = w 0 + w 0 x 1 y = w_0 + w_0 x_1 y=w0+w0x1

采用均方差损失函数:

l o s s = 1 2 ( y − y ′ ) 2 loss = \frac{1}{2} (y - y')^2 loss=21(yy)2

其中,y 为真实值,来自样本;y’为预测值,即线性方程表达式,带入损失函数得:

l o s s = 1 2 ( y − ( w 0 + w 1 x 1 ) ) 2 loss = \frac{1}{2} (y - (w_0 + w_1 x_1))^2 loss=21(y(w0+w1x1))2

将该式子展开:

l o s s = 1 2 ( y 2 − 2 y ( w 0 + w 1 x 1 ) + ( w 0 + w 1 x 1 ) 2 ) = 1 2 ( y 2 − 2 y ∗ w 0 − 2 y ∗ w 1 x 1 + w 0 2 + 2 w 0 ∗ w 1 x 1 + w 1 2 x 1 2 ) loss = \frac{1}{2} (y^2 - 2y(w_0 + w_1 x_1) + (w_0 + w_1 x_1)^2) =\\\frac{1}{2} (y^2 - 2y*w_0 - 2y*w_1x_1 + w_0^2 + 2w_0*w_1 x_1 + w_1^2x_1^2) \\ loss=21(y22y(w0+w1x1)+(w0+w1x1)2)=21(y22yw02yw1x1+w02+2w0w1x1+w12x12)

w 0 w_0 w0求导:

∂ l o s s ∂ w 0 = 1 2 ( 0 − 2 y − 0 + 2 w 0 + 2 w 1 x 1 + 0 ) = 1 2 ( − 2 y + 2 w 0 + 2 w 1 x 1 ) = 1 2 ∗ 2 ( − y + ( w 0 + w 1 x 1 ) ) = ( − y + y ′ ) = − ( y − y ′ ) \frac{\partial loss}{\partial w_0} = \frac{1}{2}(0-2y-0+2w_0 + 2w_1 x_1 +0) \\=\frac{1}{2}(-2y + 2 w_0 + 2w_1 x_1) \\= \frac{1}{2} * 2(-y + (w_0 + w_1 x_1)) \\=(-y + y') = -(y - y') w0loss=21(02y0+2w0+2w1x1+0)=21(2y+2w0+2w1x1)=212(y+(w0+w1x1))=(y+y)=(yy)

w 1 w_1 w1求导:

∂ l o s s ∂ w 1 = 1 2 ( 0 − 0 − 2 y ∗ x 1 + 0 + 2 w 0 x 1 + 2 w 1 x 1 2 ) = 1 2 ( − 2 y x 1 + 2 w 0 x 1 + 2 w 1 x 1 2 ) = 1 2 ∗ 2 x 1 ( − y + w 0 + w 1 x 1 ) = x 1 ( − y + y ′ ) = − x 1 ( y − y ′ ) \frac{\partial loss}{\partial w_1} = \frac{1}{2}(0-0-2y*x_1+0+2 w_0 x_1 + 2 w_1 x_1^2) \\= \frac{1}{2} (-2y x_1 + 2 w_0 x_1 + 2w_1 x_1^2) \\= \frac{1}{2} * 2 x_1(-y + w_0 + w_1 x_1) \\= x_1(-y + y') = - x_1(y - y') w1loss=21(002yx1+0+2w0x1+2w1x12)=21(2yx1+2w0x1+2w1x12)=212x1(y+w0+w1x1)=x1(y+y)=x1(yy)

推导完毕。

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

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

相关文章

回归预测 | MATLAB实现GA-LSSVM基于遗传算法优化最小二乘向量机的多输入单输出数据回归预测模型 (多指标,多图)

回归预测 | MATLAB实现GA-LSSVM基于遗传算法优化最小二乘向量机的多输入单输出数据回归预测模型 (多指标,多图) 目录 回归预测 | MATLAB实现GA-LSSVM基于遗传算法优化最小二乘向量机的多输入单输出数据回归预测模型 (多指标&#…

Relocations for this machine are not implemented,IDA版本过低导致生成汇编代码失败

目录 1、问题描述 2、安卓app发生崩溃,需要查看汇编代码上下文去辅助分析 3、使用IDA打开.so动态库文件,提示Relocations for this machine are not implemented 4、IDA版本较老,不支持ARM64的指令集,使用7.0版本就可以了 5、…

vue中echarts柱状图点击x轴数据复制

参考自:Vue 3 使用 vue-echarts 的柱状图 barItem 和 x, y 轴点击事件实现_echarts x轴点击事件-CSDN博客 例如柱状图如下: 步骤: 一、数据处理的时候需要在 xAxis 对象中添加:triggerEvent: true 这个键值对,以增加…

vscode如何开发微信小程序?(保姆级教学)

1.安装“微信小程序开发工具”扩展 2.安装“vscode weapp api”扩展 3.安装“vscode wxml”扩展 4.安装“vscode-wechat”扩展 5.在终端执行命令: vue create -p dcloudio/uni-preset-vue uniapp-test uniapp-test就是我这里的项目名称了 6.如果遇到了这个错误&a…

构建平战结合的融合通信指挥调度系统平台

华脉智联PTTLINK融合通信指挥调度系统将语音、视频、GIS进行高度融合,构建“平战结合”的指挥调度模式,既满足平时的日常办公、会议会商、应急培训、应急演练等需求,也能够应对战时的应急指挥、应急救援、应急决策等需求,达到统一…

前端性能监控和错误监控

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

积极办理等保测评,保证企业网络安全!

随着网络的越发普及以及发达,网络安全问题日益突出,保障网络安全越发重要。为了保障网络系统的安全稳定运行,办理等保测评成为了企业和组织必须面对的重要任务。简单来说就是,积极办理等保测评,保证企业网络安全&#…

1005. K 次取反后最大化的数组和 增强for循环(foreach循环)遍历数组

1005. K 次取反后最大化的数组和 原题链接:完成情况:解题思路:参考代码:_1005K次取反后最大化的数组和_1005K次取反后最大化的数组和_简洁写法 错误经验吸取增强for循环(foreach循环)遍历数组 原题链接&am…

Kafka--从Zookeeper数据理解Kafka集群工作机制

从Zookeeper数据理解Kafka集群工作机制 这一部分主要是理解Kafka的服务端重要原理。但是Kafka为了保证高吞吐,高性能,高可扩展的三高架构,很多具体设计都是相当复杂的。如果直接跳进去学习研究,很快就会晕头转向。所以&#xff0c…

亚信科技AntDB数据库——深入了解AntDB-M元数据锁的实现(二)

5.5 防止低优先级锁饥饿 AntDB-M按照优先级将锁又分了两类,用于解决低优先级锁饥饿问题。 ●独占型(hog): X, SNRW, SNW; 具有较强的不兼容性,优先级高,容易霸占锁,造成其他低优先级锁一直处于等待状态。 ●暗弱型(piglet): SW; …

【leetcode876】链表的中间结点Java代码讲解

12.19 链表的中间结点 给你单链表的头结点 head ,请你找出并返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 示例 1: 输入:head [1,2,3,4,5] 输出:[3,4,5] 解释:链表只有一个中间结点&a…

P2P网络下分布式文件共享场景的测试

P2P网络介绍 P2P是Peer-to-Peer的缩写,“Peer”在英语里有“对等者、伙伴、对端”的意义。因此,从字面意思来看,P2P可以理解为对等网络。国内一些媒体将P2P翻译成“点对点”或者“端对端”,学术界则统一称为对等网络(Peer-to-Pee…

Redis7--基础篇9(SpringBoot集成Redis)

1. jedis、lettuce、Redistemplate的关系 第一代为jedis,之后推出了lettuce,然后springboot继承了Redistemplate,现推荐使用Redistemplate。 总的来说,jedis、lettuce、Redistemplate都是java操作Redis数据库的驱动。 2. 本地Ja…

骨传导耳机和开放式耳机有什么区别?一文读懂骨传导耳机和开放式的关系!

先说结论,骨传导耳机和气传导耳机两者都属于是开放式耳机,开放式耳机指的是开放双耳佩戴的耳机! 开放式耳机分为两种,分别是骨传导耳机和气传导耳机,虽然两者都属于开放式耳机,但它们的佩戴方式和传声原理…

【Unity】运行时创建曲线(贝塞尔的运用)

[Unity]运行时创建线(贝塞尔的运用) 1. 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线。 2. 原理介绍 2.1 曲线的创建 unity建立网格曲线可以参考Unity程序化网格体的实现方法。主要分为顶点,三角面&#xff0c…

数据分析为何要学统计学(10)——如何进行比率检验

比率检验是通过样本推测某种事件的总体占比水平。要求事件仅有互斥的两种情况,即,概率分别为p与1-p。 比率检验分单样本和双样本两种情况,以下我们分别介绍。 1. 单样本比率检验 形如这样的问题:“小学生近视比例日益提高&#…

Starting the Docker Engine...一直转圈

出现的问题: 原因排查: 看了网上的很多篇文章,每个原因都排查了,没有发现问题。 遇到这样的情况应先看自己是否安装成功 打开运行,在空框中输入powershell并点击确定: docker version 显示版本证明安装…

2023年国赛高教杯数学建模D题圈养湖羊的空间利用率解题全过程文档及程序

2023年国赛高教杯数学建模 D题 圈养湖羊的空间利用率 原题再现 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养,适应不同种类、不同阶段的牲畜对空间的不同要求,以保障牲畜安全和健康;与此同时,也要尽量减少空间闲置所…

微服务技术 RabbitMQ SpringAMQP P61-P76

B站学习视频https://www.bilibili.com/video/BV1LQ4y127n4?p61&vd_source8665d6da33d4e2277ca40f03210fe53a 文档资料: 链接:https://pan.baidu.com/s/1P_Ag1BYiPaF52EI19A0YRw?pwdd03r 提取码:d03r 一 初始MQ 1. 同步通讯 2. 异步通讯 3. MQ常…

Jenkins 添加节点报错

报错日志 Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.UnsupportedClassVersionError: hudson/remoting/Launcher has been compiled by a more recent version of the Java Runtime (cl…