多特征线性回归模型

一、预测目标和原始数据展示

(一)预测目标:

通过Economy..GDP.per.Capita.(GDP)和Freedom预测Happiness.Score

(二)部分数据展示:

特征有很多,本文研究Economy..GDP.per.Capita.(GDP)和Freedom,也就是用Economy..GDP.per.Capita.(GDP)和Freedom预测Happiness.Score。

原始数据链接: 

链接:https://pan.baidu.com/s/1yUsHkwGyZafYCvdZu0YHNg?pwd=z6bp 
提取码:z6bp

二、数学原理及其应用

(一)所用参数介绍:

Y:我们需要预测的真实值,也就是Happiness.Score(自由指数)

X1:Economy..GDP.per.Capita.(GDP)

X2:Freedom(我理解为一个国家的自由度,调查得到)

θ1:X1的系数

θ2:X2的系数

ε:误差 

α:学习率

θ0:偏置项

(二)θ代表什么?

  若Y=X1+X2,那么代表着X1、X2对结果Y的影响是相同的,X1取一个数,X2取一个数,那么加起来就是Y。显而易见,GDP+Freedom != Happiness.Score,那么就需要两个数作为X1、X2的系数,来找到θ1和θ2,使得GDP和Freedom对Happiness.Score的影响达到一个最合适的比重,我们的核心目标,就是求得θ1和θ2。

(三)预测公式:

 注意这里θX是代表θ1X1+θ2X2,称为预测值。ε是误差。上述公式分开写应该如下:

 我们希望的是误差越小越好,因为误差越小,我们的预测值就越接近于真实值。

(四)偏置项

在线性回归中,偏置项也被称为截距(intercept),是指模型中的一个常数项,用于调整模型的拟合程度。偏置项通常表示自变量为0时的响应变量值,即直线在y轴上的截距。

偏置项的存在可以使得模型更加灵活,能够更好地拟合数据。如果模型中不包含偏置项,则拟合的直线必须经过原点。

简单理解,就是截距。

(五)前提引入:

1.误差独立并且具有相同的分布,服从均值为0,方差为σ^2的高斯分布。

这个问题我也理解不彻底,只是先作为一个前提条件提出。

2.我们这里所说的X、Y、θ都不单单指一个数,而是一个矩阵,由于运算需要,以上公式需要改动一下,对θ矩阵求转置。

 

(六)使误差最小:

高斯分布公式:

应用到本文中: 

 

我们的目标是希望的是误差越小越好,因为误差越小,我们的预测值就越接近于真实值。

要使误差越小,就要使似然函数越大,在似然函数之前,需先了解最大似然估计:

  假如一个箱子里有很多很多红球和黑球,数量足够庞大,就假设有70亿个,我任意抽五个球,设抽到黑球的概率为θ,那么抽到红球的概率为1-θ

可以得到似然函数:

 现在抽到的这三黑两红,就是一组观测数据,我要用这组数据,去估计箱子里红球和黑球各有多少,那么我就要使这组数据出现的概率最大,简单来说,如果某个参数值能够使得观测数据出现的概率更大,那么这个参数更有可能是其实际的参数。因为我就抽了这五个,那我应该希望这组观测数据出现的概率更大,才能估计箱子里红球和黑球各有多少。

  而似然函数就可以衡量参数与观测数据的匹配程度,所以说要使似然函数越大越好。

  这里就是数学问题了,我现在想要在似然函数最大的情况下求得θ,那就对θ求导并使其函数只等于0,因为导数反应的是函数的变化率,或者说是切线斜率,当函数到达最高点时,函数的变化率或者说是切线斜率就等于0,想想一个开口向下的抛物线函数。在独立同分布的条件下,联合概率密度等于边缘概率密度的乘积。 

回到线性回归中。

 现在,得到了一个常数和一个函数,我们称他为损失函数,要使似然函数最大,那么问题进一步转化为了让损失函数最小。我们把损失函数定义出来,如下:

 

 想要解决时损失函数最小的问题,需要用到梯度下降算法,但在这之前,其原理需要用到高数中的方向导数与梯度。

