说明:本文不包括TensorFlow相关内容

概念

概念:回归分析

回归分析(regression analysis)是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。运用十分广泛,回归分析按照涉及的变量的多少,分为一元回归和多元回归分析;按照因变量的多少,可分为简单回归分析和多重回归分析;按照自变量和因变量之间的关系类型,可分为线性回归分析和非线性回归分析。如果在回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且自变量之间存在线性相关,则称为多重线性回归分析。

回归分析按照三个要素区分:

自变量的个数

因变量的类型

回归线的形状

概念:线性回归

线性回归(Linear Regression),也就是回归线的形状为线性的回归,它是最为人熟知的建模技术之一。线性回归通常是人们在学习预测模型时首选的技术之一。在这种技术中,因变量是连续的,自变量可以是连续的也可以是离散的,回归线的性质是线性的。

线性回归使用最佳的拟合直线(也就是回归线)在因变量(Y)和一个或多个自变量(X)之间建立一种关系。

多元线性回归可表示为Y=a+b1∗X1+b2∗X2+⋯+bn∗Xn+ε,其中n表示自变量的个数,a表示截距,b1,b2…bn表示直线的斜率,ε是误差项。多元线性回归可以根据给定的预测变量来预测目标变量的值。

概念:一元线性回归

一元线性回归也就是自变量的个数为1的线性回归。

一元线性回归可以表示为y=ax+b+ε

y=a+bx+ε

概念:残差

