线性回归(一)

server/2024/10/24 9:14:57/

线性回归

1.基本术语

①特征:预测所依据的自变量称为特征或协变量

②标签:试图预测的目标称为标签或目标

2.举个栗子

线性假设是指目标(房屋价格)可以表示为特征(面积和房龄)的加权和,如下面的式子:

绘制图像如下图所示:

可知平面无法拟合所有的数据点,所以需求变成让尽可能多的点落在平面上,这个需要权重和偏置项来调整平面位置和倾斜度。

③权重决定了每个特征对我们预测值的影响

④偏置是指当所有特征都取值为0时,预测值应该为多少,对图像进行平移功能。

常见的为点积形式:

整合2.1.2式子可得

(2.1.3)

⑤误差(损失函数)

量化实际值与预测值之间存在的差距(用ε表示该误差)

对于每个样本存在该式:

(2.1.4)

(真实值=预测值+误差项),误差值越小表示损失越小。

误差ε是独立并且具有相同的分布,并且服从均值为0方差为θ^2的高斯分布。独立表示一个变量的值不会影响另一个变量的值,同分布表示具有相同的统计特性,高斯分布:绝大多数情况下浮动不会太大,极小情况下浮动会比较大,符合正常情况

由于误差服从高斯分布:

(2.1.5)

将2.1.4代入2.1.5可得:

(2.1.6)

可以找到一个关于θ似然函数:

(2.1.7)

由于我们仅仅关注极值点的位置,并不关注极值的大小,所以可以给两边取对数,就可以将累乘变成累加,得到:

(2.1.8)

由logAB=logA+logB可得:

(2.1.9)

2.1.9公式可以看作是一个常数减去一个平方数的形式,所以要找2.1.9式的极大值,就可以看作找后面平方数的极小值,可得:

当样本i的预测值为y^i,其相应的真实标签为ytrue^i时, 平方误差可以定义为以下公式:

(2.1.10)

将2.1.4式代入2.1.11中可得

(2.1.11)

3.梯度下降算法

梯度下降算法的核心思想是:从一个初始点开始,沿着目标函数的梯度(最陡上升方向)的反方向迭代地更新参数,直到达到最小值。

首先由上面的推导,我们可以得出线性回归的目标函数为:

img

(3.1.1)

我们的目标是找后面平方数的极小值,所以对4.1.1式进行求导可得:

其中m为样本的数量,我们对J求关于θ的偏导得到梯度方程式

img

(3.1.2)

梯度下降算法原理就是每次迭代过程对参数向梯度反方向前进梯度个步数生成新的参数、直到找到最拟合目标函数的参数为止。

批量梯度下降:每次前进总样本的平均梯度,容易得到最优解,但是速度很慢,在数据量大的时候一般不使用,参数迭代方程式如下:

img

(3.1.3)

随机梯度下降:每次找一个样本的梯度进行迭代,速度快,但是随机性强,每次迭代不一定向着收敛的方向,参数迭代方程式如下:

img

(3.1.4)

小批量梯度下降:每次使用一小部分的平均梯度进行迭代,速度快,迭代方向也比较好,经常被使用,参数迭代方程式(12)如下:

img

(3.1.5)

其中α为学习率

4.代码实现

