当前位置: 首页 > news >正文

机器学习之线性规划原理详解、公式推导(手推)、以及简单实例

1. 原理详解

1.1. 线性回归

  假设一个空间中有一堆散点,线性回归的目的就是希望用一条直线,最大程度地“概括”这些散点。它不要求经过每一个散点,但是希望能考虑到每个散点的特点。按照西瓜书的例子就是,好瓜的评判标准y可以由 x i x_i xi表示,也就是说, f g o o d ( x ) = w 1 x 色泽 + w 1 x 根蒂 + w 1 x 敲声 + b f_{good}(x)=w_1x_{色泽}+w_1x_{根蒂}+w_1x_{敲声}+b fgood(x)=w1x色泽+w1x根蒂+w1x敲声+b
  那么我们不难发现,线性回归需要考虑的几个问题:

  • 确定系数 w i w_i wi以及偏置 b b b
  • 如何确定 f g o o d ( x ) f_{good}(x) fgood(x)能很好地概括瓜的特点

1.2. 回归系数

  关于这点,我们需要确定,我们算出来的回归系数一定是当前最优的结果,怎么确定呢?

  • 均方误差(西瓜书)
  • R^2(用于模型评估)

均方误差(MSE)

  这个其实就是残差平方和的平均值。
M S E = ∑ i = 0 n y i − f ( x i ) n MSE=\frac{\sum_{i=0}^ny_i-f(x_i)}{n} MSE=ni=0nyif(xi)

R^2

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

  其中,SST是总偏差平方和
S S T = ∑ i = 0 n ( y i − y ˉ ) 2 SST=\sum_{i=0}^n(y_i-\bar y)^2 SST=i=0n(yiyˉ)2
  SSR是回归平方和
S S R = ∑ i = 0 n ( f ( x i ) − y ˉ ) 2 SSR=\sum_{i=0}^n(f(x_i)-\bar y)^2 SSR=i=0n(f(xi)yˉ)2
  SSE是残差平方和
S S E = ∑ i = 0 n ( y i − f ( x i ) ) 2 SSE=\sum_{i=0}^n(y_i-f(x_i))^2 SSE=i=0n(yif(xi))2

2. 公式推导

2.1. 单元线性回归

这里我们跟西瓜书一样采取均方误差。

在这里插入图片描述

计算得w与b。

2.2. 多元线性回归

多元线性回归涉及到矩阵运算。

在这里插入图片描述

若X为m * n的矩阵,则 X T X X^TX XTX为n * n的方阵。 X T X X^TX XTX的意义在于保持其为可逆矩阵,因为若它不可逆,则导致其行列式为0,就会导致w趋向无穷。

3. 简单实例

3.1. 实例1:一元线性回归

计算这个二元线性回归

indexxy
162
281
3100
4142
5180

我们这里采用几种解法

  1. 西瓜书内的公式
  2. 最小二乘估计w, b
  3. linalg直接解
# -*- coding:utf-8 -*-
# 2022.09.05
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def task1_vis(x, y, w, b):
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.scatter(x, y)
    x = np.linspace(0, 20, 100)
    y = w * x + b
    ax.plot(x, y)
    # plt.title('Pizza price plotted against diameter')
    ax.set_xlabel('x', fontdict={'size': 10, 'color': 'black'})
    ax.set_ylabel('y', fontdict={'size': 10, 'color': 'black'})
    plt.show()


def task1_way1(x, y):
    w = np.dot(y, (x - x.mean())).sum() / (sum(np.square(x)) - np.square(sum(x)) / x.shape[0])
    b = sum(y - np.multiply(w, x)) / x.shape[0]
    print("方法一:\t\tw:{}\tb:{}".format(w, b))


def task1_way2(x, y):
    x_bar = x.mean()
    y_bar = y.mean()
    # 计算协方差
    cov = np.multiply((x - x_bar).transpose(), (y - y_bar)).sum() / (x.shape[0] - 1)
    var = np.var(x, ddof=1)
    w = cov / var
    # w = (y_bar - w * x_bar) / (x.shape[0])
    b = y_bar - w * x_bar
    print("方法二:\t\tw:{}\tb:{}".format(w, b))


def task1_way3(x, y):
    from numpy.linalg import lstsq
    x = np.vstack([x, [1 for i in range(x.shape[0])]])
    w = lstsq(x.T, y.reshape(-1, 1))[0][0][0]
    b = lstsq(x.T, y.reshape(-1, 1))[0][1][0]
    print("方法三:\t\tw:{}\tb:{}".format(w, b))
    return w, b


def task1():
    x = np.array([6, 8, 10, 14, 18])
    y = np.array([7, 9, 13, 17.5, 18])
    task1_way1(x, y)
    task1_way2(x, y)
    w, b = task1_way3(x, y)
    task1_vis(x, y, w, b)


if __name__ == '__main__':
    task1()

运行结果如下
在这里插入图片描述
在这里插入图片描述

实例2: 多元线性回归

# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

def task2():
    from numpy.linalg import inv
    X = np.array([[1, 6, 2], [1, 8, 1], [1, 10, 0], [1, 14, 2], [1, 18, 0]])
    X[:, 2] = X[:, 1] * X[:, 1]
    Y = np.array([[7], [9], [13], [17.5], [18]])
    beita = np.dot(inv(np.dot(np.transpose(X), X)), np.dot(np.transpose(X), Y))
    print(beita)
    from numpy.linalg import lstsq
    print(lstsq(X, Y)[0])

