目录
1 什么是相关性?
相关性不等于因果性,也不是简单的个性化,相关性所涵盖的范围和领域几乎覆盖了我们所见到的方方面面,相关性在不同的学科里面的定义也有很大的差异。1
相关性分析(Analysis of Correlation)是指对两个或多个具备相关性的变量元素进行分析,从而衡量两个变量因素的相关密切程度。相关性的元素之间需要存在一定的联系或者概率才可以进行相关性分析。1
相关分析与回归分析之间的区别2:
- 回归分析侧重于研究随机变量间的依赖关系,以便用一个变量去预测另一个变量;
- 相关分析侧重于发现随机变量间的种种相关特性。相关分析在工农业、水文、气象、社会经济和生物学等方面都有应用。
利用双坐标轴折线图可以发现费用成本和广告曝光量两组数据的变化和趋势大致相同3。从整体的大趋势来看,费用成本和广告曝光量两组数据都呈现增长趋势。从规律性来看费用成本和广告曝光量数据每次的最低点都出现在同一天。从细节来看,两组数据的短期趋势的变化也基本一致。
经过以上这些对比,我们可以说广告曝光量和费用成本之间有一些相关关系,但这种方法在整个分析过程和解释上过于复杂,如果换成复杂一点的数据或者相关度较低的数据就会出现很多问题。
比折线图更直观的是散点图3。散点图去除了时间维度的影响,只关注广告曝光量和费用成本这里两组数据间的关系。在绘制散点图之前,我们将费用成本标识为X,也就是自变量,将广告曝光量标识为y,也就是因变量。下面是一张根据每一天中广告曝光量和费用成本数据绘制的散点图,X轴是自变量费用成本数据,Y轴是因变量广告曝光量数据。从数据点的分布情况可以发现,自变量x和因变量y有着相同的变化趋势,当费用成本的增加后,广告曝光量也随之增加。
折线图和散点图都清晰的表示了广告曝光量和费用成本两组数据间的相关关系,优点是对相关关系的展现清晰,缺点是无法对相关关系进行准确的度量,缺乏说服力。并且当数据超过两组时也无法完成各组数据间的相关分析。若要通过具体数字来度量两组或两组以上数据间的相关关系,就需要使用协方差来完成计算。
协方差及协方差矩阵
协方差用来衡量两个变量的总体误差:
如果两个变量的变化趋势一致,协方差就是正值,说明两个变量正相关
。
如果两个变量的变化趋势相反,协方差就是负值,说明两个变量负相关
。
如果两个变量相互独立,那么协方差就是0,说明两个变量不相关
。
cov
(
X
,
Y
)
=
∑
i
=
1
n
(
X
i
−
X
ˉ
)
(
Y
i
−
Y
ˉ
)
n
−
1
\operatorname{cov}(X, Y)=\frac{\sum_{i=1}^{n}\left(X_{i}-\bar{X}\right)\left(Y_{i}-\bar{Y}\right)}{n-1}
cov(X,Y)=n−1∑i=1n(Xi−Xˉ)(Yi−Yˉ)
协方差只能对两组数据进行相关性分析,当有两组以上数据时就需要使用协方差矩阵。下面是三组数据x,y,z,的协方差矩阵计算公式:
C
=
(
cov
(
x
,
x
)
cov
(
x
,
y
)
cov
(
x
,
z
)
cov
(
y
,
x
)
cov
(
y
,
y
)
cov
(
y
,
z
)
cov
(
z
,
x
)
cov
(
z
,
y
)
cov
(
z
,
z
)
)
C=\left(\begin{array}{lll} \operatorname{cov}(x, x) & \operatorname{cov}(x, y) & \operatorname{cov}(x, z) \\ \operatorname{cov}(y, x) & \operatorname{cov}(y, y) & \operatorname{cov}(y, z) \\ \operatorname{cov}(z, x) & \operatorname{cov}(z, y) & \operatorname{cov}(z, z) \end{array}\right)
C=⎝⎛cov(x,x)cov(y,x)cov(z,x)cov(x,y)cov(y,y)cov(z,y)cov(x,z)cov(y,z)cov(z,z)⎠⎞
协方差通过数字衡量变量间的相关性,正值表示正相关,负值表示负相关。
但无法对相关的密切程度进行度量,当我们面对多个变量时,无法通过协方差来说明那两组数据的相关性最高,所以需要相关系数。
相关系数
相关系数(Correlation coefficient)又称皮尔逊相关系数,衡量了两个变量的线性相关程度。定义变量
X
X
X与
Y
Y
Y的协方差
C
o
v
(
X
,
Y
)
Cov(X,Y)
Cov(X,Y):
C
o
v
(
X
,
Y
)
=
E
[
X
−
E
(
x
)
]
[
Y
−
E
(
Y
)
]
Cov(X,Y) = E{[X - E(x)][Y - E(Y)]}
Cov(X,Y)=E[X−E(x)][Y−E(Y)]
随机变量与的相关系数
ρ
X
Y
ρ_{XY}
ρXY:
ρ
X
Y
=
Cov
(
X
,
Y
)
D
(
x
)
D
(
y
)
\rho_{X Y}=\frac{\operatorname{Cov}(X, Y)}{\sqrt{D(x)} \sqrt{D(y)}}
ρXY=D(x)D(y)Cov(X,Y)
相关系数有如下的性质:
1.
∣
ρ
X
Y
∣
≤
1
∣ρ_{XY}∣ ≤ 1
∣ρXY∣≤1的
∣
ρ
X
Y
∣
∣ρ_{XY}|
∣ρXY∣越大,表明线性相关程度越高,当
∣
ρ
X
Y
∣
=
0
∣ρ_{XY}∣ =0
∣ρXY∣=0表示为不相关。
2.
∣
ρ
X
Y
∣
=
1
∣ρ_{XY}∣ =1
∣ρXY∣=1的充要条件是存在常数
a
,
b
a,b
a,b使得
P
{
Y
=
a
+
b
X
}
=
1
P\{Y=a+bX\}=1
P{Y=a+bX}=1,即
X
X
X和
Y
Y
Y一定存在线性关系。
3.线性相关和独立的关系:
- 当 X X X和 Y Y Y相互独立时, C o v ( X , Y ) = 0 Cov(X,Y)=0 Cov(X,Y)=0。因此 ∣ ρ X Y ∣ = 0 ∣ρ_{XY}∣ =0 ∣ρXY∣=0,此时 X X X和 Y Y Y一定不相关。
- 当 X X X和 Y Y Y不相关, X X X和 Y Y Y不一定相互独立。因为不相关针对线性关系来说的,相关独立是就一般关系来说的。
(1)简单相关分析
简单相关分析,就是分析两个变量之间的线性相关程度。
适用范围:线性相关分析,两个变量之间的线性相关程度
常用相关系数:Pearson 相关系数,Spearman相关系数,Kendall相关系数
方法简述:根据定义计算相关系数,从而判定相关关系。
(2)偏相关分析
适用范围:当两个变量同时与第三个变量相关时,控制其他变量的线性影响的条件下分析两变量间的线性相关性
常用相关系数:偏相关系数
方法简述:将第三个变量的影响剔除,只分析另外两个变量之间相关关系,进行简单相关分析得到偏相关系数,然后判定指标相关系数的R值。
(3)复相关分析
适用范围:一个变量与另一组变量的相关关系
常用相关系数:复相关系数
方法简述:测定一个变量和一组变量之间的相关系数,即复相关系数时,先将一组变量进行线性组合,通过计算一个变量与该线性组合之间的简单相关系数作为复相关系数,然后判定指标相关系数的R值。
(4)典型相关分析
适用范围:多个随机变量和多个随机变量之间的相关关系
方法简述:利用主成分分析的思想,相当于对每组变量进行线性组合,求组合后的两个典型变量之间的相关性,然后使用用p检验方法,将显著性最大的那组作为最后的线性组合的系数,从而得到相关关系。
2 对已有数据的预分析
根据已有的数据表,可以找到以下
英文名 | 中文名 | 示例数据 |
---|---|---|
time | 数据时间 | 43476.9993055556 |
velocity | 车速 km/h | 0 |
SoC | SOC(荷电状态) | 70 |
voltage | 总电压 V | 573.6 |
current | 总电流 A | -203.5 |
maximum voltage | 最高电池值 | 3.42 |
minimum voltage | 最低电池值 | 3.39 |
max. temperature | 最高温度值 | 27 |
min. tem. | 最低温度值 | 22 |
voltage of ES | 可充电储能装置电压 | 573.6 |
current of ES | 可充电储能装置电流 | -203.5 |
cell num. | 电池总数 | 336 |
cell vol. | 单体电池电压列表 | {3.410/3.400/3.410…} |
tem. | 可充电储能装置温度探针个数 | 64 |
tem. of ES | 可充电储能装置温度值 | {25/26/26…} |
2.1 绘制变量相关的热力图
我们对各变量之间的相关性进行分析:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
csv_name = 'velocity_SOC(1).csv'
# header参数将表头设置为1,而不是默认的0
csv_data = pd.read_csv(csv_name, encoding='gbk', header=1)
# index_col参数默认为False,即自动分配行index
# csv_data.head(10)
corrit = csv_data.corr()
# 丢失掉缺失项的行列
corrit.dropna(axis=1, how="all", inplace=True)
corrit.dropna(axis=0, how="all", inplace=True)
# print(corrit)
# 解决中文乱码
sns.set_style('whitegrid',{'font.sans-serif':['simhei','Arial']})
# 解决保存图像是负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus']=False
# 设置大小
plt.figure(figsize=(8, 8))
plt.rcParams['savefig.dpi'] = 50 #图片像素
plt.rcParams['figure.dpi'] = 50 #分辨率
# 绘制图像
ax = sns.heatmap(corrit, linewidths = 0.01,vmin=-1, vmax=1.0, square=True, annot=True)
ax.set_title("相关性热力图")
从上面的热力图我们可以分析:
- 相关性为1的其实就是一样的数值,也就是除了一样的变量外,可充电储能装置的电压和总电压V、可充电储能装置的电流和总电流A数值是一样的,具体原因有待分析,可能是电车就一种电池装置所以数值一致。
- 然后就是根据此表绘制可能相关的变量表(|相关性|<0.4的舍弃):
2.2 对热力图进行分析
变量1 | 变量2 | 相关系数 | 分析与备注 |
---|---|---|---|
车速 km/h | 最低电池值 | -0.55 | 车速快,功率大,电压低 |
车速 km/h | 总电压 V | -0.42 | 车速快,功率大,电压低 |
SOC | 最高电池值 | 0.71 | 均是电池参数,会随用电改变 |
SOC | 最低电池值 | 0.67 | 均是电池参数,会随用电改变 |
SOC | 总电压 V | 0.69 | 均是电池参数,会随用电改变 |
SOC | 总电流 A | -0.63 | 均是电池参数,会随用电改变 |
总电压 V | 总电流 A | -0.96 | 电流和电压负相关 |
总电压 V | 最高电池值 | 0.97 | 都是电压肯定相关 |
总电压 V | 最低电池值 | 0.97 | 都是电压肯定相关 |
总电压 V | 最高温度值 | 0.56 | 发热引起温度改变 |
总电压 V | 最低温度值 | 0.58 | 发热引起温度改变 |
总电流 A | 最高电池值 | -0.91 | 电流和电压负相关 |
总电流 A | 最低电池值 | -0.89 | 电流和电压负相关 |
总电流 A | 最高温度值 | -0.62 | 发热引起温度改变 |
总电流 A | 最低温度值 | -0.63 | 发热引起温度改变 |
最高电池值 | 最低电池值 | 0.92 | 同属性变化趋势一样 |
最高电池值 | 最高温度值 | 0.59 | 发热引起温度改变 |
最高电池值 | 最低温度值 | 0.61 | 发热引起温度改变 |
最低电池值 | 最高温度值 | 0.52 | 发热引起温度改变 |
最低电池值 | 最低温度值 | 0.54 | 发热引起温度改变 |
最高温度值 | 最低温度值 | 0.99 | 同属性变化趋势一样 |
根据分析判断,选择以下几种变量可以开展研究:
序号 | 变量1 | 变量2 | 相关系数 | 分析与备注 |
---|---|---|---|---|
① | 车速 km/h | 最低电池值 | -0.55 | 车速快,功率大,电压低 |
② | SOC | 总电压 V | 0.69 | 均是电池参数,会随用电改变 |
③ | 总电压 V | 总电流 A | -0.96 | 电流和电压负相关 |
④ | 总电压 V | 最高温度值 | 0.56 | 发热引起温度改变 |
⑤ | 总电流 A | 最高温度值 | -0.62 | 发热引起温度改变 |
根据实验③和物理知识,可以得知电压电流与最高温度值的关系应该差不多,所以方便起见可以只考虑总电压与最高温度值的关系。
那么就可以把研究变成三个大方面:
- 实验①通过车速研究最低电池值(电压),以达到对车速上限的合理控制;
- 实验②通过电池剩余电量SOC与总电压的关系,可以预测车辆剩余电量,以再通过车辆行驶状态预测剩余续航里程;
- 实验④通过总电压与最高温度值的关系,可以做到限制最高功率输出,来降低电池温度,以达到保护电池的作用。
3 具体研究的展开
3.1 车速 km/h与最低电池值(电压)的研究
我们通过对按照数据时间分组,然后车速和最低电池值取平均值,然后先绘制时间序列相关的图:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
csv_name = 'velocity_SOC(1).csv'
# header参数将表头设置为1,而不是默认的0
csv_data = pd.read_csv(csv_name, encoding='gbk', header=1)
# 实验①需要的数据
# 对数据按照数据时间分组,然后车速和最低电池值取平均值
exper_1= csv_data.groupby("数据时间")[["车速 km/h", "最低电池值"]].mean()
plt.figure(figsize=(20, 8))
#exper_1
plt.subplot(121)
plt.plot(np.arange(1,exper_1.shape[0]+1),exper_1['车速 km/h'].values)
plt.title("车速km/h随时间序列的变化")
plt.ylabel("车速km/h")
plt.subplot(122)
plt.plot(np.arange(1,exper_1.shape[0]+1),exper_1['最低电池值'].values)
plt.title("最低电池值随时间序列的变化")
plt.ylabel("最低电池值")
从每个图中,对其变化的趋势并没有发现很明显的规律,结合两个图可以看出来,在车速上升的时候最低电池值会随之下降(凹陷),但是车速在025和80170时间段中对应的最低电池值起始不太一样,难道是中间在125时刻电池进行了充电?
所以根据预处理图的关系,我认为将时间序列缩短到25~80时刻进行研究,我们再绘制图:
# 把数据圈定在25~80时刻
exper_1_final = exper_1.iloc[25:81]
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(np.arange(1,exper_1_final.shape[0]+1),exper_1_final['车速 km/h'].values, 'b-')
ax2.plot(np.arange(1,exper_1_final.shape[0]+1),exper_1_final['最低电池值'].values,'g-')
ax1.set_ylabel("车速km/h",color='b')
ax2.set_ylabel("最低电池值",color='g')
从上图就可以看出来非常具有可以进一步分析的地步,接下来我们就找出来对应关系并且找到最低得安全临界电池值就可以找到最高限速在什么地方。
3.2 SOC(电池剩余电量)与总电压V的研究
同理的我们也可以计算出实验二对应的图:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
csv_name = 'velocity_SOC(1).csv'
# header参数将表头设置为1,而不是默认的0
csv_data = pd.read_csv(csv_name, encoding='gbk', header=1)
# 实验②需要的数据
# 对数据按照数据时间分组,然后SOC和总电压V取平均值
exper_2= csv_data.groupby("数据时间")[["SOC", "总电压 V"]].mean()
plt.figure(figsize=(15, 7))
#exper_2
plt.subplot(221)
plt.plot(np.arange(1,exper_2.shape[0]+1),exper_2['SOC'].values)
plt.title("SOC随时间序列的变化")
plt.ylabel("SOC")
plt.subplot(222)
plt.plot(np.arange(1,exper_1.shape[0]+1),exper_2['总电压 V'].values)
plt.title("总电压V值随时间序列的变化")
plt.ylabel("总电压V")
ax1 = plt.subplot(212)
#fig, ax1 = plt.subplots()
ax2 = plt.twinx()
ax1.plot(np.arange(1,exper_2.shape[0]+1),exper_2['总电压 V'].values, 'b-')
ax2.plot(np.arange(1,exper_2.shape[0]+1),exper_2['SOC'].values,'g-')
ax1.set_ylabel("总电压V",color='b')
ax2.set_ylabel("SOC",color='g')
3.3 总电压V与最高温度值的研究
同样我们也进行绘制:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
csv_name = 'velocity_SOC(1).csv'
# header参数将表头设置为1,而不是默认的0
csv_data = pd.read_csv(csv_name, encoding='gbk', header=1)
# 实验③需要的数据
# 对数据按照数据时间分组,然后最高温度值和总电压 V取平均值
exper_3= csv_data.groupby("数据时间")[["最高温度值", "总电压 V"]].mean()
plt.figure(figsize=(15, 7))
#exper_3
plt.subplot(221)
plt.plot(np.arange(1,exper_2.shape[0]+1),exper_3['最高温度值'].values)
plt.title("最高温度值随时间序列的变化")
plt.ylabel("最高温度值")
plt.subplot(222)
plt.plot(np.arange(1,exper_1.shape[0]+1),exper_3['总电压 V'].values)
plt.title("总电压V值随时间序列的变化")
plt.ylabel("总电压V")
ax1 = plt.subplot(212)
#fig, ax1 = plt.subplots()
ax2 = plt.twinx()
ax1.plot(np.arange(1,exper_3.shape[0]+1),exper_3['总电压 V'].values, 'b-')
ax2.plot(np.arange(1,exper_3.shape[0]+1),exper_3['最高温度值'].values,'r-')
ax1.set_ylabel("总电压V",color='b')
ax2.set_ylabel("最高温度值",color='r')
4 总结
上述探究还远没有完成,还需要进一步探究和总结,通过对数据相关性的探究,不仅可以提高numpy、pandas、matplotlib以及拓展库的使用熟练度,甚至于利用sklearn、pytorch进行进一步的机器学习和深度学习研究,还可以提高对数据模型的直观认识。可是我由于对此领域的知识欠缺,和分析的局限性,往往不知道下一步工作该如何开展,我会坚持不断得继续探究和分析,进一步完成分析工作。