數據特征—正態性檢驗


利用觀測數據判斷總體是否服從正態分布的檢驗稱為正態性檢驗,它是統計判決中重要的一種特殊的擬合優度假設檢驗。

正態分布

 

 

在實際數據分析過程中並不是所有數據都是滿足正態分布

並不是必須滿足正態分布才能分析

通過正太分布作為參考去理解事物規律

 

 

直方圖初判 / QQ圖判斷 / K-S檢驗

直方圖初判

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline
# 直方圖初判

s = pd.DataFrame(np.random.randn(1000)+10,columns = ['value'])
print(s.head())
# 創建隨機數據+10 就是μ往前+10

fig = plt.figure(figsize = (10,6))
ax1 = fig.add_subplot(2,1,1) # 創建子圖1
ax1.scatter(s.index, s.values)
plt.grid()
# 繪制數據分布圖

ax2 = fig.add_subplot(2,1,2) # 創建子圖2
s.hist(bins=30,alpha = 0.5,ax = ax2)
s.plot(kind = 'kde', secondary_y=True,ax = ax2)
plt.grid()
# 繪制直方圖
# 呈現較明顯的正太性

 

 

 

QQ圖判斷

QQ圖通過把測試樣本數據的分位數與已知分布相比較,從而來檢驗數據的分布情況

QQ圖是一種散點圖,對應於正態分布的QQ圖,就是由標准正態分布的分位數為橫坐標,樣本值為縱坐標的散點圖

參考直線:四分之一分位點和四分之三分位點這兩點確定,看散點是否落在這條線的附近

繪制思路

① 在做好數據清洗后,對數據進行排序(次序統計量:x(1)<x(2)<....<x(n))

② 排序后,計算出每個數據對應的百分位p{i},即第i個數據x(i)為p(i)分位數,其中p(i)=(i-0.5)/n (pi有多重算法,這里以最常用方法為主)

③ 繪制直方圖 + qq圖,直方圖作為參考

s = pd.DataFrame(np.random.randn(1000)+10,columns = ['value'])
print(s.head())

# 創建隨機數據 rand 就不是正態分布的

mean = s['value'].mean()
std = s['value'].std()
print('均值為:%.2f,標准差為:%.2f' % (mean,std))
print('------')

# 計算均值,標准差

s.sort_values(by = 'value', inplace = True) # 重新排序
s_r = s.reset_index(drop = False) # 重新排序后,更新index
s_r['p'] = (s_r.index - 0.5) / len(s_r)  
s_r['q'] = (s_r['value'] - mean) / std
print(s_r.head())
print('------')

# 計算百分位數 p(i)

# 計算q值

st = s['value'].describe()
x1 ,y1 = 0.25, st['25%']
x2 ,y2 = 0.75, st['75%']
print('四分之一位數為:%.2f,四分之三位數為:%.2f' % (y1,y2))
print('------')

# 計算四分之一位數、四分之三位數

fig = plt.figure(figsize = (10,9))
ax1 = fig.add_subplot(3,1,1) # 創建子圖1
ax1.scatter(s.index, s.values)
plt.grid()

# 繪制數據分布圖

ax2 = fig.add_subplot(3,1,2) # 創建子圖2
s.hist(bins=30,alpha = 0.5,ax = ax2)
s.plot(kind = 'kde', secondary_y=True,ax = ax2)
plt.grid()

# 繪制直方圖

ax3 = fig.add_subplot(3,1,3) # 創建子圖3
ax3.plot(s_r['p'],s_r['value'],'k.',alpha = 0.1)
ax3.plot([x1,x2],[y1,y2],'-r')
plt.grid()

# 繪制QQ圖,直線為四分之一位數、四分之三位數的連線,基本符合正態分布

 

 

KS檢驗

比較一個頻率分布f(x)與理論分布g(x)或者兩個觀測值分布的檢驗方法

樣本數據的累計頻數分布於特定的理論分布比較(比如正態分布),如果兩者差距小,則推論樣本分布取自某特定分布。

假設檢驗問題:

H0:樣本的總體分布 服從 某種特定分布

H1:樣本的總體分布 不服從 某特定分布

Fn(x)—樣本的累計分布函數

F0(x)—理論分布的分布函數

D —Fn(x)與F0(x) 差值的絕對值最大值

D = max |Fn(x)-F0(x)|

D>D(n,α) 相比較 —p>0.05 則接受H0,P<0.05則拒絕H0,接受H1

 

 代碼實現

data = [87,77,92,68,80,78,84,77,81,80,80,77,92,86,
      76,80,81,75,77,72,81,72,84,86,80,68,77,87,
      76,77,78,92,75,80,78]

# 樣本數據,35位健康男性在未進食之前的血糖濃度

df = pd.DataFrame(data, columns =['value'])
u = df['value'].mean()
std = df['value'].std()
print("樣本均值為:%.2f,樣本標准差為:%.2f" % (u,std))
print('------')

# 查看數據基本統計量

s = df['value'].value_counts().sort_index()
df_s = pd.DataFrame({'血糖濃度':s.index,'次數':s.values})

# 創建頻率數據

df_s['累計次數'] = df_s['次數'].cumsum()
df_s['累計頻率'] = df_s['累計次數'] / len(data)
df_s['標准化取值'] = (df_s['血糖濃度'] - u) / std
df_s['理論分布'] =[0.0244,0.0968,0.2148,0.2643,0.3228,0.3859,0.5160,0.5832,0.7611,0.8531,0.8888,0.9803] # 通過查閱正太分布表
df_s['D'] = np.abs(df_s['累計頻率'] - df_s['理論分布'])
dmax = df_s['D'].max()
print("實際觀測D值為:%.4f" % dmax)

# D值序列計算結果表格

df_s['累計頻率'].plot(style = '--k.')
df_s['理論分布'].plot(style = '--r.')
plt.legend(loc = 'upper left')
plt.grid()

# 密度圖表示
df_s

 

 

 

直接用算法做KS檢驗

from scipy import stats

# scipy包是一個高級的科學計算庫,它和Numpy聯系很密切,Scipy一般都是操控Numpy數組來進行科學計算

data = [87,77,92,68,80,78,84,77,81,80,80,77,92,86,
      76,80,81,75,77,72,81,72,84,86,80,68,77,87,
      76,77,78,92,75,80,78]

# 樣本數據,35位健康男性在未進食之前的血糖濃度

df = pd.DataFrame(data, columns =['value'])
u = df['value'].mean() # 計算均值
std = df['value'].std() # 計算標准差
stats.kstest(df['value'], 'norm', (u, std))

# .kstest方法:KS檢驗,參數分別是:待檢驗的數據,檢驗方法(這里設置成norm正態分布),均值與標准差

# 結果返回兩個值:statistic → D值,pvalue → P值

# p值大於0.05,為正態分布

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM