回归算法细说

  • 回归算法概念
    • 1.什么是回归算法
    • 2.线性回归
    • 3.公式推导
    • 常见回归算法目标函数
    • 回归算法案例
  • 附加扩展内容
    • 过拟合:简单来说 就是训练的模型时过分的依赖训练数据
    • 欠拟合:训练的模型不足以表达数据的关系
      • 模型效果判断
    • 梯度下降算法

回归算法概念

1.什么是回归算法

回归算法是一种有监督算法
回归算法是一种比较常用的机器学习算法,用来建立“解释”变量(自变量X)和观测值(因变量Y)之间的关系;从机器学习的角度来讲,用于构建一个算法模型(函数)来做属性(X)与标签(Y)之间的映射关系,在算法的学习过程中,试图寻找一个函数 使得参数之间的关系拟合性最好。
回归算法中算法(函数)的最终结果是一个连续的数据值,输入值(属性值)是一个d维度的属性/数值向量
举个例子
对于房屋租赁价格画出如下图:

横坐标为房屋租赁面积10,纵坐标是租赁价格1000,通过模型学习,会找到一个函数,使得参数之间的拟合性最好,在这个例子中我们找到的函数时y=ax+b,通过计算可得y=0.4.71x+0.4679。这时,我们相当训练好了一个模型,如果此时要预测面积为110即x=110时的y值,就直接可以带入上式计算得到结果。这是最简单的训练流程,实际中我们要求的不止这么简单。

2.线性回归

线性回归公式如下:

如果对应到刚才的房屋租赁,图像如下:

线性回归的目的在于:计算出 θ 的值,并选择最优的 值构成算法公式

:上面的计算方法是矩阵一行承一列(自行复习一下矩阵乘法)

3.公式推导

前面近似的把线性回归函数比作y=ax+b,后续我们将y=ax+b换成如下公式:

我们既然有了线性回归的函数,那么如何才能是的该函数的结果可以最为接近真实值呢,在这之前,先说一下最小二乘法
我们线性回归模型最优的时候是所有样本的预测值和实际值之间的差值最小化,由于预测值和实际值之间的差值存在正负性,所以要求平方后的值最小化。也就是可以得到如下的一个目标函数:
我们对模型优化,最终都是要求得上式函数结果的最小值
h(x)式模型预测出来的结果,y是原始的真实值,意思就是:假如有三天数据,我们全部送入模型训练,将训练好的模型拿来预测第三天的数据,然后用预测数据减去第三天真实数据,求平方后累加,最后除以2(可不除),如果上式求得的结果最小,那么代表我们的数据越接近真实值
用一句话去解释线性回归算法:首先求得一个线性回归的函数(这个函数中的参数未知),预测值与真实值存在一定的误差,如果我们求得参数带入线性回归函数使得预测值与真实值的误差最小,那么就代表所求参数最优

具体求解过程如下

常见回归算法目标函数

回归算法案例

测试数据集链接: [link](Individual household electric power consumption Data Set)
建议:使用python的sklearn库的linear_model中LinearRegression来获取算法

# 引入所需要的全部包
from sklearn.model_selection import train_test_split # 数据划分的类
from sklearn.linear_model import LinearRegression # 线性回归的类
from sklearn.preprocessing import StandardScaler # 数据标准化import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
from pandas import DataFrame
import time## 设置字符集,防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False# 加载数据
# 日期、时间、有功功率、无功功率、电压、电流、厨房用电功率、洗衣机用电功率、热水器用电功率
path1='./datas/household_power_consumption_1000.txt'
df = pd.read_csv(path1, sep=';', low_memory=False)#没有混合类型的时候可以通过low_memory=F调用更多内存,加快效率)
df.head() ## 获取前五行数据查看查看

数据如下

# 异常数据处理(异常数据过滤)
new_df = df.replace('?', np.nan)#替换非法字符为np.nan
datas = new_df.dropna(axis=0, how = 'any') # 只要有一个数据为空,就进行行删除操作
datas.describe().T#观察数据的多种统计指标(只能看数值型的)
## 创建一个时间函数格式化字符串
def date_format(dt):# dt显示是一个series/tuple;dt[0]是date,dt[1]是timeimport timet = time.strptime(' '.join(dt), '%d/%m/%Y %H:%M:%S')return (t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)
## 需求:构建时间和功率之间的映射关系,可以认为:特征属性为时间;目标属性为功率值。
# 获取x和y变量, 并将时间转换为数值型连续变量
X = datas.iloc[:,0:2]
# apply对DataFrame中的数据采用给定的函数进行处理,具体是行数据还是列数据,看参数axis;
# 如果axis为1,那么表示按行进行数据处理; 如果axis为0,表示按照列进行数据处理
X = X.apply(lambda x: pd.Series(date_format(x)), axis=1)
Y = datas['Global_active_power']
## 对数据集进行测试集合训练集划分
# X:特征矩阵(类型一般是DataFrame)
# Y:特征对应的Label标签(类型一般是Series)
# test_size: 对X/Y进行划分的时候,测试集合的数据占比, 是一个(0,1)之间的float类型的值
# random_state: 数据分割是基于随机器进行分割的,该参数给定随机数种子;给一个值(int类型)的作用就是保证每次分割所产生的数数据集是完全相同的
X_train,X_test,Y_train,Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
## 数据标准化
# StandardScaler:将数据转换为标准差为1的数据集(有一个数据的映射)
# scikit-learn中:如果一个API名字有fit,那么就有模型训练的含义,默认是没法返回值
# scikit-learn中:如果一个API名字中有transform, 那么就表示对数据具有转换的含义操作
# scikit-learn中:如果一个API名字中有predict,那么就表示进行数据预测,会有一个预测结果输出
# scikit-learn中:如果一个API名字中既有fit又有transform的情况下,那就是两者的结合(先做fit,再做transform)
ss = StandardScaler() # 模型对象创建
# ss.fit(X_train) # 模型训练
# X_train = xx.transform(X_train) # 对训练集合数据进行转换
X_train = ss.fit_transform(X_train) # 训练模型并转换训练集
X_test = ss.transform(X_test) ## 直接使用在模型构建数据上进行一个数据标准化操作 (测试集)
## 模型训练
lr = LinearRegression(fit_intercept=True) # 模型对象构建
lr.fit(X_train, Y_train) ## 训练模型
## 模型校验
y_predict = lr.predict(X_test) ## 预测结果print("训练集上R2:",lr.score(X_train, Y_train))
print("测试集上R2:",lr.score(X_test, Y_test))
mse = np.average((y_predict-Y_test)**2)
rmse = np.sqrt(mse)
print("rmse:",rmse)
# 输出模型训练得到的相关参数
print("模型的系数(θ):", end="")
print(lr.coef_)
print("模型的截距:", end='')
print(lr.intercept_)
## 模型保存/持久化
# 在机器学习部署的时候,实际上其中一种方式就是将模型进行输出;另外一种方式就是直接将预测结果输出
# 模型输出一般是将模型输出到磁盘文件
from sklearn.externals import joblib# 保存模型要求给定的文件所在的文件夹比较存在
joblib.dump(ss, "result/data_ss.model") ## 将标准化模型保存
joblib.dump(lr, "result/data_lr.model") ## 将模型保存
# 加载模型
ss3 = joblib.load("result/data_ss.model") ## 加载模型
lr3 = joblib.load("result/data_lr.model") ## 加载模型# 使用加载的模型进行预测
data1 = [[2006, 12, 17, 12, 25, 0]]
data1 = ss3.transform(data1)
print(data1)
lr3.predict(data1)

附加扩展内容

:一般算法中都会存在两种问题,即过拟合和欠拟合问题

过拟合:简单来说 就是训练的模型时过分的依赖训练数据

欠拟合:训练的模型不足以表达数据的关系

1.线性回归目标函数:为了防止数据过拟合,也就是的θ值在样本空间中不能过大,可以在目标函数之上增加一个平方和损失:

