相关(correlation)与回归(regression)
分类问题研究的是离散值,而回归问题所研究的目标变量是连续值,可以根据回归曲线来预测数值
变量之间的关系分为函数(回归)关系和相关关系
- 回归是研究自变量与因变量之间的关系形式的分析方法,其目的为根据已知自变量(输入量)来估计和预测因变量(输出量)的值
- 相关是反映事物之间的非严格的不确定的线性依存关系,其特点为:
- 事物之间在数量上确实存在一定的内在联系,表现在一个变量发生数量上的变化,要影响另一个变量也相应的发生数量上的变化,不如劳动生产率和成本之间的关系,劳动生产率上升,成本下降。
- 事物之间的数量依存关系不是确定的,具有一定的随机性。表现在给定自变量一个数值,因变量会有若干个数值和它对应,并且因变量总是遵循一定规律围绕这些数值平均数上下波动。其原因是影响因变量发生变化的因素不止一个,比如影响环境温度的不只是太阳辐射,还有可能是城市下垫面、大气污染、人工热源等的影响
研究两个或者两个以上变量之间关系的方法有回归分析和相关分析
- 相关分析:研究两个或者两个以上随机变量之间线性依存关系的紧密程度。通常用相关系数表示,多元相关时用复相关系数表示
- 回归分析:研究某一随机变量(因变量)与其他一个或几个普通变量(自变量)之间的数量变动的关系
相关关系中的相关系数是对变量之间关系密切程度的度量
(r 的取值为[-1,1],当r=1时为完全正相关,r=-1的时候为完全负相关,r=0的时候为不存在线性相关关系,r<0为负相关,r>0为正相关)
- |r|>0.7为高度相关
- |r|<0.3为低度相关
- 0.3<|r|<0.7为中度相关
下图为例:
相关系数的缺点:r接近于1的程度与数据的样本大小n有关
当n较小时r的波动较大
当n较大时r的绝对值容易偏小
例如,当n=2时,r的绝对值总是为1,因为两点的连线总为一条直线
根据计算相关系数公式可以写程序计算相关系数,也可以使用pandas中的corr()方法计算相关系数公式
"""
-*- coding: utf-8 -*-
@Time : 2021/8/6 11:22
@Author : wcc
@FileName: CorrelationTest.py
@Software: PyCharm
@Blog :https://blog.csdn.net/qq_41575517?spm=1000.2115.3001.5343
"""
import pandas as pd
import numpy as np
income = [20, 40, 20, 30, 10, 10, 20, 20, 20, 30]
production = [30, 60, 40, 60, 30, 40, 40, 50, 30, 70]
# 形成字典结构
df = pd.DataFrame({'income': np.array(income), 'production': np.array(production)})
print(df)
# 计算相关系数
print(df.corr())
当有多个变量时求其相关系数为:
"""
-*- coding: utf-8 -*-
@Time : 2021/8/6 11:35
@Author : wcc
@FileName: Correlation.py
@Software: PyCharm
@Blog :https://blog.csdn.net/qq_41575517?spm=1000.2115.3001.5343
"""
import pandas as pd
import numpy as np
cost = [250, 360, 165, 43, 92, 200, 355, 290, 230, 120, 73, 205, 400, 320, 72, 272, 94, 190, 235, 139]
temperature = [35, 29, 36, 60, 65, 30, 10, 70, 21, 55, 54, 48, 20, 39, 60, 20, 58, 40, 27, 30]
thickness = [3, 4, 7, 6, 5, 5, 6, 10, 9, 2, 12, 5, 5, 4, 8, 5, 7, 8, 9, 7]
years = [6, 10, 3, 9, 6, 5, 7, 10, 11, 5, 4, 1, 15, 7, 6, 8, 3, 11, 8, 5]
df = pd.DataFrame({'cost': np.array(cost), 'temperature': np.array(temperature), 'thickness': np.array(thickness), 'year': np.array(years)})
print(df)
print(df.corr())
# 如果键值对中的键为中文,则索引的时候的['temperature']要变为[u'temperature'],也就是前面要加一个u,意思是用Unicode的方式进行编码
# 此处是取的temperature和四个其他参数之间的关系
print(df.corr()['temperature'])
# 求cost和temperature之间的关系
print(df['cost'].corr(df['temperature']))
输出:
cost temperature thickness year
0 250 35 3 6
1 360 29 4 10
2 165 36 7 3
3 43 60 6 9
4 92 65 5 6
5 200 30 5 5
6 355 10 6 7
7 290 70 10 10
8 230 21 9 11
9 120 55 2 5
10 73 54 12 4
11 205 48 5 1
12 400 20 5 15
13 320 39 4 7
14 72 60 8 6
15 272 20 5 8
16 94 58 7 3
17 190 40 8 11
18 235 27 9 8
19 139 30 7 5
cost temperature thickness year
cost 1.000000 -0.661027 -0.257101 0.536728
temperature -0.661027 1.000000 0.178191 -0.315893
thickness -0.257101 0.178191 1.000000 0.063617
year 0.536728 -0.315893 0.063617 1.000000
cost -0.661027
temperature 1.000000
thickness 0.178191
year -0.315893
Name: temperature, dtype: float64
-0.6610265353019104
相关分析和回归分析的区别和联系:
区别:
- 相关分析:研究的变量都是随机变量,不分自变量与因变量。判断各个属性之间联系的紧密程度
- 回归分析:明确的自变量与因变量,自变量是确定的普通变量,因变量是随机变量。用来分析预测
联系:
- 在实际生活中,一般先进行相关分析,由相关系数的大小决定是否需要进行回归分析,在相关分析的基础上建立回归模型,以便进行推算和预测
使用回归时需要注意的点:
- 回归模型中的医院回归模型和多元回归模型是依据自变量的多少来区分的
- 而线性和非线性回归模型是依据自变量与因变量之间的关系是否成线性来区分的
- 利用回归来分析预测的时候,数据量不能太少
- 预测对象和影响因素之间必须存在相关关系
一元线性回归(Linear regression )
其实一元线性回归研究的问题是如何画好一条直线,并且只研究一个自变量和一个因变量之间线性的关系,其只涉及一个变量的简单线性回归模型为:
上式中的β0和β1是参数,而ε是随机误差项,又称随机干扰项,并且有ε~N(0,δ2)
但是如何选好这条线?换句话说也就是如何知道自己选的线是最标准且预测出来的数据最准确?可以用最小二乘法来进行计算
最小二乘法
通过数学模型拟合出来一条较为理想的直线,且这条直线必须满足两点要求
- 原数列的观测值与模型估计值的离差(观测值和估计值之间的差)平方和(即所有点到该直线的垂直距离的平方和)为最小
- 原数列的观测值与模型的估计值的离差之和为0
根据上述公式可以用代码实现并得到直线回归方程:
"""
-*- coding: utf-8 -*-
@Time : 2021/8/12 21:54
@Author : wcc
@FileName: Linear.py
@Software: PyCharm
@Blog :https://blog.csdn.net/qq_41575517?spm=1000.2115.3001.5343
"""
from sklearn import linear_model
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4))
plt.title("Linear function")
x = [522, 539, 577, 613, 644, 670, 695, 713, 741, 769, 801, 855, 842, 860, 890, 920]
y = [6700, 7136, 7658, 7784, 8108, 7583, 8002, 8442, 8158, 8683, 9317, 9675, 8542, 8584, 9612, 9719]
x = np.array(x)
y = np.array(y)
n = int(x.size)
mulXY = 0
sumX = 0
sumY = 0
sumSquareX = 0
# 中间步骤,分别计算各个参数
for i in range(n):
mulXY += x[i] * y[i]
sumX += x[i]
sumY += y[i]
sumSquareX += x[i] * x[i]
# 计算b1和b0
b1 = ((n * mulXY)-(sumX * sumY))/((n*sumSquareX)- sumX*sumX)
b0 = sumY/n - b1*sumX/n
print(b1)
print(b0)
# 得到的估计值方程
y1 = b0 + b1*x
# 画出求得的直线
plt.plot(x, y1, label="linear", color="red", linewidth=2)
# 画出散点
plt.scatter(x, y)
# xlabel()和ylabel()设置X/Y轴的文字
plt.xlabel("X")
plt.ylabel("Y")
# 为了显示曲线所对应的名称,如去掉legend(),则图示中的曲线名称不显示
plt.legend()
plt.show()
输出:
6.5248271193981315
3605.139951993273
所得到的图形为:
调用sklearn模块中的函数来计算直线回归方程:
"""
-*- coding: utf-8 -*-
@Time : 2021/8/12 23:51
@Author : wcc
@FileName: Linear2.py
@Software: PyCharm
@Blog :https://blog.csdn.net/qq_41575517?spm=1000.2115.3001.5343
"""
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
x = [522, 539, 577, 613, 644, 670, 695, 713, 741, 769, 801, 855, 842, 860, 890, 920]
y = [6700, 7136, 7658, 7784, 8108, 7583, 8002, 8442, 8158, 8683, 9317, 9675, 8542, 8584, 9612, 9719]
x = np.array(x).reshape(-1, 1)
y = np.array(y).reshape(-1, 1)
# 调用模型
model = linear_model.LinearRegression()
# 用此模型去训练x,y
model.fit(x, y)
# 打印系数
print(model.coef_)
# 打印截距
print(model.intercept_)
输出:
[[6.52482712]]
[3605.13995199]
多元线性回归
当有多个因变量时的回归叫做多元线性回归
当设x0=1时,则可以推出如下公式:
上述方程称为回归方程的通式,θi被称为回归系数或权重
而做线性回归所需要解决的问题也就显而易见,也就是找到θ向量的值
与一元线性回归相似,在求θ向量的时候也要确保预测值h(x)和真实值y尽可能接近
为了衡量预测值与真实值的接近程度,定义损失函数如下(依旧是以最小二乘的思想来计算的):
y(i)表示第i个训练实例对应的目标变量值,m为实例数量
常数1/2是为了求导方便(为了求导后和降下来的平方抵消掉)
注意:并不是所有的函数都可以根据偏导求出取得0值的点的,可能会出现导数在每个点的值可以求出来,但是直接解方程解不出来的情况,并且,由于计算机的特性,循环迭代的方法可能更适合计算机求极值。其基本思路为:先假设一个初始参数值,计算损失函数数值,再不断调整参数,并对比调整前后损失函数值的变化,如果函数值变小,则表示调整后的参数值较好
梯度下降法(逼近)
是一个最优化算法,通常也被称为最速下降法,梯度下降法可以简单理解为:假设爬山的时候想最快爬到山顶,势必要从最山势陡峭(也就是山势变化最快)的地方向上爬。同理,如果从任意一点出发,想要以最快速度搜索到最大值,那么也应从函数变化最快的方向搜索,函数变化最快的方向即为函数的梯度方向
- 在选取步长α时,要注意选取适当值,当选取值过大时容易出现越过极值点,导致不收敛,过小则会使收敛速度恨慢
- 随着迭代次数的增加,一般要慢慢减小α(直观理解为刚开始很快,然后逐渐放慢速度)
如果每一次更新都计算整个训练集的数据样本,则称之为批量梯度下降法(Batch Gradient Descent (BGD)),其计算成本很高
另一种方法是一次仅仅用一个随机选取的样本来更新回归系数,该方法称为随机梯度下降法(Stochastic Gradient Descent(SGD))
此处引出了一个重要问题,也就是机器学习时的训练是在训练什么?其实是在训练参数,而梯度下降法则是训练参数的一个重要代表方法