相關系數及顯著性檢驗

做課題需要分析PM2.5濃度變化的原因,準備將該變量作為研究對象,分析該變量與O3濃度、氣象變量之間的同期或前期關系。先看PM2.5和O3,如果相關關系顯著,則表明它們之間可能存在因果關系,之後就可以進一步地探索分析其是否存在物理化學機理上的關聯(如果二者相關關系不顯著,不要吧真的會瘋…)


準備知識:

1.什麼是相關系數和顯著性檢驗

根據相關現象間的不同特征(如變量的個數等),我們一般將反映兩變量間線性相關關系的統計量稱為相關系數;將反映兩變量間曲線相關關系的統計量稱為非線性相關系數;將反映多個變量之間的多元線性相關關系的統計量稱為復相關系數。

但實際我們是根據數據樣本計算得到的樣本相關系數r(這裡是2015-2022年的濃度數據),它隻是總體相關系數R的估計值。為瞭確定我們從樣本中所得到的是有效的統計結論,即結論是普適的、具有統計學意義的、對總體中任意一個樣本均適用,我們需要對結論進行顯著性檢驗,這可以通過計算結論所對應的p值實現。如果p≥0.05,則該相關結果無統計學意義,即可能隻是該樣本中存在這樣的相關關系,其他樣本中不一定成立;如果p<0.05,則稱為顯著相關;如果p<0.01,則稱為非常顯著相關。

但p值越小,兩個變量之間的相關性並不是越強,相關程度的強弱與顯著性檢驗的顯著程度是兩回事。相關程度的強弱需要看相關系數的絕對值大小,當絕對值|r|越接近1,表明相關程度越高。

2.常用的相關系數

Pearson相關系數

該相關系數是由卡爾·皮爾遜在前人的研究基礎上所提出的相關統計量,可以用來度量兩個變量之間的簡單線性關系。它的計算公式如下:

通過該公式計算得到的相關系數r,取值范圍為[-1,1]。

  • 當r=0時,表明兩個變量X和Y之間無線性關系(註意並不代表X和Y一定相互獨立,可能存在非線性等其他關系);
  • 當0<r<1時,表明兩個變量X和Y之間存在正相關關系;
  • 當-1<r<0時,表明兩個變量X和Y之間存在負相關關系。

由於Pearson相關系數的形式簡單,因此其應用十分廣泛。但其也存在缺點,即:

  • 該相關系數隻能識別簡單的線性相關關系,無法處理非線性相關關系;
  • 對異常值(或離群點)和樣本容量較為敏感;
  • 要求研究的變量是數值變量,且變量符合或較為接近正態分佈。

一般認為,相關系數在 0-0.2 之間不相關或極弱相關,0.2-0.4 之間弱相關,0.4-0.6 之間中等相關,0.6-0.8 之間強相關,0.8-1 極強相關

常用 t 檢驗來檢驗Pearson相關系數的顯著性:

其中,n 為樣本個數,r 為相關系數,t 為檢驗值。可以看到,當樣本量 n 越大時,達到顯著相關的相關系數 r 就越小,因此當樣本量較大時,由於樣本數據的差異性,相關系數一般不會很高,但是顯著性檢驗卻可以認為兩組樣本數據相關性顯著,一般常用的顯著性檢驗水平為 0.05(顯著相關)和 0.01(極顯著相關)。

Spearman相關系數

上文提到Perason相關系數無法識別非線性關系,並且存在對一個或幾個離群(異常)點極為敏感的局限性。Spearman相關系數與可以作為Pearson相關系數的替代方法。它可以用來衡量兩個變量間是否存在單調相關關系,計算公式如下(其中Di是第i對數據之間秩的差值):

通過該公式計算得到的相關系數ρ,取值范圍為[-1,1]。

  • 當一個變量隨另一個變量單調遞減時,ρ=-1;
  • 當一個變量隨另一個變量單調遞增時,ρ=1。

Spearman相關系數有時也稱為“等級相關系數”。

相對於Pearson相關系數的優點:

  • 使用條件沒有Pearson相關系數那麼嚴格,隻要兩個變量的值是成對的等級數據(即原始數據經過排序後的等級或順序值),或者是經由連續變量轉化得到的等級數據,就可以用上述 Spearman 相關系數的公式進行計算,分析這兩個變量之間是否存在單調相關關系。
  • 與變量的分佈和樣本容量都沒有關系,並且計算結果對個別異常值不敏感。所以能夠適用於較多場景。

具體選擇哪種相關系數需要根據所使用到的數據來決定


import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr #進行Pearson相關系數計算的包
from scipy.stats import normaltest #檢驗數據是否符合正態分佈的包
df1=pd.read_csv(r"E:thesispnightmean.csv")
df2=pd.read_csv(r"E:thesisonightmean.csv")
df =pd.merge(df1,df2,on="day")
df["year"]=pd.DatetimeIndex(df["day"]).year
df["month"]=pd.DatetimeIndex(df["day"]).month
df.columns=["date","pm25","o3","year","month"]
df=df[df["month"]==10]
Year=[2015,2016,2017,2018,2019,2020,2021,2022]
fig = plt.figure(figsize=(16,10))
for i,year in enumerate(Year):
ax=fig.add_subplot(4,2,i+1)
df3=df[df["year"]==year]
df3.drop(["year","month"],axis=1)
print(normaltest(df3["pm25"]))
print(normaltest(df3["o3"]))
r,p=pearsonr(df3["pm25"],df3["o3"])
# print('r=',np.round(r,3),'p=',np.round(p,3))
ax.text(0.1, 0.9, r"r=%.3f,p=%.4f" %(r,p),fontsize=14,transform = ax.transAxes)
ax.plot(df3["date"],df3["pm25"],marker="o")
ax.plot(df3["date"],df3["o3"],marker="o")
ax.title.set_text("%s" %year)
ax.set_xticklabels(np.arange(1,32,1))
fig.suptitle("Oct",fontsize=16)
plt.tight_layout()
plt.savefig(r"E:thesistuOct.svg")

赞(0)