相关分析与线性回归

相关系数

$Corr(X,Y)=\frac{Cov(X,Y)}{\sqrt{Var(X)Var(Y)}}$

协方差

$Cov(X,Y)=E((X-E(X))(Y-E(Y)))$

https://zhuanlan.zhihu.com/p/59550194

In [5]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats

上面的代码是为了引入python的函数包,其中pandas是一个处理数据的著名的库。numpy是python基础的库,包含了一些数学运算与数据间基础的处理函数。matplotlib.pyplot是一个画图的函数包,提供了许多诸如散点图、柱状图、折线图之类的画图工具。scipy.stats是一个统计工具包,提供了许多统计模型,我们第一部分的求相关系数就是用的这个函数包的功能。

需要注意的是,我们用的是“import xxx as xx”的形式,它的意思就是引入(import)xxx(函数包的名字)作为(as)xx(缩略名词),实际上它出现的意义就是我们懒,不想每次引用的时候把函数包那么长的名字都打一遍,所以给了它一个缩略词xx。

比如pandas的缩略词就是pd,以后我们想引用pandas这个函数包是就只需要用缩略词,我在下面给出了一个例子。

In [6]:
data_eco_citizen=pd.read_csv("https://raw.githubusercontent.com/Zhenz2020/Zhenz2020.github.io/main/Data_eco.csv")

上面这段代码的作用就是在一个网站上读取csv的数据,将他命名为data_eco_citizen,我们可以看到是是,我使用了"pd.read_csv",pd就是pandas这个函数包的缩略,read_csv就是pandas函数包包含的一个函数工具,就是读取csv文件(从英文上也可以显而易见的看出)"."在python里面的作用就是明确在“pd”(pandas)中取出“read_csv”这个函数工具

下面正式进入python相关分析的部分

In [7]:
data = pd.DataFrame(np.random.randn(200,2)*100, columns=['X','Y'])

上面代码的意思就是在pd(pandas)这个函数包里面用了DataFrame函数,它的作用就是把一组数据变成dataframe数据的形式,其中数据内容就是“np.random.randn(200,2)*100”,“columns=['X','Y']”顾名思义就是这个dataframe数据列的名字是X与Y,一共两列。

np.random.randn(200,2)*100这段代码的意思就是使用np(numpy)这个函数包下的random小工具包下面的randn函数,randn函数的作用就是生成一组随机的符合正态分布的数。在我们的代码中,就是生成200个2维的数据,并将这些数据乘以200。

最后将200个2维的以dataframe形式储存的符合正态分布的随机数储存到data这个变量中。

In [8]:
print(data)
              X           Y
0   -122.902604  237.577430
1     19.184870  107.616772
2    -49.583025 -115.763356
3    104.049007  170.974989
4     50.967095  -39.584779
..          ...         ...
195   37.980427   81.815656
196  192.184940  -98.648955
197  -97.554337 -166.067038
198 -178.703796  156.912358
199  -40.097073   47.094136

[200 rows x 2 columns]

上面的代码意思就是打印出data这个变量,注意,print前没有像上面的例子中使用xxx.print的形式,这是由于print函数是python自带的,无需加载其他函数包使用print

In [9]:
plt.scatter(data.iloc[:,0],data.iloc[:,1])
Out[9]:
<matplotlib.collections.PathCollection at 0x7fb2c4bc5910>

上面这段代码的意思就是画散点图,使用的就是plt函数包下面scatter这个函数,data.iloc[:,0]代表data这个数据的第一列,iloc是pandas的一个函数,作用就是定位,位置就是[:,0],中括号中逗号隔开,逗号前是行,逗号后是列,冒号‘:’代表所有行或者所有列(在逗号前就是所有行,在逗号后就是所有列),逗号后的0代表第一列,逗号后的1代表第二列,以此类推(python中数据是从0为起点的)。

所以上面代码的意思就是以data数据的第一列为x,第二列为y,画散点图。

In [10]:
r,p = stats.pearsonr(data.X,data.Y)  # 相关系数和P值
print('相关系数r为 = %6.3f,p值为 = %6.3f'%(r,p))
相关系数r为 =  0.093,p值为 =  0.189

上面代码就是求相关系数与其对应的p值。

使用的就是stats函数包下的pearsonr函数,pearsonr函数就是求的数据的pearsonr相关系数,其中data.X代表的就是data函数中名字为X的列,你可以在第八个代码print(data)中看到data的列名

关于相关系数与p值的解释,参见开头的链接

例一:居民消费水平与消费指数

In [ ]:
data_eco_citizen=pd.read_csv('/content/Data_eco.csv')
In [ ]:
print(data_eco_citizen)
    Level of household consumption  ...  Index of consumption levels of rural residents 