(七)方向导数与梯度

  高数书中这么引入方向导数:偏导数反映的是函数沿坐标轴方向的变化率,但许多物理现象告诉我们,只考虑沿坐标轴方向的变化率是不够的,例如:热空气要向冷的地方流动,气象学中就要确定大气温度,气压沿着某些方向的变化率,因此,我们有必要来讨论函数沿任一指定方向的变化率问题。

  梯度下降算法得到loss函数的最小值,而下降不能胡乱下降,需要找到一个方向,也就是函数沿任一指定方向的变化率,以下来证明沿哪个方向下降:

   这是一个常见的高数题,请先记住题中的梯度向量:

  梯度量永远指向方向导数变化最大的向,换句话说,梯度向量的方向是函数上升最快的方向。

那么现在,进入梯度下降算法。

(八)梯度下降 

  梯度下降算法的基本思路是通过不断迭代来更新模型参数,直到达到最小化目标函数的效果。具体地,给定一个初始点,我们计算当前点的负梯度(即梯度的相反数),并沿着负梯度的方向更新参数。重复这个过程,直到收敛到一个局部极小值或全局极小值。 在梯度下降算法中,学习率是一个非常关键的参数。它决定了每一次迭代中,更新参数的幅度大小。这个学习率,可以理解为步长。

  本文研究两个特征值,Economy..GDP.per.Capita.(GDP)和Freedom,对应的损失函数定义和更新参数θ如下:

 梯度量永远指向方向导数变化最大的向,换句话说,梯度向量的方向是函数上升最快的方向。所以说虽然求导后得负,但要取反。上述更新参数的算法为批量梯度下降。

以上就为我理解的原理,下面进入代码模块

三、代码模块

(一)数据预处理

#Preprocess_data.py
import numpy as np
import pandas as pddef Preprocess_data(train_X1):Mean_value = np.mean(train_X1,0) #求得均值Standard_deviation = np.std(train_X1,0) #求得标准差train_X1 = (train_X1 - Mean_value)/Standard_deviationsample_number = train_X1.shape[0]train_X1 = np.hstack((np.ones((sample_number, 1)), train_X1))return train_X1

为什么要对数据进行预处理?

  如果两种数据相差太大,那么会对预测结果造成非常大的误差,假如说要用年龄和身高作为预测数据的话,例如:年龄:[20,21,10,18,27,33,60......],身高:[180,170,175,169,166,185,187......],两位数和三位数的相差太大了,那么求得的他们的系数θ也会相差很大,造成的是身高对预测结果的影响远远大于年龄对预测结果的影响,这样的误差对模型十分致命,所以,我们要对数据进行预处理。

归一化预处理:

  通过将每个特征的值减去均值,并除以标准差,实现了对特征值的归一化。这样做可以使得各个特征的取值范围相对统一,避免某些特征因为数值范围过大而在优化过程中权重变化较小或者被主导的问题。参考概率论中的随机变量标准化正态分布。

train_X1 = np.hstack((np.ones((sample_number, 1)), train_X1))

  在二(四)中我们提到偏置项,为数据添加一列1,就是为了得到偏置项,也就是截距。

(二)梯度下降算法实现