正则项(norm)/惩罚项:

这里这个正则项叫做L2-norm
过拟合正则项:

使用L2正则的线性回归模型就称为Ridge回归(岭回归)


使用L1正则的线性回归模型就称为LASSO回归(Least Absolute Shrinkage and Selection Operator)

L2-norm中,由于对于各个维度的参数缩放是在一个圆内缩放的,不可能导致有维度参数变为0的情况,那么也就不会产生稀疏解;实际应用中,数据的维度中是存在噪音和冗余的,稀疏的解可以找到有用的维度并且减少冗余,提高后续算法预测的准确性和鲁棒性(减少了overfitting)(L1-norm可以达到最终解的稀疏性的要求)
Ridge模型具有较高的准确性、鲁棒性以及稳定性(冗余特征已经被删除了);LASSO模型具有较高的求解速度。
如果既要考虑稳定性也考虑求解的速度,就使用Elasitc Net
同时使用L1正则和L2正则的线性回归模型就称为Elasitc Net算法(弹性网络算法)

模型效果判断

MSE:误差平方和,越趋近于0表示模型越拟合训练数据。
RMSE:MSE的平方根,作用同MSE
R2:取值范围(负无穷,1],值越大表示模型越拟合训练数据;最优解是1;当模型预测为随机值的时候,有可能为负;若预测值恒为样本期望,R2为0
TSS:总平方和TSS(Total Sum of Squares),表示样本之间的差异情况,是伪方差的m倍
RSS:残差平方和RSS(Residual Sum of Squares),表示预测值和样本值之间的差异情况,是MSE的m倍

在实际工作中,对于各种算法模型(线性回归)来讲,我们需要获取θ、λ、p的值;θ的求解其实就是算法模型的求解,一般不需要开发人员参与(算法已经实现),主要需要求解的是λ和p的值,这个过程就叫做调参(超参)
交叉验证:将训练数据分为多份,其中一份进行数据验证并获取最优的超参:λ和p;比如:十折交叉验证、五折交叉验证(scikit-learn中默认)等

梯度下降算法

1.批量梯度下降算法
2.随机梯度下降算法
3.小批量梯度下降法
SGD速度比BGD快(整个数据集从头到尾执行的迭代次数少)
SGD在某些情况下(全局存在多个相对最优解/J(θ)不是一个二次),SGD有可能跳出某些小的局部最优解,所以一般情况下不会比BGD坏;SGD在收敛的位置会存在J(θ)函数波动的情况。
BGD一定能够得到一个局部最优解(在线性回归模型中一定是得到一个全局最优解),SGD由于随机性的存在可能导致最终结果比BGD的差
注意:优先选择SGD
三种比较
BGD、SGD、MBGD的区别:
当样本量为m的时候,每次迭代BGD算法中对于参数值更新一次,SGD算法中对于参数值更新m次,MBGD算法中对于参数值更新m/n次,相对来讲SGD算法的更新速度最快;
SGD算法中对于每个样本都需要更新参数值,当样本值不太正常的时候,就有可能会导致本次的参数更新会产生相反的影响,也就是说SGD算法的结果并不是完全收敛的,而是在收敛结果处波动的;
SGD算法是每个样本都更新一次参数值,所以SGD算法特别适合样本数据量大的情况以及在线机器学习(Online ML)。