0                            27438  ...                                           1712.9
1                            27504  ...                                           1668.2
2                            25245  ...                                           1558.8
3                            22969  ...                                           1386.6
4                            20801  ...                                           1251.4
5                            18857  ...                                           1129.1
6                            17220  ...                                           1002.3
7                            15586  ...                                            903.9
8                            14074  ...                                            826.1
9                            12668  ...                                            764.0
10                           10575  ...                                            689.2
11                            9249  ...                                            654.0
12                            8505  ...                                            593.8
13                            7454  ...                                            566.8
14                            6319  ...                                            521.4
15                            5688  ...                                            485.8
16                            5071  ...                                            454.9
17                            4555  ...                                            437.7
18                            4270  ...                                            418.5
19                            3968  ...                                            392.7

[20 rows x 6 columns]
In [ ]:
plt.scatter(data_eco_citizen.iloc[:,2].values,data_eco_citizen.iloc[:,5].values)
# 农村居民消费水平和农村居民消费水平指数
Out[ ]:
<matplotlib.collections.PathCollection at 0x7f525a9d4c10>
In [ ]:
r,p = stats.pearsonr(data_eco_citizen.iloc[:,2].values,data_eco_citizen.iloc[:,5].values)  # 相关系数和P值
print('相关系数r为 = %6.3f,p值为 = %6.3f'%(r,p))
相关系数r为 =  0.999,p值为 =  0.000

例二:GDP与居民消费水平

In [ ]:
GDP=[1008782.5,983751.2,915243.5,830945.7,742694.1,685571.2,644380.2,588141.2,537329,483392.8,410354.1,347934.9,321229.5,270704,219028.5,185998.9,161415.4,136576.3,120480.4,109276.2]
In [ ]:
plt.scatter(GDP,data_eco_citizen.iloc[:,2].values)
Out[ ]:
<matplotlib.collections.PathCollection at 0x7f525a94ce90>
In [ ]:
r,p = stats.pearsonr(GDP,data_eco_citizen.iloc[:,2].values)
print('相关系数r为 = %6.3f,p值为 = %6.3f'%(r,p))
相关系数r为 =  0.986,p值为 =  0.000

例三:世界冠军与GDP

In [ ]:
World_champion=[3,33,27,24,23,25,22,22,24,24,22,30,24,22,24,22,27,17,99,79]
GDP=[1008782.5,983751.2,915243.5,830945.7,742694.1,685571.2,644380.2,588141.2,537329,483392.8,410354.1,347934.9,321229.5,270704,219028.5,185998.9,161415.4,136576.3,120480.4,109276.2]
In [ ]:
plt.scatter(GDP,World_champion)
Out[ ]:
<matplotlib.collections.PathCollection at 0x7f525a8cb8d0>
In [ ]:
r,p = stats.pearsonr(GDP,World_champion)
print('相关系数r为 = %6.3f,p值为 = %6.3f'%(r,p))
相关系数r为 = -0.425,p值为 =  0.062

中国国家数据开放平台

https://data.stats.gov.cn/index.htm

Gdp和建筑公司数量

In [ ]:
Number_of_architecture_companies=[116716,103805,96544,88074,83017,80911,81141,78919,75280,72280,71863,70817,71095,62074,60166,58750,59018,48688,47820,45893]
GDP=[1008782.5,983751.2,915243.5,830945.7,742694.1,685571.2,644380.2,588141.2,537329,483392.8,410354.1,347934.9,321229.5,270704,219028.5,185998.9,161415.4,136576.3,120480.4,109276.2]
plt.scatter(GDP,Number_of_architecture_companies)
Out[ ]:
<matplotlib.collections.PathCollection at 0x7f52566dc7d0>
In [ ]:
r,p = stats.pearsonr(GDP,Number_of_architecture_companies)
print('相关系数r为 = %6.3f,p值为 = %6.3f'%(r,p))
相关系数r为 =  0.966,p值为 =  0.000

线性回归

In [20]:
import numpy as np
import matplotlib.pyplot as plt

关于回归,使用的就是stats函数包下linregress函数,linspace(-5, 5, 100)函数的意思就是以-5为起点,5为终点,在其中均匀创建100个点,把这一百个点作为x的数据。

关于np.random.randn(y.shape[-1]),你们可以查一下它是什么意思

In [21]:
x = np.linspace(-5, 5, 100)
y = 4 * x + 1.5
noise_y = y + np.random.randn(y.shape[-1]) * 2.5
slope, intercept, r_value, p_value, std_err = stats.linregress(x,noise_y)
In [22]:
p=plt.plot(x,noise_y)
p=plt.plot(x,slope*x+intercept)

回归的一个例子

对GDP进行回归

In [11]:
GDP=[1008782.5,983751.2,915243.5,830945.7,742694.1,685571.2,644380.2,588141.2,537329,483392.8,410354.1,347934.9,321229.5,270704,219028.5,185998.9,161415.4,136576.3,120480.4,109276.2]
In [19]:
year=np.linspace(2020,2001,20)
Out[19]:
array([2020., 2019., 2018., 2017., 2016., 2015., 2014., 2013., 2012.,
       2011., 2010., 2009., 2008., 2007., 2006., 2005., 2004., 2003.,
       2002., 2001.])
In [18]:
slope, intercept, r_value, p_value, std_err = stats.linregress(year,GDP)
p=plt.plot(year,GDP)
p=plt.plot(year,slope*year+intercept)