python">import numpy as np
​
def normalize(features):"""特征归一化:param features: 传入特征:return: 归一化后的特征,特征均值,特征标准差"""features_normalized = np.copy(features).astype(float)# 计算均值features_mean = np.mean(features, 0)# 计算标准差features_deviation = np.std(features, 0)# 标准化操作if features.shape[0] > 1:features_normalized -= features_mean# 防止除以0features_deviation[features_deviation == 0] = 1features_normalized /= features_deviationreturn features_normalized, features_mean, features_deviation
python">import numpy as np
import normalize
​
​
def generate_polynomials(dataset, polynomials_degree, normalize_data=False):"""变换方法:x1, x2, x1^2, x2^2, x1 * x2, x1 * x2^2, etc.:param dataset:原始数据:param polynomials_degree:多项式的维度:param normalize_data:是否归一化:return:生成的多项式参数"""features_split = np.array_split(dataset, 2, axis=1)dataset_1 = features_split[0]dataset_2 = features_split[1]
​(num_examples_1, num_features_1) = dataset_1.shape(num_examples_2, num_features_2) = dataset_2.shape
​if num_examples_1 != num_examples_2:raise ValueError("can not generate polynomials for two sets with different number")if num_features_1 == 0 and num_features_2 == 0:raise ValueError("can not generate polynomials for two sets with no colums")if num_features_1 == 0:dataset_1 = dataset_2elif num_features_2 == 0:dataset_2 = dataset_1
​num_features = num_features_1 if num_features_1 < num_examples_2 else num_features_2dataset_1 = dataset_1[:, :num_features]dataset_2 = dataset_2[:, :num_features]
​polynomials = np.empty((num_examples_1, 0))for i in range(1, polynomials_degree + 1):for j in range(i + 1):polynomial_feature = (dataset_1 ** (i - j)) * (dataset_2 ** j)polynomials = np.concatenate((polynomials, polynomial_feature), axis=1)
​if normalize_data:polynomials = normalize.normalize(polynomials)[0]
​return polynomials
python">import numpy as npdef generate_sinusoids(dataset, sinusoid_degree):"""变换方式 sin(x):param dataset: 原始数据:param sinusoid_degree:变换维度:return: 变换后的参数"""num_examples = dataset.shape[0]sinusoids = np.empty((num_examples, 0))for degree in range(1, sinusoid_degree + 1):sinusoid_fatures = np.sin(degree * dataset)sinusoids = np.concatenate((sinusoids, sinusoid_fatures), axis=1)return sinusoids

 

python">import numpy as np
import normalize
import generate_polynomials
import generate_sinusoids
​
def prepare_for_train(data, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):"""对数据进行预处理:param data: 原始数据:param polynomial_degree: 多项式维度:param sinusoid_degree: 正弦维度:param normalize_data: 是否进行归一化:return: 处理后的数据,特征均值,特征方差"""# 获取样本总数num_examples = data.shape[0]data_processed = np.copy(data)
​# 预处理features_mean = 0features_deviation = 0data_normalized = data_processedif normalize_data:data_normalized, features_mean, features_deviation = normalize.normalize(data_processed)data_processed = data_normalized
​# 特征变量正弦变换if sinusoid_degree > 0:sinusoids = generate_sinusoids.generate_sinusoids(data_normalized, sinusoid_degree)data_processed = np.concatenate((data_processed, sinusoids), axis=1)
​# 特征变量多项式变换if polynomial_degree > 0:polynomials = generate_polynomials.generate_polynomials(data_processed, polynomial_degree, normalize_data)data_processed = np.concatenate((data_processed, polynomials), axis=1)
​# 加一列1data_processed = np.hstack((np.ones((num_examples, 1)), data_processed))
​return data_processed, features_mean, features_deviation

python">import numpy as np
​
import prepare_train
​
​
class LinearRegression:def __init__(self, data, labels, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):"""1、对数据进行预处理操作2、得到特征个数3、初始化参数矩阵:param data:原始数据:param labels:数据的标签:param polynomial_degree:多项式维度:param sinusoid_degree:正弦维度:param normalize_data:是否进行归一化"""(data_processed, features_mean, features_deviation) = prepare_train.prepare_for_train(data, polynomial_degree,sinusoid_degree,normalize_data)
​self.data = data_processedself.labels = labelsself.features_mean = features_meanself.features_deviation = features_deviationself.polynomial_degree = polynomial_degreeself.sinusoid_degree = sinusoid_degreeself.normalize_data = normalize_data
​num_features = self.data.shape[1]self.theta = np.zeros((num_features, 1))
​def train(self, alpha, num_epoch=500):"""开始训练:param alpha: 学习速率:param num_epoch: 迭代次数:return: 训练好的参数,损失值记录"""cost_history = self.gradient_descent(alpha, num_epoch)return self.theta, cost_history
​def gradient_descent(self, alpha, num_epoch):"""小批量梯度下降算法:param alpha: 学习速率:param num_epoch: 迭代次数:return: 损失值的记录"""cost_history = []for i in range(num_epoch):self.gradient_step(alpha)cost_history.append(self.cost_function(self.data, self.labels))return cost_history
​def gradient_step(self, alpha):"""梯度下降参数更新方法:param alpha: 学习率:return: 无"""num_examples = self.data.shape[0]prediction = LinearRegression.hypothesis(self.data, self.theta)delta = prediction - self.labelstheta = self.thetatheta = theta - alpha * (1 / num_examples) * (np.dot(delta.T, self.data)).Tself.theta = theta
​def cost_function(self, data, labels):"""计算损失值函数(最小二乘法):param data:当前数据:param labels:当前标签:return:预测损失值"""num_example = data.shape[0]delta = LinearRegression.hypothesis(data, self.theta) - labelscost = (1 / 2) * np.dot(delta.T, delta)return cost[0][0]
​@staticmethoddef hypothesis(data, theta):"""求预测值:param data: 输入数据:param theta: 当前参数:return: 预测值"""prediction = np.dot(data, theta)return prediction
​def get_cost(self, data, labels):"""获取损失值:param data: 传入的数据:param labels: 数据的标签:return: 当前模型预测数据的损失值"""(data_processed, _, _) = prepare_train.prepare_for_train(data, self.polynomial_degree, self.sinusoid_degree,self.normalize_data)return self.cost_function(data_processed, labels)
​def predict(self, data):"""预测函数:param data: 输入数据:return: 预测的值"""(data_processed, _, _) = prepare_train.prepare_for_train(data, self.polynomial_degree, self.sinusoid_degree,self.normalize_data)predictions = LinearRegression.hypothesis(data_processed, self.theta)return predictions

今天在b站上刷到了唐宇迪博士数据分析与机器视频课程,并进行对应学习,捋了一天公式,概率论的好多公式都忘了,hhhh

 


http://www.ppmy.cn/server/134402.html

相关文章

axios直接上传binary

axios直接上传二进制文件 、 axios直接上传apk、axios直接上传binary postman中的参数选项中有个binary&#xff0c;平常我们很少使用&#xff0c;可能有的同学遇到这种情况不太会了&#xff0c;认为后端应该有个字段名来接收&#xff0c;或者使用 Formdata&#xff0c;但其实…

「Qt Widget中文示例指南」如何实现半透明背景?

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将为大家展示如…

舍伍德业务安全架构(Sherwood Applied Business Security Architecture, SABSA)

舍伍德业务安全架构&#xff08;Sherwood Applied Business Security Architecture, SABSA&#xff09;是一个企业级的安全架构框架&#xff0c;它提供了一个全面的方法来设计和实现信息安全策略。SABSA模型将业务需求与安全控制相结合&#xff0c;确保企业的信息安全措施能够支…

【毕业设计】工具大礼包之『Maven3.6.3安装与配置』

系统版本 电脑系统&#xff1a;Windows 10 一.Maven下载 &#x1f3af; 统一版本 apache-maven-3.6.3&#xff0c;下面两种下载方式2选1即可 1.官网直下 官网下载地址 https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/ 找到apache-maven-3.6.3-bin.zip 云盘…

《YOLO 目标检测》—— YOLO v3 详细介绍

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;还未写完&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xf…

Maven进阶——坐标、依赖、仓库

目录 1.pomxml文件 2. 坐标 2.1 坐标的概念 2.2 坐标的意义 2.3 坐标的含义 2.4 自己项目的坐标 2.5 第三方项目坐标 3. 依赖 3.1 依赖的意义 3.2 依赖的使用 3.3 第三方依赖的查找方法 3.4 依赖范围 3.5 依赖传递和可选依赖 3.5.1 依赖传递 3.5.2 依赖范围对传…

Arduino-ESP32机器人控制器设计练习题汇总

机器人 对抗案例 迷宫案例 练习题 数码管计时器 74HC595等 单选题 ESP32与74HC595之间主要通过哪种通信方式连接&#xff1f; A. I2CB. SPIC. UARTD. 串行移位寄存器&#xff08;答案&#xff09;在Arduino环境中&#xff0c;控制74HC595移位寄存器的库是&#xff1f; A. Wi…

Java:抽象类和接口

一.抽象类 1.抽象类概念和语法 ⨀概念&#xff1a; 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类。 ⨀语…