参考链接:
1-【机器学习】【线性代数】均值,无偏估计,总体/样本方差,样本标准差,矩阵中心化/标准化、协方差,正/不/负相关等,协方差矩阵2-数据什么时候需要做中心化和标准化处理?3-推荐引擎中的RMS和RMSE
注意方差、标准差与RMS的区别,若想学习RMS请参考链接3
目录
- 1、numpy基础
- 2、数据保存与加载
- 2.1使用numpy方法保存和加载数据
- 2.2、使用pickle方法保存与加载数据
- 2.2.1保存加载一般的数据类型
- 2.2.2保存加载类及调用类方法
- 3、求方差(variance),一般简写var
- 4、求标准差(standard deviation),一般简写std
- 5、求协方差(covariance),一般简写cov
- 6、求协方差矩阵
- 7、数据中心化
1、numpy基础
定义一个数组
>>> import numpy as np
>>> a = np.array([2,7,4,3])#传入列表定义
>>> a
array([2, 7, 4, 3])
>>> a = np.zeros([2,3])#用形状
>>> a
array([[0., 0., 0.],
[0., 0., 0.]])
>>> a = np.ones([2,3])
>>> a
array([[1., 1., 1.],
[1., 1., 1.]])
2、数据保存与加载
2.1使用numpy方法保存和加载数据
numpy的save方法,简单方便使用,可以保存数组、json等各种格式,如果用来保存类等一些方法,加载的时候会转换成ndarray格式,从而再调用类中方法的时候会出错
import numpy as np
data = {"a":np.array([1,2,3]),"b":np.array([4,5,6]),"c":123,"d":[1,2,3]}
print("data=",data)
np.save("./NumpyTest",data)
b3 = np.load("./NumpyTest.npy",allow_pickle=True)
print("b3=",b3)
输出
b3= {'a': array([1, 2, 3]), 'b': array([4, 5, 6]), 'c': 123, 'd': [1, 2, 3]}
检查输出的NumpyTest.npy文件,大小541字节
2.2、使用pickle方法保存与加载数据
pickle提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。
pickle模块只能在python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,
pickle序列化后的数据,可读性差,人一般无法识别。
pickle.dump(obj, file[, protocol])
序列化对象,并将结果数据流写入到文件对象中。参数protocol是序列化模式,默认值为0,表示以文本的形式序列化。protocol的值还可以是1或2,表示以二进制的形式序列化。
pickle.load(file)
反序列化对象。将文件中的数据解析为一个Python对象。
对比发现,与numpy保存优点:
1、使用二进制序列化保存,使得文件大小大幅度减少
2、保存的类等变量,加载后依然可以正常使用(加载的时候这个类进行申明或者可访问状态,否则会出现异常)
2.2.1保存加载一般的数据类型
以上面numpy保存的数据文件为例子进行下面操作
import pickle
data = {"a":np.array([1,2,3]),"b":np.array([4,5,6]),"c":123,"d":[1,2,3]}
print("data=",data)
f = open("./PickleTest.pkl","wb")#用二进制保存方式
pickle.dump(data,f)
f.close()
f2 = open("./PickleTest.pkl","rb")#用二进制方式进行读取
b2 = pickle.load(f2)
f2.close()
print("b2=",b2)
输出:
data= {'a': array([1, 2, 3]), 'b': array([4, 5, 6]), 'c': 123, 'd': [1, 2, 3]}
b2= {'a': array([1, 2, 3]), 'b': array([4, 5, 6]), 'c': 123, 'd': [1, 2, 3]}
说明完全还原了保存前的数据状态
查看保存的PickleTest.pkl文件,只有272字节,相对于numpy保存接近减少了一半的空间量
2.2.2保存加载类及调用类方法
import pickle
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
print("name = %s,age = %s"%(self.name,self.age))
aa = Person("Robin",30)
aa.show()
f = open("./PickleTest.pkl","wb")
pickle.dump(aa,f)
f.close()
f2 = open("./PickleTest.pkl","rb")
b2 = pickle.load(f2)
f2.close()
b2.show()
输出:
name = Robin,age = 30
name = Robin,age = 30
3、求方差(variance),一般简写var
公式:
方差定义:统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。在许多实际问题中,研究方差即偏离程度有着重要意义。(百度百科)
求解步骤:
1、定义样本:a = [a1,a2,a3....an]
2、求出样本的平均值 m = mean(a)
3、用样本delta_a = a -m
结果:delta_a = [a1-m,a2-m,a3-m,....,an-m]
4、对delta_a列表中每个元素进行平方,delta_a_square =[delta_a[0]**2,delta_a[1]**2,....delta_a[n]**2]
5、对第四步的结果求和 Sum_delta_square = sum(delta_a_square)
6、方差的结果等于第五步求和的结果除以a的长度,即:
var = Sum_delta_square/len(a)
公式验证:(验证数据:[ 0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88,
-0.04, 0.2 , 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.8 ,
-0.33, -0.24, -0.13, -0.82, 0.56])
import numpy as np
a = np.array([ 0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88,
-0.04, 0.2 , 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.8 ,
-0.33, -0.24, -0.13, -0.82, 0.56])
m = np.mean(a)#0.0060869565217391165
b = a-m#公式第三步
b = b**2#公式第四步
var = sum(b)/len(b)公式第五步和六步
>>> var
0.2534933837429112
希望可以通过上面分解的公式可以理解其含义,其实也可以借助numpy调用.var()函数一行搞定:
>>> np.var(a)
0.25349338374291114
4、求标准差(standard deviation),一般简写std
方差开放即标准差,接着上面的代码
借助于numpy中的std()方法一行搞定,如下代码:
5、求协方差(covariance),一般简写cov
协方差公式:如果有X,Y两个变量,每个时刻的“X值与其均值之差”乘以“Y值与其均值之差”得到一个乘积,再对这每时刻的乘积求和并求出均值,即为协方差。
协方差的意义:
在概率论和统计学中,协方差用于衡量两个变量的总体误差。而方差是协方差的一种特殊情况,即当两个变量是相同的情况。
正相关、负相关、不相关理解:
两个变量在变化过程中是否同向变化?还是反方向变化?同向或反向程度如何?
你变大,同时我也变大,说明两个变量是同向变化的,这是协方差就是正的。
你变大,同时我变小,说明两个变量是反向变化的,这时协方差就是负的。
从数值来看,协方差的数值越大,两个变量同向程度也就越大,反之亦然。
可以看出来,协方差代表了两个变量之间的是否同时偏离均值,和偏离的方向是相同还是相反。
协方差为0的两个 随机变量称为是不相关的。
cov(X,Y)数值表示X和Y的相关性。
假如X代表女人的颜值高低,Y代表男人对女人的喜欢程度。
cov(X,Y)>0,表明女人颜值越高,男人越喜欢女人,即X和Y是正相关。
cov(X,Y)<0,表明女人颜值越高,男人越讨厌女人,即X和Y是负相关。
cov(X,Y)=0,表明女人颜值高不高,和男人喜欢不喜欢,没有任何关联关系。
公式理解:
#测试数据
a=[ 0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88,
-0.04, 0.2 , 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.8 ,
-0.33, -0.24, -0.13, -0.82, 0.56]
b=[ 0.07, -0.55, -0.04, 3.11, 0.28, -0.5 , 1.1 , 1.97, -0.31,
-0.55, 2.06, -0.24, -1.44, 1.56, 3.69, 0.53, 2.3 , 1.09,
-2.63, 0.29, 1.3 , -1.54, 3.19]
求a和b的协方差
计算步骤:
1、求出a的均值和b的均值。
m_a = np.mean(a) = sum(a1+a2+a3+....+an)/len(a)
m_b = np.mean(b) = sum(b1+b2+b3+....+bn)/len(b)
2、分别求出均值差:
delta_a = a-m_a = [a1-m_a, a2-m_a, a3-m_a,....an - m_a ]
delta_b = b-m_b = [b1-m_b, b2-m_b, b3-m_b,....bn - m_b ]
3、分别相乘
c = [delta_a[0]*delta_b[0],delta_a[1]*delta_b[1],delta_a[2]*delta_b[2],....,delta_a[n]*delta_b[n]]
4、求出协方差值,c的所有值求和除以c的元素个数就可以求出协方差值了
conv = sum(c)/len(c)
验证代码:
也可以使用numpy的cov()方法
np.cov(a,b,ddof=0)[1][0]
0.4385294896030245
看不懂那个矩阵什么意思,不要紧,接着看协方差矩阵你就明白了。
6、求协方差矩阵
协方差Cov(X,Y)只能处理二维问题,比如女人颜值和男人的喜爱的相关度,如果要处理多维问题,就需要用到协方差矩阵了。
还是上一个例子的输入数据,只是a等于x, b =y=z,的数据完全相等,如下:
x=[ 0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88,
-0.04, 0.2 , 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.8 ,
-0.33, -0.24, -0.13, -0.82, 0.56]
y=[ 0.07, -0.55, -0.04, 3.11, 0.28, -0.5 , 1.1 , 1.97, -0.31,
-0.55, 2.06, -0.24, -1.44, 1.56, 3.69, 0.53, 2.3 , 1.09,
-2.63, 0.29, 1.3 , -1.54, 3.19]
z = [ 0.07, -0.55, -0.04, 3.11, 0.28, -0.5 , 1.1 , 1.97, -0.31,
-0.55, 2.06, -0.24, -1.44, 1.56, 3.69, 0.53, 2.3 , 1.09,
-2.63, 0.29, 1.3 , -1.54, 3.19]
每行23个数
协方差矩阵公式就是下面的写法
上一步对两组数据求协方差介绍了步骤,协方差矩阵就是按照上面矩阵模式两两求协方差,然后放到对应的位置
其中:
1、自身对自身的协方差为自身的方差(方差怎么求上面讲了的),即:cov(x,x) = var(x)
2、x对y的方差等于y对x的方差。即cov(x,y) = cov(y,x)
所以它有如下性质:
(1)协方差矩阵是一个对称阵;
(2)协方差矩阵的对角线上的元素是每个维度的方差;
(3)协方差矩阵计算的是一个样本中不同维度之间的协方差,而不是两个或多个样本之间的协方差。
代码验证上面性质猜想:
由上图可以看到上面的三个性质完全满足
7、数据中心化
样本矩阵中心化,即每一维度减去该维度的均值,使每一维度上的均值为0。
从几何意义来讲,矩阵中心化就是使得样本矩阵的中心回归到坐标系的原点。
注:数据中心化和数据标准化的目标区别
(1)对数据进行中心化预处理,这样做的目的是要增加基向量的正交性。
(2)对数据标准化的目的是消除特征之间的差异性。便于对一心一意学习权重。