回归算法以及源码分享相关推荐

  1. app和web逆向算法还原案例源码分享

    1.前言 后续公众号将不再设置任何收费,只做算法还原源码分享并分享在github项目上 项目地址是:https://github.com/YotaGit/AlgorithmRestore 现已将之前公 ...

  2. 多目标人工秃鹫优化算法(MATLAB源码分享,智能优化算法) 提出了一种多目标版本的人工秃鹫优化算法(AVOA)

    多目标人工秃鹫优化算法(MATLAB源码分享,智能优化算法) 提出了一种多目标版本的人工秃鹫优化算法(AVOA),用于多目标优化问题. AVOA的灵感来源于非洲秃鹫的生活方式. 档案.网格和领导者选择 ...

  3. 2020年泰迪杯C题智慧政务中的文本数据挖掘应用--论文+全部源码分享

    5.2问题二模型的建立与求解 本题要求针对热点问题进行挖掘,主要目的是从群众留言中挖掘出热点问题.也就是给每一条留言都量化一个热度指数.并且根据热度指数进行排序,从而获取热度较高的评价问题.对于问题热 ...

  4. Python基于OpenCV的图像去雾算法[完整源码&部署教程]

    1.图片识别 2.视频展示 [项目分享]Python基于OpenCV的图像去雾算法[完整源码&部署教程]_哔哩哔哩_bilibili 3.算法原理 图像增强算法常见于对图像的亮度.对比度.饱和 ...

  5. c语言球球半径,C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗?...

    原标题:C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗? 游戏背景 <球球大作战>是Superpop一款自主研du发的免费手机网络游戏. 以玩家间的实时互动PK产生游戏乐 ...

  6. 俄罗斯方块源码分享 html+css+js

    效果: [html+css+js]俄罗斯方块源码分享 这是在网上跟着黑马的视频做的,然后也加了些自己的想法. 在线试玩:http://www.beijiguang.site/game/index.ht ...

  7. “图片差异检查”辅助工具(即“大家来找茬”辅助工具)源码分享

    忽然心血来潮,想写一个辅助工具,让朋友们在"大家来找茬"之类的游戏中可以少费一些眼睛. 在Java方面我是新手,在折腾了一段时间后,终于还是写出了一个基本可用的测试版程序.详细的使 ...

  8. 最新猜骰子玩法源码分享+微信猜骰子源码下载

    模拟算法是用随机函数来模拟自然界中发生的不可预测的情况,C语言中是用srand()和rand()函数来生成随机数. 先来介绍一下随机数的生成: 1.产生不定范围的随机数 函数原型:int rand() ...

  9. PID温控实验平台搭建(二)——PID进阶知识介绍及源码分享

    PID温控实验平台搭建 (一)PID基础知识介绍 (二)PID进阶知识介绍及源码分享 (三)从零开始搭建STM32温控实验平台 (四)PID温控系统代码讲解 (五)最终实验现象与总结 文章目录 前言 ...

最新文章

  1. android 实现表格横向混动_Flutter混合开发和Android动态更新实践
  2. Advanced Auto Layout:Programmatically Creating Constraints
  3. 使用Oracle数据泵迁移数据库
  4. 数据结构 二叉树的遍历
  5. cefsharp已停止工作_windows资源管理器已停止工作怎么解决
  6. ArcGIS实验教程——实验十五:拓扑关系创建与编辑
  7. 诗与远方:无题(九十二)
  8. 国际C语言混乱代码大赛
  9. Modelbuilder进阶教程
  10. JSON数组转LIST集合的两种方法
  11. Xposed安装与使用
  12. win7 局域网访问网站
  13. C++异常机制的实现方式和开销分析
  14. 2022电大国家开放大学网上形考任务-大学语文非免费(非答案)
  15. 利用 SysRq 键排除和诊断系统故障
  16. lenb和len的区别
  17. 成都敏之澳电商:拼多多商家怎么看店铺是否降权导?
  18. Javascript+webdriverio App自动化demo
  19. Unity隐身 观察隐身
  20. URIError: URI malformed

热门文章

  1. V8、JSCore、Hermes、QuickJS,hybrid开发JS引擎怎么选
  2. 世界杯小组赛积分的所有可能
  3. 【Raft】分布式一致性算法Raft和zab、paxos
  4. java常用加密算法及MD5的使用
  5. phpcms-前台模板调用和后台模板调用
  6. 【Excel】忘记VBA密码怎么办(Hex编辑器)
  7. 2018汽车之家汽车品牌、车型数据库采集带品牌logo以及车型图
  8. 数据挖掘:概念与技术 第一章
  9. 计算机网络:网络层的功能概述
  10. FPGA读取MPU6050六轴陀螺仪