#Linear_Regression.py
import numpy as np
from Preprocess_data import Preprocess_dataclass LinearRegression:def __init__(self,train_X1,train_Y):train_X1 = Preprocess_data(train_X1)self.train_X1 = train_X1self.train_Y = train_Yself.theta = np.zeros(((self.train_X1.shape[1]),1))def train(self,alpha,train_times):record_loss = self.gradient_descent(alpha,train_times)return self.theta,record_lossdef gradient_descent(self,alpha,train_times):record_loss = []for _ in range(train_times):self.gradient_step(alpha)record_loss.append(self.compute_loss(self.train_X1,self.train_Y))return record_lossdef gradient_step(self,alpha):prediction = LinearRegression.hypothesis(self.train_X1,self.theta)delta = prediction - self.train_Ytheta = self.thetaSample_number = self.train_X1.shape[0]theta = theta - alpha*(1/Sample_number)*(np.dot(delta.T,self.train_X1)).Tself.theta = theta@staticmethoddef hypothesis(train_X1,theta):prediction = np.dot(train_X1,theta)return predictiondef compute_loss(self,train_X1,train_Y):sample_number = train_X1.shape[0]delta = LinearRegression.hypothesis(self.train_X1,self.theta)- train_Yloss = (1/2)*np.dot(delta.T,delta)/sample_number #使用均方误差来衡量线性回归模型的拟合程度return loss[0][0]def predict(self,X1_predictions):X1_predictions = Preprocess_data(X1_predictions)final_prediction = LinearRegression.hypothesis(X1_predictions,self.theta)return final_prediction

self.theta = np.zeros(((self.train_X1.shape[1]),1))

  数据预处理中我们为了得到偏置项为数据添加了一列1,由于矩阵相乘的特点同时也是为了得到偏置项,我们按照数据的列数,创建theta的行数。

theta = theta - alpha*(1/Sample_number)*(np.dot(delta.T,self.train_X1)).T
  这一步就是二(八)中批量梯度下降数学表达式的实现。

@staticmethod

  通过将方法定义为静态方法,可以直接通过类名调用该方法,而不需要先创建类的实例。这在某些情况下可以简化代码的编写和调用方式。 

(三)数据传入和模型

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
from Linear_Regression import LinearRegressiondata = pd.read_csv('D:\\Programming\\MicrosoftVSCodeData\\MachineLearning\\data\\world-happiness-report-2017.csv')train_data = data.sample(frac=0.8)
test_data = data.drop(train_data.index)X1_title = "Economy..GDP.per.Capita."
X2_title = "Freedom"
Y_title = "Happiness.Score"X_train = train_data[[X1_title, X2_title]].values
Y_train  = train_data[[Y_title]].valuestest_X = test_data[[X1_title, X2_title]].values
test_Y = test_data[[Y_title]].valuesX = data[[X1_title, X2_title]]
y = data[Y_title]train_times = 500  
alpha = 0.01  mesh_size = .02
margin = 0# Condition the model on sepal width and length, predict the petal width
model = LinearRegression(X_train,Y_train)
(theta, loss_history) = model.train(alpha,train_times)print('开始损失',loss_history[0])
print('结束损失',loss_history[-1])
plt.plot(range(train_times), loss_history)
plt.title('loss_function')
plt.show()# Create a mesh grid on which we will run our model
x_min, x_max = X[X1_title].min() - margin, X[X1_title].max() + margin
y_min, y_max = X[X2_title].min() - margin, X[X2_title].max() + margin
xrange = np.arange(x_min, x_max, mesh_size)
yrange = np.arange(y_min, y_max, mesh_size)
xx, yy = np.meshgrid(xrange, yrange)# Condition the model on sepal width and length, predict the petal width
pred = model.predict(np.c_[xx.ravel(), yy.ravel()])
pred = pred.reshape(xx.shape)# Generate the plot
fig = px.scatter_3d(train_data, x=X1_title, y=X2_title, z=Y_title)
fig.update_traces(marker=dict(size=10))
fig.add_trace(go.Surface(x=xrange, y=yrange, z=pred, name='Predict_Happiness'))fig.add_trace(go.Scatter3d(x=test_data[X1_title],y=test_data[X2_title],z=test_data[Y_title],mode='markers',marker=dict(size=10,color='red'),name='test_data'
))fig.show()

真没找到合适的多特征线性回归模型,不得已出此下策用非线性的模型改成线性,原模型如下: 

 模型来源:Ml regression in Python (plotly.com)

将模型代码copy,数据改成自己的数据即可。如果网站加载缓慢的,用UU加速器,搜索学术资源进行加速(没有打广告)。