残差在数理统计中是指实际观察值与估计值(拟合值)之间的差。“残差”蕴含了有关模型基本假设的重要信息。如果回归模型正确的话, 我们可以将残差看作误差的观测值。一元线性回归中的残差即为
ε=y−(a+bx)
公式推导
设有n对观测数据(xi,yi)(i=1,2,3,⋯,n),也就是
yi=a+bxi+εi
那么残差也就是
εi=yi−(a+bxi)
如果这些残差的简单求和视为总残差
Q(a,b)=∑i=1nεi=∑i=1n(yi−(a+bxi))
由于这些残差有正有负,简单求和可能导致正负抵消,设有函数
P:R→R,ε→P(ε)
Q(a,b)=∑i=1nP(εi)=∑i=1nP(yi−(a+bxi))
为了避免正负抵消,函数
P
应当满足
∀ε∈R
有
P(ε)≥0
,也就是非负性,最简单的情况为绝对值
Q(a,b)=∑i=1n∣εi∣=∑i=1n∣(yi−(a+bxi)∣
因为绝对值不便于公式推导,所以可以使用
Q(a,b)=∑i=1n(εi)2=∑i=1n((yi−(a+bxi))2
因此,只要求出使
Q(a,b)=∑i=1n((yi−(a+bxi))2
取得最小值的
a,b
值,既可以作为
a,b
的估计值
a^,b^
。
设x¯=1n∑i=1nxi,y¯=1n∑i=1nyi,可得
\begin{align}
\displaystyle Q(a,b) & = \sum_{i=1}^n (y_i - b x_i - a)^2 \\
& = \sum_{i=1}^n \bigl( (y_i - b x_i) - a \bigr)^2 \\
& = \sum_{i=1}^n \bigl( (y_i - b x_i)^2 + a^2 - 2 a (y_i - b x_i) \bigr) \\
& = \sum_{i=1}^n (y_i - b x_i)^2 + \sum_{i=1}^n a^2 + \sum_{i=1}^n - 2 a (y_i - b x_i) \\
& = \sum_{i=1}^n (y_i - b x_i)^2 + \sum_{i=1}^n a^2 + \sum_{i=1}^n (- 2 a y_i + 2 a b x_i) \\
& = \sum_{i=1}^n (y_i - b x_i)^2 + \sum_{i=1}^n a^2 - 2 a \sum_{i=1}^n y_i + 2 a b \sum_{i=1}^n x_i \\
& = \sum_{i=1}^n (y_i - b x_i)^2 + \sum_{i=1}^n a^2 - 2 a \sum_{i=1}^n \bar y + 2 a b \sum_{i=1}^n \bar x \\
& = \sum_{i=1}^n (y_i - b x_i)^2 + \sum_{i=1}^n a^2 + \sum_{i=1}^n ( - 2 a \bar y + 2 a b \bar x ) \\
& = \sum_{i=1}^n (y_i - b x_i)^2 + \sum_{i=1}^n a^2 + \sum_{i=1}^n - 2 a (\bar y - b \bar x ) \\
& = \sum_{i=1}^n (y_i - b x_i)^2 - \sum_{i=1}^n (\bar y - b \bar x)^2 + \sum_{i=1}^n (\bar y - b \bar x)^2 + \sum_{i=1}^n a^2 + \sum_{i=1}^n - 2 a (\bar y - b \bar x ) \\
& = \sum_{i=1}^n (y_i - b x_i)^2 - \sum_{i=1}^n (\bar y - b \bar x)^2 + \sum_{i=1}^n \bigl( (\bar y - b \bar x) - a \bigr)^2 \\
& = \overbrace{\sum_{i=1}^n \bigl( (y_i - b x_i)^2 - (\bar y - b \bar x)^2 \bigr)}^{part 1} + \overbrace{\sum_{i=1}^n \bigl( (\bar y - b \bar x) - a \bigr)^2}^{part 2} \label{label1} \\
\end{align}
等式
part1
只包含
b
,继续分解
\begin{align}
\displaystyle
\eqref{label1} part 1 & = \sum_{i=1}^n \bigl( (y_i - b x_i)^2 - (\bar y - b \bar x)^2 \bigr) \\
& = \sum_{i=1}^n ( y_i^2 - 2 b x_i y_i + b^2 x_i^2 - {\bar y}^2 + 2 b \bar x \bar y - b^2 {\bar x}^2 ) \\
& = \sum_{i=1}^n \bigl( b^2 (x_i^2 - {\bar x}^2) - 2 b (x_i y_i - \bar x \bar y) + y_i^2 - {\bar y}^2 \bigr) \\
& = b^2 \sum_{i=1}^n x_i^2 - b^2 \sum_{i=1}^n {\bar x}^2 - 2 b \sum_{i=1}^n (x_i y_i - \bar x \bar y) + \sum_{i=1}^n ( y_i^2 - {\bar y}^2 ) \\
& = b^2 \sum_{i=1}^n x_i^2 - b^2 n {\bar x}^2 - 2 b \sum_{i=1}^n (x_i y_i - \bar x \bar y) + \sum_{i=1}^n ( y_i^2 - {\bar y}^2 ) \\
& = b^2 \sum_{i=1}^n x_i^2 - 2 b^2 n {\bar x}^2 + b^2 n {\bar x}^2 - 2 b \sum_{i=1}^n (x_i y_i - \bar x \bar y) + \sum_{i=1}^n ( y_i^2 - {\bar y}^2 ) \\
& = b^2 \sum_{i=1}^n x_i^2 - b^2 \sum_{i=1}^n 2 x_i \bar x + b^2 \sum_{i=1}^n {\bar x}^2 - 2 b \sum_{i=1}^n (x_i y_i - \bar x \bar y) + \sum_{i=1}^n ( y_i^2 - {\bar y}^2 ) \\
& = b^2 \sum_{i=1}^n (x_i^2 -2 x_i \bar x + {\bar x}^2) - 2 b \sum_{i=1}^n (x_i y_i - \bar x \bar y) + \sum_{i=1}^n ( y_i^2 - {\bar y}^2 ) \\
& = b^2 \sum_{i=1}^n (x_i - \bar x)^2 - 2 b \sum_{i=1}^n (x_i y_i - \bar x \bar y) + \sum_{i=1}^n ( y_i^2 - {\bar y}^2 ) \label{label2} \\
\end{align}
b
应当为
b = \frac{\displaystyle \sum_{i=1}^n (x_i y_i - \bar x \bar y)}{\displaystyle \sum_{i=1}^n (x_i - \bar x)^2} \label{labelb}
得出
b
后,等式
part2
的最小值为0,此时
a = \bar y - b \bar x \label{labela}
\eqref{labela}
\eqref{labelb}
\displaystyle Q(a,b) = \sum_{i=1}^n \bigl( (y_i - (a + b x_i) \bigr)^2
Q(a,b)=∑i=1n((yi−(a+bxi))2
取得最小值的
a,b
a,b
值
\begin{cases} \hat b \stackrel{\eqref{labelb}}= \frac{\displaystyle \sum_{i=1}^n (x_i y_i - \bar x \bar y)}{\displaystyle \sum_{i=1}^n (x_i - \bar x)^2} \\ \hat a \stackrel{\eqref{label2}}= \bar y - \hat b \bar x \end{cases}
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪b^∑i=1n(xiyi−x¯y¯)∑i=1n(xi−x¯)2a^y¯−b^x¯
由此得到的直线
y^=a^+b^x
就成为这些样本数据的回归直线,此直线方程即为线性回归方程,其中
a^
称为回归截距,
b^
称为回归系数,
y^
称为回归值,回归截距也被称为偏置bias,缩写
b
,此时回归系数称为权重weight,缩写
w
。
# -*- coding: utf-8 -*-
""" filename : tutorial_example_1_helloworld.py author: hu@daonao.com QQ: 443089607 weixin: huzhenghui weibo: http://weibo.com/443089607 category : tensorflow title : python tensorflow学习笔记(六)最小二乘法 csdn blog url : weibo article url : weibo message url : 为了清晰直观展现python严格要求的缩进及数学公式,请访问博客上博文 详细说明见源代码中的注释 # 源代码 """
# standard import
import logging
import os
import matplotlib
import numpy
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('start tensorflow tutorial example 6 least squares')
STR_SCRIPT_DIR, STR_SCRIPT_FILE = os.path.split(__file__)
logging.debug('STR_SCRIPT_DIR : %s', STR_SCRIPT_DIR)
logging.debug('STR_SCRIPT_FILE : %s', STR_SCRIPT_FILE)
STR_SCRIPT_PREFIX = os.path.splitext(STR_SCRIPT_FILE)[0]
logging.debug('STR_SCRIPT_PREFIX : %s', STR_SCRIPT_PREFIX)
# os.path.join(STR_SCRIPT_DIR, STR_SCRIPT_PREFIX + '.ext')
# 样本x
SAMPLE_X = numpy.asarray([474.7, 479.9, 488.1, 509.6, 576.4, 654.7, 755.6,
798.6, 815.4, 718.4, 767.2, 759.5, 820.3, 849.8,
974.7, 1041.0, 1099.3, 1186.1, 1252.5])
logging.debug('SAMPLE_X : \n%s', SAMPLE_X)
# 样本y
SAMPLE_Y = numpy.asarray([526.9, 532.7, 566.8, 591.2, 700.0, 744.1, 851.2,
884.4, 847.3, 821.0, 884.2, 903.7, 984.1, 1035.3,
1200.9, 1289.8, 1432.9, 1539.0, 1663.6])
logging.debug('SAMPLE_Y : \n%s', SAMPLE_Y)
# 样本数量
N_SAMPLES = SAMPLE_X.shape[0]
logging.debug('N_SAMPLES : %d', N_SAMPLES)
# 样本x的平均值
MEAN_X = sum(SAMPLE_X) / N_SAMPLES
logging.debug('MEAN_X : %f', MEAN_X)
# 样本y的平均值
MEAN_Y = sum(SAMPLE_Y) / N_SAMPLES
logging.debug('MEAN_Y : %f', MEAN_Y)
# 权重
WEIGHT = ((sum(SAMPLE_X[i] * SAMPLE_Y[i] for i in range(N_SAMPLES)) - N_SAMPLES * MEAN_X * MEAN_Y) /
sum((SAMPLE_X[i] - MEAN_X) * (SAMPLE_X[i] - MEAN_X) for i in range(N_SAMPLES)))
logging.debug('WEIGHT : %f', WEIGHT)
# 偏置
BIAS = MEAN_Y - WEIGHT * MEAN_X
logging.debug('BIAS : %f', BIAS)
# 绘制样本
matplotlib.pyplot.plot(SAMPLE_X, SAMPLE_Y, 'ro', label='样本')
# 绘制拟合直线
matplotlib.pyplot.plot(SAMPLE_X, SAMPLE_X * WEIGHT + BIAS, label='拟合')
# 显示图例
matplotlib.pyplot.legend()
# 保存图片
matplotlib.pyplot.savefig(os.path.join(STR_SCRIPT_DIR, STR_SCRIPT_PREFIX + '.png'))
# 显示图片
matplotlib.pyplot.show()
# end of file