if __name__ == '__main__':
    # task1()
    task2()

3.3. 实例3:房价预测

在这里插入图片描述

# -*- coding:utf-8 -*-
# 2022.09.05
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def task1_vis(x, y, w, b):
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.scatter(x, y)
    y = w * x + b
    ax.plot(x, y, 'r')
    # plt.title('Pizza price plotted against diameter')
    ax.set_xlabel('x', fontdict={'size': 10, 'color': 'black'})
    ax.set_ylabel('y', fontdict={'size': 10, 'color': 'black'})
    plt.show()


def task1_way1(x, y):
    w = np.dot(y, (x - x.mean())).sum() / (sum(np.square(x)) - np.square(sum(x)) / x.shape[0])
    b = sum(y - np.multiply(w, x)) / x.shape[0]
    print("方法一:\t\tw:{}\tb:{}".format(w, b))
    return w, b


def task1_way2(x, y):
    x_bar = x.mean()
    y_bar = y.mean()
    # 计算协方差
    cov = np.multiply((x - x_bar).transpose(), (y - y_bar)).sum() / (x.shape[0] - 1)
    var = np.var(x, ddof=1)
    w = cov / var
    # w = (y_bar - w * x_bar) / (x.shape[0])
    b = y_bar - w * x_bar
    print("方法二:\t\tw:{}\tb:{}".format(w, b))


def task1_way3(x, y):
    from numpy.linalg import lstsq
    x = np.vstack([x, [1 for i in range(x.shape[0])]])
    w = lstsq(x.T, y.reshape(-1, 1))[0][0][0]
    b = lstsq(x.T, y.reshape(-1, 1))[0][1][0]
    print("方法三:\t\tw:{}\tb:{}".format(w, b))
    return w, b


def task1():
    x = np.array([6, 8, 10, 14, 18])
    y = np.array([7, 9, 13, 17.5, 18])
    task1_way1(x, y)
    task1_way2(x, y)
    w, b = task1_way3(x, y)
    task1_vis(x, y, w, b)


def task2():
    from numpy.linalg import inv
    X = np.array([[1, 6, 2], [1, 8, 1], [1, 10, 0], [1, 14, 2], [1, 18, 0]])
    X[:, 2] = X[:, 1] * X[:, 1]
    Y = np.array([[7], [9], [13], [17.5], [18]])
    beita = np.dot(inv(np.dot(np.transpose(X), X)), np.dot(np.transpose(X), Y))
    print(beita)
    from numpy.linalg import lstsq
    print(lstsq(X, Y)[0])


def task3():
    x_train = np.array([77.36, 116.74, 116.7, 100.68, 116.1, 115.81, 104.24, 106.73, 115.86])
    y_train = np.array([470, 730, 760, 680, 700, 720, 700, 690, 730])
    x_test = np.array([56.6, 78.4, 58, 123.5, 56.8, 77, 150.6])
    w, b = task1_way1(x_train, y_train)
    y_pre = x_test * w + b
    print(y_pre)
    task1_vis(x_train, y_train, w, b)


if __name__ == '__main__':
    # task1()
    # task2()
    task3()

相关文章:

  • 计算机网络——OSI 参考模型
  • 【.Net实用方法总结】 整理并总结System.IO中StreamWriter类及其方法介绍
  • openGl坐标系统
  • 实用工具系列 - Pycharm安装下载使用
  • Pyecharts绘图笔记
  • SNARK性能及安全
  • 学会 Python 自动安装第三方库,从此跟pip说拜拜
  • 3.前端开发就业前景
  • Discovery服务发现与Eureka自我保护机制及总结步骤
  • 机器学习01
  • 类加载器及反射简单笔记
  • MT6701磁编码器使用指南,14Bit单圈绝对值,I2C stm32 HAL库读角度
  • leetcode竞赛:20220918周赛
  • 牛客刷题,python入门基础(11)
  • 循序渐进学Git(可复习)
  • 深入了解以太坊
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Android开源项目规范总结
  • CentOS7简单部署NFS
  • MYSQL 的 IF 函数
  • mysql中InnoDB引擎中页的概念
  • SwizzleMethod 黑魔法
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • ViewService——一种保证客户端与服务端同步的方法
  • Vue--数据传输
  • 编写高质量JavaScript代码之并发
  • 初识 beanstalkd
  • 复杂数据处理
  • 搞机器学习要哪些技能
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 浅谈web中前端模板引擎的使用
  • 入手阿里云新服务器的部署NODE
  • 中文输入法与React文本输入框的问题与解决方案
  • 选择阿里云数据库HBase版十大理由
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (¥1011)-(一千零一拾一元整)输出
  • (1)(1.11) SiK Radio v2(一)
  • (Forward) Music Player: From UI Proposal to Code
  • (poj1.2.1)1970(筛选法模拟)
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (排序详解之 堆排序)
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (四)js前端开发中设计模式之工厂方法模式
  • (一)Docker基本介绍
  • .NET Core中的时区转换问题
  • .Net Memory Profiler的使用举例
  • .NET 表达式计算:Expression Evaluator
  • .net 设置默认首页
  • @vue-office/excel 解决移动端预览excel文件触发软键盘
  • @开发者,一文搞懂什么是 C# 计时器!
  • [28期] lamp兄弟连28期学员手册,请大家务必看一下
  • [Android]RecyclerView添加HeaderView出现宽度问题