模型改动:添加了以下代码把测试数据加入图中进行对比和画出损失函数图像。

fig.add_trace(go.Scatter3d(x=test_data[X1_title],y=test_data[X2_title],z=test_data[Y_title],mode='markers',marker=dict(size=10,color='red'),name='test_data'
))print('——————————————————————————')print('开始损失',loss_history[0])
print('结束损失',loss_history[-1])
plt.plot(range(train_times), loss_history)
plt.title('loss_function')
plt.show()

四、程序调试和模型展示

经数据代入方程计算得出误差大约在0.4左右,如果把剩余的6个特征也加入方程,误差可更小。

 

五、参考课程和鸣谢

【多元微分专题】第六期:方向导数和梯度的直观理解_哔哩哔哩_bilibili

9-多特征回归模型_哔哩哔哩_bilibili

 高斯分布 - 知乎 (zhihu.com)

【梯度下降】3D可视化讲解通俗易懂_哔哩哔哩_bilibili

每天一个数学小知识——导数的定义_哔哩哔哩_bilibili

有些参考文章可能未列出,感谢各位老师的教导!

本人学术不精,如有错误望指正,感谢! 

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

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

相关文章

[计算机提升] Windows系统软件:娱乐类

3.3 系统软件:娱乐类 3.3.1 Windows Media Player:dvdplay Windows Media Player是Windows操作系统自带的多媒体播放软件,用于播放和管理电脑中的音频和视频文件。它提供了以下功能: 播放音频和视频文件:Windows Med…

OpenGL_Learn04

我这边并不是教程&#xff0c;只是学习记录&#xff0c;方便后面回顾&#xff0c;代码均是100%可以运行成功的。 1. 渐变三角形 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include <cmath>void framebuffer_size_callba…

修改element组件库的el-input-number的图标

官方样式&#xff1a; 我希望组件的图标改成一对上下是三角形的图标&#xff1a; 直接复制以下代码&#xff1a; ::v-deep .el-icon-arrow-down:before {content: "\e790"; } ::v-deep .el-icon-arrow-up:before {content: "\e78f"; } 完成&#xff01…

2021-arxiv-GPT Understands, Too

2021-arxiv-GPT Understands, Too Paper&#xff1a; https://arxiv.org/abs/2103.10385 Code&#xff1a; https://github.com/THUDM/P-tuning Prompt 简单理解 举例来讲&#xff0c;今天如果有这样两句评论&#xff1a; 1. 什么苹果啊&#xff0c;都没有苹果味&#xff0c…

ViT Vision Transformer超详细解析,网络构建,可视化,数据预处理,全流程实例教程

关于ViT的分析和教程&#xff0c;网上又虚又空的东西比较多&#xff0c;本文通过一个实例&#xff0c;将ViT全解析。 包括三部分内容&#xff0c;网络构建&#xff1b;orchview.draw_graph 将网络每一层的结构与输入输出可视化&#xff1b;数据预处理。附完整代码 网络构建 …

偶数矩阵判断【C语言作业】

题目 若一个布尔矩阵所有行和所有列的和都是偶数&#xff0c;则称为偶数矩阵。请编写一个程序&#xff0c;判断一个布尔矩阵是否是偶数矩阵。 要求&#xff1a; &#xff08;1&#xff09;输入:首先输入一个正整数n(n<100),代表该矩阵的大小&#xff0c;接下来是n行n列的矩…

第5天:基础入门-资产架构amp;端口amp;应用amp;CDNamp;WAFamp;站库分离amp;负载均衡

第5天&#xff1a;基础入门-资产架构&端口&应用&CDN&WAF&站库分离&负载均衡 #知识点&#xff1a;1. 资产架构-端口&目录&插件接口&多站点&多应用 2. 番外安全-域名&服务器本身&服务厂商&管理人员 3. 考虑阻碍-站库分离&am…

c++-AVL树

文章目录 前言一、AVL树1、AVL树概念2、AVL树模拟实现3、AVL树的旋转操作3.1 左单旋3.2 左单旋代码实现3.3 右单旋3.4 右单旋代码实现。3.5 什么时候调用左单旋和右单旋3.6 左右双旋3.7 左右双旋代码实现3.8 右左双旋3.9 右左双旋代码实现3.10 什么时候调用左右双旋和右左双旋 …

Kafka - 监控工具 Kafka Eagle:实时洞察Kafka集群的利器

文章目录 引言Kafka Eagle简介Kafka Eagle的特点Kafka Eagle的优势使用Kafka Eagle的步骤结论 引言 在现代大数据架构中&#xff0c;Apache Kafka已成为一个不可或缺的组件&#xff0c;用于可靠地处理和传输大规模的数据流。然而&#xff0c;随着Kafka集群规模的不断增长&…

编写shell脚本,利用mysqldump实现MySQL数据库分库分表备份

查看数据和数据表 mysql -uroot -p123456 -e show databases mysql -uroot -p123456 -e show tables from cb_d 删除头部Database和数据库自带的表 mysql -uroot -p123456 -e show databases -N | egrep -v "information_schema|mysql|performance_schema|sys"编写…

Linux之sched_setscheduler调度策略总结(六十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

设计模式第一课-单例模式(懒汉模式和饿汉模式)

单例模式 个人理解&#xff1a;单例模式实际就是通过类加载的方式获取到一个对象&#xff0c;并且保证这个对象在使用中只有一个&#xff0c;不允许再次被创建 一、懒汉模式 1、懒汉模式的基础写法 代码解释&#xff1a; &#xff08;1&#xff09;、编写LazySingleton类的…

Shiny Server和ShinyProxy是什么,有什么区别?

调研以及参与过多个生物公司的生信工具研发&#xff0c;不管是ShinyServer还是ShinyProxy都有一定研究&#xff0c;尤其是ShinyServer。如果仅是本地化测试想快速的搭建Shiny应用&#xff0c;我推荐用Shiny Server&#xff0c;如果多并发用户且更好的线上管理Shiny应用&#xf…

React Native 样式及其布局

React Native 样式及其布局 参考 https://reactnative.cn/docs/flexbox 一、样式 在 React Native 中&#xff0c;你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 …

安全与HTTP协议:为何明文传输数据成为争议焦点?

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、H…

CentOS 搭建 Hadoop3 高可用集群

Hadoop FullyDistributed Mode 完全分布式 spark101spark102spark103192.168.171.101192.168.171.102192.168.171.103namenodenamenodejournalnodejournalnodejournalnodedatanodedatanodedatanodenodemanagernodemanagernodemanagerrecource managerrecource managerjob hist…

2023.10.31 关于 Spring 的基本概念

目录 Spring 容器 对象生命周期 IoC Spring IoC DI Spring Spring 的全称为 Spring Framework&#xff0c;是一个开源的 Java 应用程序框架它提供了一种综合的编程和配置模型&#xff0c;用于构建现代化企业级的应用程序 一句话概括 Spring 是包含了众多工具方法的 IoC …

docker进阶

文章目录 docker 进阶Part1 常用命令总结docker version 查看docker客户端和服务端信息docker info 查看更加详细信息docker images 列出所有镜像基本用法常用选项 docker search 搜索镜像基本用法示例用法 docker pull 拉取镜像基本用法示例用法 docker rmi 删除镜像基本用法示…

FMC子卡解决方案:FMC214-基于FMC兼容1.8V IO的Full Camera Link 输出子卡

FMC214-基于FMC兼容1.8V IO的Full Camera Link 输出子卡 一、板卡概述   基于FMC兼容1.8V IO的Full Camera Link 输出子卡支持Base、Middle、Full Camera link信号输出&#xff0c;兼容1.8V、2.5V、3.3V IO FPGA信号输出。适配xilinx不同型号开发板和公司内部各FMC载板。北…