熱線電話:13121318867

登錄
首頁大數據時代【教程】30000字長文,手把手教你用Python實現統計學
【教程】30000字長文,手把手教你用Python實現統計學
2025-02-27
收藏

1.統計學簡介

聽說你已經被統計學勸退,被Python唬住……先別著急劃走,看完這篇再說!

先說結論,大多數情況下的學不會都不是知識本身難,而是被知識的傳播者勸退的。

比如大佬們授課,雖邏輯嚴謹、思維縝密,但你只能望其項背,因為大佬們往往無法體會菜鳥的痛苦。再比如一些照本宣科的老師,他們沒有深入研究這些知識,無法用通俗的語言幫你解釋,只能貌似努力地幫你認真地讀完所有PPT……

究其本質而言,這種情況多半是按 “是什么、有什么用,怎么用” 的方式在學,而對在大多數人而言,第一步就學懂“是什么”,或許難度有點大,因為得從定義出發,了解性質,推導出原理,一套流程下來直接勸退了,反而最關心的有什么用、怎么用的問題沒有解決。

所以接下來的內容我將用“MVP(最小可行化產品)” 的思路來篩選重點內容,幫你厘清哪些內容是不可或缺及必須要學的。然后以 “有什么用,怎么用,是什么” 的順序展開,快速提升當你急需Get某個技能時候的學習效率。

另外教程的標題既然含有“極簡入門”,那么至少有2個原則:

  • 盡量不廢話
  • 盡量說人話

說“盡量”是因為有些時候,不得不說些廢話才能引起你的注意,比如以上內容…

好,我們正式開始!首先來看第一個問題:

1. 數據的種類

我們都知道,一般數據可以分為兩類,即定性數據(類別型數據)定量數據(數值型數據)

(1). 定性數據, 表示研究對象的類別。很好理解,這里的表示類別用的數字沒有大小之分,不能進行算術四則運算。

定性數據可以分為:

① 定類數據
表現為類別,但不區分順序,是由定類尺度計量形成的。一般可以從非數值型數據中編碼轉換而來,數值本身沒有意義,只是為了區分類別做出的數值型標識

例如性別用1代表男性,用2代表女性;血型用1,2,3,4來表示A、B、AB及O四種;

② 定序數據
表現為類別,但有順序,是由定序尺度計量形成的。運算符也沒有意義,

例如受教育程度用 文盲 = 1,半文盲 = 2,小學 = 3,初中 =4,高中 = 5,大專 = 6,本科 = 7,(研究生)碩士 = 8,(研究生)博士 = 9表示。

(2). 定量數據, 表示的是研究對象的數量特征,如人群中人的身高、體重等。

定量數據可以分為以下幾種:

① 定距數據
表現為數值,可進行加、減運算,是由定距尺度計量形成的。定距數據的特征是沒有絕對的零點,例如溫度,不能說10攝氏度的一倍是20攝氏度。因此乘、除法對于定距數據來說也是沒有意義的。

② 定比數據
表現為數值,可進行加、減、乘、除運算,是由定比尺度計量形成的。定比數據存在絕對的零點。例如價格,100元的2倍就是200元。

2. 什么是統計學

先看一個例子,這里有一組數據 2,23,4,17,12,12,13,16,請思考你要怎么描述它?

你可能會說他們的平均數是12.375,中位數是12.5,最大值是23,最小值是2,等等。

沒錯,這里其實你已經在用平均數、中位數、最大值、最小值的來描述這組數據。

那么用幾個數來描述一堆數就是統計學的基本概念:統計學是一門將 數據匯總為統計量或圖表的學問。

Tips:通俗來說就是,數據太多記不住且不好描述,需要簡化為更少的數字或圖表,于是有了統計學和統計圖表

知道了統計學的定義再接著看:

3. 統計學的知識體系是什么樣的?

通常我們把統計學分為兩大方向,通過計算出來的統計量來概括已有數據叫做描述統計學,通過樣本獲取總體特征的叫做推斷統計學

Tips:“算”出來的統計量,比如 中位數、平均值、眾數 這些;“猜”出來的叫推斷統計學,比如通過樣本數據來推斷總體的數字特征。

下面這張圖展示了統計學兩大分支:描述統計與推斷統計。其中推斷統計又分兩大學派,頻率學派與貝葉斯學派。這些內容大家先知道就行,后面再展開。

2. 描述性統計

上一篇介紹了數據的分類、統計學是什么、以及統計學知識的大分類,本篇我們重點學習描述性統計學。

我們描述一組數據的時候,通常分三個方面描述:集中趨勢、離散趨勢、分布形狀。通俗來說,集中趨勢是描述數據集中在什么位置,離散趨勢描述的是數據分散的程度,分布形狀描述的是數據形狀。

首先,來看描述數據的集中趨勢,使用的三個常見的統計量:

平均數

  • 算術平均數 算術平均數是n個數求和后除以n得到的結果。廣泛應用于各個領域,用于描述和分析數據的平均水平和集中趨勢

Excel求算術平均數的函數=AVERAGE(A1:A8)

PS:聰明的你肯定知道把上面8個數據 2,23,4,17,12,12,13,16,用左手復制到你Excel中的A1:A8單元格(記得豎著放?。?/p>

用Python求算術平均數

## 使用 numpy 庫里的 mean 函數
import numpy as np
data =  [2,23,4,17,12,12,13,16]
print(np.mean(data))
# 12.375
  • 幾何平均數 幾何平均數就是n個數乘積的n次方根。在金融財務、投資和銀行業的問題中,幾何平均數的應用尤為常見。當你任何時候想確定過去幾個連續時期的平均變化率時,都能應用幾何平均數。其他通常的應用包括物種總體、農作物產量、污染水平以及出生率和死亡率的變化。(在第8節案例8.1中會舉例說明)。 公式如下:

Excel求幾何平均數的函數=GEOMEAN(A1:A8)

用Python求幾何平均數

# 使用 scipy 庫里的 gmean 函數求幾何平均數
from scipy import stats as sts
data = [2,23,4,17,12,12,13,16]
print(sts.gmean(data))
# 9.918855683110795
  • 調和平均數

n個數的倒數的算術平均數的倒數

Excel求調和平均數的函數=HARMEAN(A1:A8)

Python求調和平均數

# 使用 scipy 庫里的 hmean 函數求調和平均數
from scipy import stats as sts
data = [2,23,4,17,12,12,13,16]
print(sts.hmean(data))
# 6.906127821278071

還沒看暈吧?我們小結一下,三者的大小排序一般是算術平均值 ≥ 幾何平均值 ≥ 調和平均值。另外 數值類數據的均值一般用算術平均值,比例型數據的均值一般用幾何平均值,平均速度一般用調和平均數

中位數

中位數是把數據按照順序排列,處于中間位置的那個數

Excel求中位數的函數=MEDIAN(A1:A8)

Python求中位數

# 使用 numpy 庫里的 median 函數求中位數
import numpy as np
data =  [2,23,4,17,12,12,13,16]
print(np.median(data))
# 12.5

眾數

眾數是一組數據中出現次數最多的變量值。

Excel求眾數的函數=MODE(A1:A8)

Python求眾數

# 使用 scipy 庫里的 mode 函數求眾數
from scipy import stats as sts
data =  [2,23,4,17,12,12,13,16]
print(sts.mode(data))
# ModeResult(mode=array([12]), count=array([2]))

以上便是描述數據集中趨勢的幾個統計量,接下來我們來看描述數據離散趨勢的統計量:

分位數

四分位數用3個分位數,將數據等分成4個部分。這3個四分位數,分別位于這組數據升序排序后的25%、50%和75%的位置上。另外,75%分位數與25%分位數的差叫做四分位距。

Excel求分位數的函數=QUARTILE(A1:A8,1) ,括號里面的參數:0代表最小值,1代表25%分位數,2代表50%分位數,3代表75%分位數,4代表最大值,

Python求該組數據的下四分位數與上四分位數

from scipy import stats as sts  
data =  [2,23,4,17,12,12,13,16]
print(sts.scoreatpercentile(data,25)) #25分位數
print(sts.scoreatpercentile(data,75)) #75分位數
10.0
16.25

補充一點,關于描述性統計部分的圖表可視化,本系列教程不做展開,唯一值得一提的是箱線圖,不論是描述數據、還是判斷異常都是你應該掌握的數據分析利器(在第8節案例8.2中會詳細舉例說明)這里先簡單舉例如下

用四分位數繪制的箱線圖

import seaborn as sns
data = [2,23,4,17,12,12,13,16]
# 使用sns.boxplot()函數繪制箱線圖
sns.boxplot(data=data)

箱線圖可以很直觀地看到:數據的最大值、最小值、以及大部分數據集中在什么區間。

具體來說就是: 異常值、上邊緣 Q3+1.5(Q3-Q1)、上四分位數 Q3、中位數 Q2 下四分位數 Q1、下邊緣 Q1-1.5(Q3-Q1)

  • 極差

極差又稱范圍誤差或全距,是指一組數據中最大值與最小值的差

Excel求極差的函數=MAX(A1:A8) - MIN(A1:A8)

Python 求極差

import numpy as np
data =  [2,23,4,17,12,12,13,16]
print(np.ptp(data))
# 21
  • 四分位距

四分位距是上四分位數與下四分位數之差,一般用表示

Excel求分位數的函數=QUARTILE(A1:A8,3)-QUARTILE(A1:A8,1) Python 求四分位距

from scipy import stats as sts
data =  [2,23,4,17,12,12,13,16]
print(sts.scoreatpercentile(data,75)-sts.scoreatpercentile(data,25))
# 6.25

方差

方差是一組數據中的各數據值與該組數據算術平均數之差的平方的算術平均數。

Excel求方差的函數=VAR(A1:A8)

Python求方差

from scipy import stats as sts
data =  [2,23,4,17,12,12,13,16]
print(sts.tvar(data,ddof = 1))# ddof=1時,分母為n-1;ddof=0時,分母為n
#46.55357142857143

標準差

標準差方差的開方??傮w標準差常用σ表示,樣本標準差常用S表示。 Excel求方差的函數=STDEV(A1:A8) Python求標準差:

from scipy import stats as sts
data = [2,23,4,17,12,12,13,16]
print(sts.tstd(data,ddof = 1))# ddof=1時,分母為n-1;ddof=0時,分母為n
# 6.823017765517794

變異系數

對不同變量或不同數組的離散程度進行比較時,如果它們的平均水平和計量單位都相同,才能利用上述指標進行分析,否則需利用變異系數來比較它們的離散程度。

變異系數又稱為離散系數,是一組數據中的極差、四分位差或標準差等離散指標與算術平均數的比率。

Excel求變異系數的函數=STDEV(A1:A8)/AVERAGE(A1:A8)

Python求標準差變異系數:

from scipy import stats as sts
data = [2,23,4,17,12,12,13,16]
print(sts.tstd(data)/sts.tmean(data))
# 0.5513549709509329

看完了描述數據離散程度的幾個統計量,我們接著看描述數據分布形狀的偏度和峰度:

偏度

偏度系數是對分布偏斜程度的測度,通常用SK表示。偏度衡量隨機變量概率分布的不對稱性,是相對于平均值不對稱程度的度量。

當偏度系數為正值時,表示正偏離差數值較大,可以判斷為正偏態或右偏態;反之,當偏度系數為負值時,表示負偏離差數值較大,可以判斷為負偏態或左偏態。偏度系數的絕對值越大,表示偏斜的程度就越大。

Excel求偏度的函數=SKEW(A1:A8)

Python如何求偏度:

from scipy import stats as sts
data = [2,23,4,17,12,12,13,16]
print(sts.skew(data,bias=False)) # bias=False 代表計算的是總體偏度,bias=True 代表計算的是樣本偏度
# -0.21470003988916822

峰度

峰度描述的是分布集中趨勢高峰的形態,通常與標準正態分布相比較。在歸一化到同一方差時,若分布的形狀比標準正態分布更“瘦”、更“高”,則稱為尖峰分布;若比標準正態分布更“矮”、更“胖”,則稱為平峰分布。

峰度系數是對分布峰度的測度,通常用K表示:

由于標準正態分布的峰度系數為0,所以當峰度系數大于0時為尖峰分布,當峰度系數小于0時為平峰分布。

Excel求峰度的函數=KURT(A1:A8)

Python如何求峰度:

from scipy import stats as sts
data = [2,23,4,17,12,12,13,16]
print(sts.kurtosis(data,bias=False)) # bias=False 代表計算的是總體峰度,bias=True 代表計算的是樣本峰度
# -0.17282884047242897

3. 數據分布

t分布、F分布卡方分布是統計學中常用的三種概率分布,它們分別用于樣本均值的推斷、方差的比較和數據的擬合優度檢驗。

總之這3個分布很有用,首次接觸你可能理解不了,但沒關系你知道很重要就行了,接著往下看,我們在介紹三大分布之前,先看一下正態分布和標準正態分布

正態分布(Normal Distribution)

正態分布也被稱為高斯分布,是統計學中最常見的概率分布之一。

正態分布具有鐘形曲線的特征,均值和標準差是其兩個重要的參數。

import numpy as np
import seaborn as sns

mean = 3  # 均值
std = 4  標準差
size = 1000  # 生成1000個隨機數

data = np.random.normal(mean, std, size=size)
sns.histplot(data, kde=True)

標準正態分布(Standard Normal Distribution)

標準正態分布是一種特殊的正態分布,其均值為0,標準差為1。在統計學中,標準正態分布經常用于標準化數據或進行假設檢驗。

import numpy as np
import seaborn as sns

size = 1000  # 生成1000個隨機數

data = np.random.standard_normal(size=size)
sns.histplot(data, kde=True)

t分布(t Distribution)

t分布是一種概率分布,用于小樣本情況下對總體均值的推斷。當樣本容量較小或總體方差未知時,使用T分布進行推斷更準確。T分布的形狀類似于正態分布,但尾部較寬。T分布的自由度(degrees of freedom)決定了其形狀。

import numpy as np
import seaborn as sns

df = 10  # 自由度
size = 1000  # 生成1000個隨機數

data = np.random.standard_t(df, size=size)
sns.histplot(data, kde=True)

F分布(F Distribution)

F分布是一種概率分布,用于比較兩個樣本方差的差異。F分布常用于方差分析和回歸分析中。F分布的形狀取決于兩個自由度參數,分子自由度和分母自由度。

import numpy as np
import seaborn as sns

dfn = 5  # 分子自由度
dfd = 10  # 分母自由度
size = 1000  # 生成1000個隨機數

data = np.random.f(dfn, dfd, size=size)
sns.histplot(data, kde=True)

卡方分布(Chi-Square Distribution)

卡方分布是一種概率分布,用于檢驗觀察值與理論值之間的擬合優度。卡方分布常用于擬合優度檢驗、獨立性檢驗中。卡方分布的自由度參數決定了其形狀。

import numpy as np
import seaborn as sns

df = 5  # 自由度
size = 1000  # 生成1000個隨機數

data = np.random.chisquare(df, size)
sns.histplot(data, kde=True)

番外篇:三大分布互相推導

注:本節作為延伸閱讀,初學者簡單了解即可

十九世紀中葉至二十世紀初,有三位統計學屆杰出代表: 皮爾遜( Pearson) 、戈塞特( Gosset) 、費希爾( Fisher) 表,他們是統計學三大分布的始創者。

  • 皮爾遜(Pearson) 在創立擬合優度理論的過程中發現了 分布;

  • 戈塞特( Gosset) 發現 分布的過程正是 小樣本理論 創立的過程;

  • 費希爾( Fisher) 在創立 方差分析 理論的過程中發現了 分布。

這便是著名的三大抽樣分布包括: 分布、 分布和 分布

分布是由個相互獨立的標準正態分布 的平方和確定的分布,記作 ~ ,即

分布的分子是一個 ,分母是自由度為 分布與自由度 的比值再開方確定的分布,記作 ~ ,即

分布是由兩個 分布與其自由度比值的比值確定的分布 ,記 作 ~ ,即

三大分布的推導

三大分布的推導例題

4. 區間估計

還以為你被上節課的內容唬住了~終于等到你,還好沒放棄!

本節我們將說明兩個問題:總體均值 的區間估計總體比例 的區間估計。

區間估計經常用于質量控制領域來檢測生產過程是否正常運行或者在“控制之中” ,也可以用來監控互聯網領域各類數據指標是否在正常區間。

一個總體均值的區間估計

  • 大樣本的情況下

    • 已知,

    • 未知,

  • 小樣本的情況下

    • 已知,
    • 未知,

另外補充一個公式,樣本量 這個了解就好,大部分情況下是不缺數據的,盡可能選數據量稍大些的數據。

把以上過程編寫成Python的自定義函數:

import numpy as np
import scipy.stats
from scipy import stats as sts


def mean_interval(mean=None, sigma=None,std=None,n=None,confidence_coef=0.95):
    """
    mean:樣本均值
    sigma: 總體標準差
    std: 樣本標準差
    n:   樣本量
    confidence_coefficient:置信系數
    confidence_level:置信水平 置信度
    alpha:顯著性水平
    功能:構建總體均值的置信區間
    """

    alpha = 1 - confidence_coef
    z_score = scipy.stats.norm.isf(alpha / 2)            # z分布臨界值
    t_score = scipy.stats.t.isf(alpha / 2, df = (n-1) )  # t分布臨界值
   
    if n >= 30
        if sigma != None:
            me = z_score * sigma / np.sqrt(n)
            print("大樣本,總體 sigma 已知:z_score:",z_score)
        elif sigma == None:
            me = z_score * std / np.sqrt(n)
            print("大樣本,總體 sigma 未知 z_score",z_score)
        lower_limit = mean - me
        upper_limit = mean + me
    if n < 30 :
        if sigma != None:
            me = z_score * sigma / np.sqrt(n)
            print("小樣本,總體 sigma 已知 z_score * sigma / np.sqrt(n) n z_score = ",z_score)
        elif sigma == None:
            me = t_score * std / np.sqrt(n)
            print("小樣本,總體 sigma 未知 t_score * std / np.sqrt(n) n t_score = ",t_score)
            
        print("t_score:",t_score)
        lower_limit = mean - me
        upper_limit = mean + me
    
    return (round(lower_limit, 1), round(upper_limit, 1))
應用:網站流量UV區間估計:

某網站流量UV數據如下[52,44,55,44,45,59,50,54,62,46,54,42,60,62,43,42,48,55,57,56],我們研究一下該網站的總體流量uv均值,我們先把數據放進來

import numpy as np
data = np.array([52,44,55,44,45,59,50,54,62,46,54,42,60,62,43,42,48,55,57,56])

計算一下均值為:

x_bar = data.mean()
x_bar
# 51.5

樣本標準差為:

x_std = sts.tstd(data,ddof = 1) #  ddof=1時,分母為n-1;ddof=0時,分母為n
x_std
# 6.840283158189472

進行區間估計:

mean_interval(mean=x_bar, sigma=None,std= x_std,  n=n, confidence_coef=0.95)

輸出結果:

小樣本,總體 sigma 未知 t_score * std / np.sqrt(n) 
t_score =  2.093024054408263
(48.3, 54.7)

于是我們有95%的把握,該網站的流量uv介于 [48, 55]之間。

值得一提的是,上面這個案例的數據是實際上是公眾號山有木兮水有魚 的按天統計閱讀量……有人可能要說了,你這數據也太慘了,而且舉個案例都是小樣本。我想說,小樣本的原因是這新號一共發了也沒幾天,至于數量低,你幫忙動動小手轉發轉發,這數據也就高了~希望下次舉例的時候這個能變成大樣本,均值怎么著也得個千兒八百的,感謝感謝!

一個總體比例的區間估計

其中樣本量

def proportion_interval(p=None, n=None, confidence_coef =0.95):
    """
    p: 樣本比例
    n: 樣本量
    confidence_coef: 置信系數
    功能:構建總體比例的置信區間
    """

    alpha = 1 - confidence_coef
    z_score = scipy.stats.norm.isf(alpha / 2)  # z分布臨界值
    
    me = z_score * np.sqrt((p * (1 - p)) / n) 
    lower_limit = p - me
    upper_limit = p + me
    
    return (round(lower_limit, 3), round(upper_limit, 3))

5. 假設檢驗

久經考場的你肯定對于很多概念類題目里問到的 “區別和聯系” 不陌生,與之類似,在統計領域要研究的是數據之間的區別和聯系 ,也就是差異性分析相關性分析。本節我們重點關注數據的差異性分析。

我們知道,比較兩個數之間的大小,要么前后兩者求差,要么求比。差值大于零說明前者大于后者。比值大于1說明分子大于分母。

那么如何比較兩組數據的差異性呢?大道至簡,其實和上面原理類似

我們先從簡單的看起,先比較一組數和一個給定數的差異,即,單個總體的差異性分析:

單個總體的假設檢驗

常見的單個總體差異性的假設檢驗分為3個類型:均值、比例、方差

一個總體均值的假設檢驗 (指定值和樣本均值)

顧名思義,就是檢驗指定值與樣本均值的差異,按是否已知可以分2種情況:

已知的情況: 檢驗

接下來我們用代碼舉例實現一下你就明白怎么用了:

例5.1 檢驗一批廠家生產的紅糖是否夠標重

監督部門稱了50包標重500g的紅糖,均值是498.35g,少于所標的500g。對于廠家生產的這批紅糖平均起來是否夠份量,需要統計檢驗。

分析過程: 由于廠家聲稱每袋500g,因此原假設為總體均值等于500g(被懷疑對象總是放在零假設)。而且由于樣本均值少于500g(這是懷疑的根據),把備擇假設設定為總體均值少于500g (上面這種備選假設為單向不等式的檢驗稱為單側檢驗,而備選假設為不等號“”的稱為雙側檢驗,后面會解釋)

于是我們有了原假設和備擇假設

:

引入相關庫、讀取數據如下

from scipy import stats
import scipy.stats
import numpy as np
import pandas  as pd
import statsmodels.stats.weightstats

data = [493.01,498.83,494.16,500.39,497.63,499.72,493.41,498.97,501.94,503.45,497.47,494.19,500.99,495.81,499.63,494.91,498.90,502.43,491.34,497.50,505.95,496.56,501.66,492.02,497.68,493.48,505.40,499.21,505.84,499.41,505.65,500.51,489.53,496.55,492.26,498.91,496.65,496.38,497.16,498.91,490.98,499.97,501.21,502.85,494.35,502.96,506.21,497.66,504.66,492.11]

進行z檢驗:

z, pval = statsmodels.stats.weightstats.ztest(data, value=500,alternative = 'smaller')

# 'two-sided': 樣本均值與給定的總體均值不同
# 'larger' :   樣本均值小于給定總體均值
# 'smaller' :  樣本均值大于給定總體均值
print(z,pval)
# -2.6961912076362085 0.0035068696715304876

結論: 選擇顯著性水平 0.05 的話,P=0.0035 < 0.05, 故應該拒絕原假設。具體來說就是該結果傾向于支持平均重量小于500g的備則假設。

未知的情況: 檢驗

例5.2 檢驗汽車實際排放是否低于其聲稱的排放標準

汽車廠商聲稱其發動機排放標準的一個指標平均低于20個單位。在抽查了10臺發動機之后,得到下面的排放數據: 17.0 21.7 17.9 22.9 20.7 22.4 17.3 21.8 24.2 25.4 該樣本均值為21.13.究竟能否由此認為該指標均值超過20?

分析過程: 由于廠家聲稱指標平均低于20個單位,因此原假設為總體均值等于20個單位(被懷疑對象總是放在零假設)。而且由于樣本均值大于20(這是懷疑的根據),把備擇假設設定為總體均值大于20個單位

于是我們有了原假設和備擇假設

:

讀取數據如下

data = [17.021.717.922.920.722.417.321.824.225.4]

進行t檢驗如下:

import scipy.stats
t, pval = scipy.stats.ttest_1samp(a = data, popmean=20,alternative = 'greater')
# 說明  
# a  為給定的樣本數據
# popmean 為給定的總體均值
# alternative 定義備擇假設。以下選項可用(默認為“two-sided”):
# ‘two-sided’:樣本均值與給定的總體均值(popmean)不同
# ‘less’:樣本均值小于給定總體均值(popmean)
# ‘greater’:樣本均值大于給定總體均值(popmean)

print(t, pval)

# '''
# P= 0.004793 < 5%, 拒絕原假設,接受備擇假設樣本
# '''

結論: 選擇顯著性水平 0.01 的話,P=0.1243 > 0.05, 故無法拒絕原假設。具體來說就是該結果無法支持指標均值超過20的備則假設。

一個總體比例的假設檢驗(指定比例和樣本比例)

例5.3 檢驗高爾夫球場女性球員比例是否因促銷活動而升高

某高爾夫球場去年打球?????????的人當中有20%是女性,為了增加女性球員的比例,該球場推出了一項促銷活動來吸引更多的女性參加高爾夫運動,在活動實施了1個月后,球場的研究者想通過統計分析研究確定高爾夫球場的女性球員比例是否上升,收集到了400個隨機樣本,其中有100是女性

分析過程: 由于研究的是女性球員所占的比例是否上升,因此選擇上側檢驗比較合適,備擇假設是比例大于20%

:

方法1:用statsmodels.stats.proportion里面的proportions_ztest函數計算(推薦)

import numpy as np
from statsmodels.stats.proportion import proportions_ztest
count = 100
nobs = 400
p_0 = 0.2
p_bar = count/nobs
p_0 = 0.2
n = 400
# 執行單一樣本比例檢驗 statsmodels.stats.proportion.proportions_ztest
z_statistic, p_value = proportions_ztest(count, nobs, value = p_0,alternative='larger',prop_var = value)
# 注:statsmodels.stats.proportion.proportions_ztest 的函數有幾個問題:講在第八節之后說明,感興趣的讀者請持續關注
# 打印結果
print("z統計量:", z_statistic)
print("p值:", p_value)
#z統計量: 2.4999999999999996
#p值: 0.006209665325776138

方法2 用手動方式計算

count = 100
nobs = 400
p_0 = 0.2

p_bar = count/nobs
p_0 = 0.2
n = 400
def calc_z_score(p_bar, p_0, n):
    z = (p_bar - p_0) / (p_0 * (1 - p_0) / n)**0.5
    return z

z = calc_z_score(p_bar, p_0, n)
p = stats.norm.sf(z)

# 打印結果
print("z統計量:", z)
print("p值:", p)
# z統計量: 2.4999999999999996
# p值: 0.006209665325776138

結論: 選擇顯著性水平 0.05 的話,P=0.0062 < 0.05, 拒絕原假設。具體來說就是該結果支持特定的促銷活動能夠提升該球場女性運動員比例的備則假設。

一個總體方差假設檢驗(指定方差和樣本方差

import numpy as np
from scipy import stats

def chi2test(sample_var, sample_num,sigma_square,side, alpha=0.05):
    '''
    參數:
    sample_var--樣本方差
    sample_num--樣本容量
    sigma_square--H0方差
    返回值:
    pval
    '
''
    chi_square =((sample_num-1)*sample_var)/(sigma_square)
    p_value = None
    if side == 'two-sided':
        p = stats.chi2(df=sample_num-1).cdf(chi_square)
        p_value = 2*np.min([p, 1-p])
    elif side == 'less':
        p_value = stats.chi2(df=sample_num-1).cdf(chi_square)
    elif side == 'greater':
        p_value = stats.chi2(df=sample_num-1).sf(chi_square)
    return chi_square,p_value

例5.4 檢驗公交車到站時間的方差是否比規定標準大

某市中心車站為規范化提升市民對于公交車到站時間的滿意度,對于公交車的到站時間管理做了規定,標準是到站時間的方差不超過4。為了檢驗時間的到站時間的方差是否過大,隨機抽取了24輛公交車的到站時間組成一個樣本,得到的樣本方差,假設到站時間的總體分布符合正態分布,請分析總體方差是否過大。

分析過程: 由于研究的是方差是否過大,因此選擇上側檢驗比較合適,備擇假設是方差大于4

于是我們有了原假設和備擇假設

:

chi_square,p_value = chi2test(sample_var = 4.9, sample_num = 24, sigma_square = 4,side='greater')

print("p值:", p_value)
# p值: 0.2092362676676498

結論: 選擇顯著性水平 0.05 的話,P=0.2092 > 0.05, 無法拒絕原假設。具體來說就是該結果不支持方差變大的備則假設。

例5.5 檢驗某考試中心升級題庫后考生分數的方差是否有顯著變化

某數據分析師認證考試機構CDA考試中心,歷史上的持證人考試分數的方差,現在升級了題庫,該考試中心希望新型考題的方差保持在原有水平上,為了研究該問題,收集到了30份新考題的考分組成的樣本,樣本方差,在 的顯著性水平下進行假設檢驗。

分析過程:由于目標是希望考試分數的方差保持原有水平,因此選擇雙側檢驗

于是我們有了原假設和備擇假設

:

p_value = chi2test(sample_var = 162, sample_num = 30, sigma_square = 100,side='two-sided')

print("p值:", p_value)
# p值: 0.07213100536907469

結論: 選擇顯著性水平 0.05 的話,P=0.0721 > 0.05, 故無法拒絕原假設。具體來說就是不支持方差發生了變化的備則假設。

兩個總體的假設檢驗

常見的兩總體差異性的假設檢驗也分3個類型:均值、比例、方差

兩總體均值之差的假設檢驗(獨立樣本)

例5.6(數據:drug.txt) 檢驗某藥物在實驗組的指標是否低于對照組

為檢測某種藥物對情緒的影響,對實驗組的100名服藥者和對照組的150名非服藥者進行心理測試,得到相應的某指標。需要檢驗實驗組指標的總體均值是否大于對照組的指標的總體均值。這里假定兩個總體獨立地服從正態分布。相應的假設檢驗問題為:

分析過程:由于目標是檢驗實驗組指標的總體均值是否大于對照組的指標的總體均值,因此選擇上側檢驗

于是我們有了原假設和備擇假設

:

data = pd.read_table("./t-data/drug.txt",sep = ' ')
data.sample(5)
ah id
4.4 2
6.8 2
9.6 2
4.8 2
13.2 1
a = data[data['id']==1]['ah']
b = data[data['id']==2]['ah']
'''
H0: 實驗組的均值等于對照組
H1: 實驗組的均值大于對照組

'''

t, pval = scipy.stats.ttest_ind(a,b,alternative = 'greater')
print(t,pval)
# 0.9109168350628888 0.18161186154576608

結論: 選擇顯著性水平 0.05 的話,p = 0.1816 > 0.05,無法拒絕H0,具體來說就是該結果無法支持實驗組均值大于對照組的備則假設。

兩總體均值之差的假設檢驗(配對樣本)

例5.7(數據: diet.txt) 檢驗減肥前后的重量是否有顯著性差異(是否有減肥效果)

這里有兩列50對減肥數據。其中一列數據(變量名before)是減肥前的重量,另一列(變量名after)是減肥后的重量(單位: 公斤),人們希望比較50個人在減肥前和減肥后的重量。

分析過程:這里不能用前面的獨立樣本均值差的檢驗,這是因為兩個樣本并不獨立。每一個人減肥后的重量都和自己減肥前的重量有關,但不同人之間卻是獨立的,所以應該用配對樣本檢驗。同時,由于研究的是減肥前后的重量變化,期望減肥前的重量大于減肥后的重量,所以備擇假設是期望減肥前的重量大于減肥后的重量

于是我們有了原假設和備擇假設:

:

data = pd.read_table("./t-data/diet.txt",sep = ' ')
data.sample(5)
before after
58 50
76 71
69 65
68 76
81 75
a = data['before']
b = data['after']
stats.ttest_rel(a, b,alternative = 'greater')
# Ttest_relResult(statistic=3.3550474801424173, pvalue=0.000769424325484219)

結論 選擇顯著性水平 0.05 的話,p = 0.0007 < 0.05,故應該拒絕原假設。具體來說就是該結果傾向支持減肥前后的重量之差大于零(即減肥前重量大于減肥后,也就是有減肥效果)的備則假設。

兩總體比例之差的假設檢驗

import numpy as np
import scipy.stats as stats

def proportion_test(p1, p2, n1, n2, side='two-sided'):
    """
    參數:
    p1: 樣本1的比例
    p2: 樣本2的比例
    n1: 樣本1的數量
    n2: 樣本2的數量
    side: 假設檢驗的方向,可選'two-sided'(雙側檢驗,默認), 'greater'(右側檢驗), 'less'(左側檢驗)

    返回值:
    z_value: Z統計量的值
    p_value: 對應的p值
    "
""
    p = (p1 * n1 + p2 * n2) / (n1 + n2)
    se = np.sqrt(p * (1 - p) * (1 / n1 + 1 / n2))
    z_value = (p1 - p2) / se

    if side == 'two-sided':
        p_value = 2 * (1 - stats.norm.cdf(np.abs(z_value)))
    elif side == 'greater':
        p_value = 1 - stats.norm.cdf(z_value)
    elif side == 'less':
        p_value = stats.norm.cdf(z_value)
    else:
        raise ValueError("Invalid side value. Must be 'two-sided', 'greater', or 'less'.")

    return z_value, p_value

例5.8 檢驗不同保險客戶的索賠率是否存在差異

某保險公司抽取了單身與已婚客戶的樣本,記錄了他們在一段數據內的索賠次數,計算了索賠率,現在需要檢驗兩種保險客戶的索賠率是否存在差異

分析過程:由于目標比例是否有差異,因此選擇比例之差的雙側檢驗

于是我們有了原假設和備擇假設

:

p1 = 0.14
p2 = 0.09
n1 = 250
n2 = 300

z_value, p_value = proportion_test(p1, p2, n1, n2, side='two-sided')
# 選擇雙側檢驗 alternative = 'two-sided'

print("Z_value:", z_value)
print("p_value:", p_value)
# Z_value: 1.846189280616294
# p_value: 0.0648647268570739

結論 選擇顯著性水平 0.05 的話,p = 0.0648 > 0.05,故應該拒絕原假設。具體來說就是該結果傾向支持兩種保險客戶的索賠率存在差異的備則假設。

兩總體方差之比的假設檢驗

import numpy as np
from scipy import stats
def f_test_by_s_square(n1, n2, s1_square,s2_square, side ='two-sided'):
    """
    n1 :樣本1的數量;n2 :樣本2的數量
    s1_square:樣本1的方差;s2_square:樣本2的方差
    # F_value :F統計量的值;# p_value :對應的p值
    "
""
    F_value = s1_square/s2_square
    F = stats.f(dfn = n1-1, dfd = n2-1)
    if side=='two-sided':
        print("two-sided")
        p_value = 2*min(F.cdf(F_value), 1-F.cdf(F_value))
        return F_value,p_value
    elif  side=='greater':
        print("greater")
        p_value = 1-F.cdf(F_value)
        return F_value,p_value

例5.9 檢驗不同公交公司的校車到達時間的方差是否有差異

某學校的校車合同到期,先需要在A、B兩個校車供應公司中選擇一個,才有到達時間的方差作為衡量服務質量的標準,較低方差說明服務質量穩定且水平較高,如果方差相等,則會選擇價格更低的公司,,如果方差不等,則優先考慮方差更低的公司。 現收集到了A公司的26次到達時間組成一個樣本,方差68,B公司16次到達時間組成一個樣本,方差是30,請檢驗AB兩個公司的到達時間方差。

分析過程:由于目標是希望的方差保持原有水平,因此選擇雙側檢驗。兩總體方差之比用F檢驗,將方差較大的A視為總體1

于是我們有了原假設和備擇假設

:

f_statistic , p_value= f_test_by_s_square(n1=26, n2=16,s1_square=78,s2_square=20,side='two-sided')
# 選擇雙側檢驗所以side='two-sided'
# 打印檢驗結果
print("F statistic:", f_statistic)
print("p-value:", p_value)
#two-sided
#F statistic: 3.9
#p-value: 0.00834904415829052

結論 選擇顯著性水平 0.05 的話,p = 0.0083 < 0.05,故拒絕原假設。結果傾向支持AB兩個公司的到達時間方差存在差異的備則假設。

例5.10 檢驗修完Python課程的學生是否比修完數據庫課程的學生考CDA的成績方差更大

某高校數據科學專業的學生,修完一門數據庫課程的41名學生考CDA的方差,修完Python課程的31名學生考CDA的方差,這些數據是否表明,修完數據庫的學生要比修完Python的學生CDA成績的方差更大?

分析過程:由于目標是希望修完Python的學生CDA成績的方差更大,因此選擇上側檢驗。兩總體方差之比用F檢驗,將方差較大的數據庫課程的考試成績視為總體1,另一個視為總體2,于是我們有了原假設和備擇假設

:

f_statistic , p_value= f_test_by_s_square(n1=41, n2=31,s1_square=120,s2_square=80,side='greater')# 打印檢驗結果
# 選擇上側檢驗所以side='greater'
print("F statistic:", f_statistic)
print("p-value:", p_value)

結論 選擇顯著性水平 0.05 的話,p = 0.1256 > 0.05,故無法原假設。結果無法支持修完數據庫的學生要比修完Python的學生CDA成績的方差更大的備則假設。

關于知識的學習,你會發現有很多相似的邏輯,抓住問題的本質去理解的話就沒那么復雜了,比如概念題里面的 區別和聯系 延伸到數據分析里的差異性和相關性;再比如計算機數據結構里的 樹、森林、網絡機器學習里面的決策樹、隨機森林、神經網絡;再比如從 互聯網、區塊鏈到元宇宙,都是想通過技術的手段去刻畫客觀世界;算法應用里面的圖像識別、語音識別,替代人的眼耳鼻舌身意中的前二者去感知世界。抓住了問題的本質不僅可以幫助我們理解知識,還可以將一個領域的知識或模型遷移到另一個領域加以創新和應用。

假設檢驗背后的故事:統計學史上最著名的女士品茶

6. 方差分析

單因素多水平方差分析

例6.1 不同裝配方式對生產的過濾系統數量的差異性檢驗

某城市過濾水系統生產公司,有A、B、C3種方式進行過濾水系統的裝配,該公司為了研究三種裝配方式生產的過濾系統數量是否有差異,從全體裝配工人中抽取了15名工人,然后隨機地指派一種裝配方式,這樣每個裝配方式就有5個工人。在指派裝配方法和培訓工作都完成后,一周內對每名工人的裝配過濾系統數量進行統計如下:

方法A 方法B 方法C
58 58 48
64 69 57
55 71 59
66 64 47
67 68 49

請根據數據判斷3種裝配方式有無差異

分析過程:由于目標是判斷3種裝配方式有無差異,多樣本的檢驗用方差分析

于是我們有了原假設和備擇假設

:均值不全相等

import pandas as pd
import numpy as np
from scipy import stats

# 數據
A = [58,64,55,66,67]
B = [58,69,71,64,68]
C = [48,57,59,47,49]

data = [A, B, C]
方差的齊性檢驗
w, p = stats.levene(*data)
if p < 0.05:
    print('方差齊性假設不成立')
 
 
# 成立之后, 就可以進行單因素方差分析
f_value, p_value = stats.f_oneway(*data)
# 輸出結果
print("F_value:", f_value)
print("p_value:", p_value)
F_value: 9.176470588235295
p_value: 0.0038184120755124806

結論 選擇顯著性水平 0.05 的話,p = 0.0038 < 0.05,故拒絕原假設。支持三種裝配方式裝配數量均值不全相等的備則假設。

例6.2 不同優惠金額對購買轉化率的差異性檢驗

某公司營銷中心為了提升銷量,針對某產品設計了3種不同金額的優惠,想測試三種優惠方式對于用戶的購買轉化率是否有顯著影響,先收集到了三種不同方式在6個月內的轉化率數據

請根據數據判斷3種不同優惠金額的轉化率有無差異

優惠A 優惠B 優惠C
0.043 0.05 0.048
0.047 0.048 0.05
0.051 0.045 0.047
0.049 0.055 0.056
0.045 0.048 0.054
0.0469 0.0491 0.0509

分析過程:由于目標是判斷3種不同金額的優惠券對于轉化率有無差異,多樣本的檢驗用方差分析

于是我們有了原假設和備擇假設

:認為這幾組之間的購買率不一樣

P < 0.05 拒絕原假設,傾向于支持不同優惠金額購買率不一樣的備擇假設。認為不同優惠金額會對購買率產生影響 P > 0.05 無法拒絕原假設。認為不同優惠金額不會對購買率產生影響

import pandas as pd
import numpy as np
from scipy import stats

A = [0.043 , 0.047 , 0.051 , 0.049 , 0.045 , 0.0469]
B = [0.05  , 0.048 , 0.045 , 0.055 , 0.048 , 0.0491]
C = [0.048 , 0.05  , 0.047 , 0.056 , 0.054 , 0.0509]
data = [A, B, C]
方差的齊性檢驗
w, p = stats.levene(*data)
if p < 0.05:
    print('方差齊性假設不成立')
 
 
# 成立之后, 就可以進行單因素方差分析
f_value, p_value = stats.f_oneway(*data)
# 輸出結果
print("F_value:", f_value)
print("p_value:", p_value)

# F_value: 2.332956563862427
# p_value: 0.13116820340181937

結論 選擇顯著性水平 0.05 的話,p = 0.1311 > 0.05,故無法拒絕原假設。認為不同優惠金額不會對購買率產生影響

雙因素方差分析

1.雙因素方差分析(等重復實驗)

這里的等重復實驗,意思就是針對每個組合做大于等于兩次的實驗,比如下方例子中表里A1和B1的組合里面有2個數字,即說明做了兩次實驗,如果是3個數字則說明3次實驗,依次類推。

例6.3 不同燃料種類和推進器的火箭射程差異性檢驗

火箭的射程與燃料的種類和推進器的型號有關,現對四種不同的燃料與三種不同型號的推進器進行試驗,每種組合各發射火箭兩次,測得火箭的射程如表(以海里計)(設顯著性水平為0.05)

燃料 B1 B2 B3
A1 58.2 , 52.6 56.2 , 41.2 65.3 , 60.8
A2 49.1 , 42.8 54.1 , 50.5 51.6 , 48.4
A3 60.1 , 58.3 70.9 , 73.2 39.2 , 40.7
A4 75.8 , 71.5 58.2 , 51.0 48.7 , 41.0
import numpy as np
import pandas as pd 

d = np.array([[58.2, 52.6, 56.2, 41.2, 65.3, 60.8],
    [49.1, 42.8, 54.1, 50.5, 51.6, 48.4],
    [60.1, 58.3, 70.9, 73.2, 39.2, 40.7],
    [75.8, 71.5, 58.2, 51.0, 48.7,41.4]
])
data = pd.DataFrame(d)
data.index=pd.Index(['A1','A2','A3','A4'],name='燃料')
data.columns=pd.Index(['B1','B1','B2','B2','B3','B3'],name='推進器')

pandas寬表轉長表
data = data.reset_index().melt(id_vars =['燃料'])
data = data.rename(columns={'value':'射程'})
data.sample(5)
燃料 推進器 射程
A2 B3 48.4
A3 B2 73.2
A3 B3 39.2
A4 B1 71.5
A2 B2 54.1
import statsmodels.api as sm
from statsmodels.formula.api import ols

# 進行雙因素方差分析
model = ols('射程~C(燃料) + C(推進器)+C(燃料):C(推進器)', data =data).fit()
# 打印方差分析表
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
sum_sq df F PR(>F)
C(燃料) 261.675 3 4.41739 0.025969
C(推進器) 370.981 2 9.3939 0.00350603
C(燃料):C(推進器) 1768.69 6 14.9288 6.15115e-05
Residual 236.95 12 nan nan

結論:

對燃料因素來說,其p = 0.0259 < 0.05 所以拒絕,認為燃料對射程影響顯著;

對推進器因素來說,其p = 0.0035 < 0.05,所以拒絕,認為推進器對射程影響顯著;

對燃料和推進器的交互因素來說,其p = 0.000062< 0.05,所以拒絕,認為交互因素其對射程影響顯著。

2.雙因素方差分析(無重復實驗)

在等重復實驗中,我們為了檢驗實驗中兩個因素的交互作用,針對每對組合至少要做2次以上實驗,才能夠將交互作用與誤差分離開來,在處理實際問題時候,如果我們一直不存在交互作用,或者交互作用對實驗指標影響極小,則可以不考慮交互作用,此時每對組合只做一次實驗,類似下方例子中的表中數據:

例6.4 不同時間、不同地點顆粒狀物含量差異性檢驗 無重復實驗

下面給出了在5個不同地點、不同時間空氣中的顆粒狀物(單位:mg/m°)含 量的數據記錄于表中,試在顯著性水平下檢驗不同時間、不同地點顆粒狀物含量有無顯著差異?(假設兩者沒有交互作用〉

因素B -地點
因素A - 時間
1995年10月 76 67 81 56 51
1996年01月 82 69 96 59 70
1996年05月 68 59 67 54 42
1996年08月 63 56 64 58 37
import numpy as np
import pandas as pd 

d = np.array([
    [76,67,81,56,51],
    [82,69,96,59,70],
    [68,59,67,54,42],
    [63,56,64,58,37]])
data = pd.DataFrame(d)
data.index=pd.Index(['1995年10月','1996年01月','1996年05月','1996年08月'],name='時間')
data.columns=pd.Index(['B1','B2','B3','B4','B5'],name='地點')
pandas寬表轉長表
data = data.reset_index().melt(id_vars =['時間'])
data = data.rename(columns={'value':'顆粒狀物含量'})
data.sample(5)

隨機查看5條轉化后的數據:

時間 地點 顆粒狀物含量
1996年05月 B4 54
1995年10月 B4 56
1996年05月 B3 67
1996年01月 B2 69
1996年01月 B3 96
import statsmodels.api as sm
from statsmodels.formula.api import ols

# 進行雙因素方差分析
model = ols('顆粒狀物含量~C(時間) + C(地點)', data =data).fit()
# 打印方差分析表
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
sum_sq df F PR(>F)
C(時間) 1182.95 3 10.7224 0.00103293
C(地點) 1947.5 4 13.2393 0.000234184
Residual 441.3 12 nan nan

結論:

對時間因素來說,其p = 0.001033 < 0.05 所以拒絕,認為時間對顆粒狀物含量影響顯著;

對地點因素來說,其p = 0.000234 < 0.05,所以拒絕,認為地點對顆粒狀物含量影響顯著;

致敬:數理統計的大半江山的創造者——費希爾
致敬:數理統計的大半江山的創造者——費希爾

7. 相關性分析

前面的假設檢驗、方差分析基本上都是圍繞差異性分析,不論是單個總體還是兩個總體及以上,總之都是屬于研究“區別”,從本節開始,我們關注“聯系”,變量之間的關系分為 函數關系和相關關系。 本節這里重點探討的是不同類型變量之間的相關性,千萬記住一點相關性不代表因果性。除表中列出的常用方法外,還有Tetrachoric、相關系數等。

變量類型 變量類型 相關系數計算方法 示例
連續型變量 連續型變量 Pearson(正態)/Spearman(非正態) 商品曝光量和購買轉化率
二分類變量(無序) 連續型變量 Point-biserial 性別和疾病指數
無序分類變量 連續型變量 方差分析 不同教育水平的考試成績
有序分類變量 連續型變量 連續指標離散化后當做有序分類 商品評分與購買轉化率
二分類變量 二分類變量 數學公式: 檢驗 聯合 Cramer's V 性別和是否吸煙
二分類變量(有序) 連續型變量 Biserial 樂器練習時間與考級是否通過
無序分類變量 無序分類變量 數學公式: 檢驗 / Fisher檢驗 手機品牌和年齡段
有序分類變量 無序分類變量 數學公式: 檢驗 滿意度和手機品牌
有序分類變量 有序分類變量 Spearman /Kendall Tau相關系數 用戶等級和活躍程度等級

連續型變量 vs 連續型變量 : Pearson / Spearmanr

Pearson

Pearson相關系數度量了兩個連續變量之間的線性相關程度;

import random 
import numpy as np
import pandas as pd

np.random.seed(10)
df = pd.DataFrame({'商品曝光量':[1233,1333,1330,1323,1323,1142,1231,1312,1233,1123],
     '購買轉化率':[0.033,0.034,0.035,0.033,0.034,0.029,0.032,0.034,0.033,0.031]})
df
pd.Series.corr(df['商品曝光量'], df['購買轉化率'],method = 'pearson'# pearson相關系數
# 0.885789300493948
import scipy.stats as stats

# 假設有兩個變量X和Y
X = df['商品曝光量']
Y = df['購買轉化率']

# 使用spearmanr函數計算斯皮爾曼相關系數和p值
corr, p_value = stats.pearsonr(X, Y)

print("Pearson相關系數:", corr)
print("p值:", p_value)
# Pearson相關系數: 0.8857893004939478
# p值: 0.0006471519603654732

Spearman等級相關系數

Spearman等級相關系數可以衡量非線性關系變量間的相關系數,是一種非參數的統計方法,可以用于定序變量或不滿足正態分布假設的等間隔數據;

import random 
import numpy as np
import pandas as pd

np.random.seed(10)
df = pd.DataFrame({'品牌知名度排位':[9,4,3,6,5,8,1,7,10,2],
     '售后服務質量評價排位':[8,2,5,4,7,9,1,6,10,3]})
df
pd.Series.corr(df['品牌知名度排位'], df['售后服務質量評價排位'],method = 'spearman'# spearman秩相關
# 0.8787878787878788
import scipy.stats as stats

# 假設有兩個變量X和Y
X = df['品牌知名度排位']
Y = df['售后服務質量評價排位']

# 使用spearmanr函數計算斯皮爾曼相關系數和p值
corr, p_value = stats.spearmanr(X, Y)

print("斯皮爾曼相關系數:", corr)
print("p值:", p_value)
# 斯皮爾曼相關系數: 0.8787878787878788
# p值: 0.0008138621117322101

結論:p = 0.0008<0.05,表明兩變量之間的正向關系很顯著。

二分類變量(自然)vs 連續型變量 :Point-biserial

假設我們想要研究性別對于某種疾病是否存在影響。我們有一個二元變量“性別”(男、女)和一個連續型變量“疾病指數”。我們想要計算性別與疾病指數之間的相關系數,就需要用到Point-biserial相關系數。

import scipy.stats as stats

# 創建一個列表來存儲數據
gender = [0, 1, 0, 1, 1, 0]
disease_index = [3.2, 4.5, 2.8, 4.0, 3.9, 3.1]

# 使用pointbiserialr函數計算Point-biserial相關系數和p值
corr, p_value = stats.pointbiserialr(gender, disease_index)

print("Point-biserial相關系數:", corr)
print("p值:", p_value)
# Point-biserial相關系數: 0.9278305692406299
# p值: 0.007624695507848026

結論:p = 0.007<0.05,表明兩變量之間的正向關系很顯著。即性別與疾病指數正相關

無序分類變量 vs 連續型變量 : ANOVA

假設我們想要比較不同教育水平的學生在CDA考試成績上是否存在顯著差異。我們有一個無序分類變量“教育水平”(高中、本科、研究生)和一個連續型變量“考試成績”。

import pandas as pd
import statsmodels.api as sm
from statsmodels.formula.api import ols

# 創建一個DataFrame來存儲數據
data = pd.DataFrame({
    '教育水平': ['高中''本科''本科''研究生''高中''本科''研究生'],
    '考試成績': [80, 90, 85, 95, 75, 88, 92]
})

# 使用ols函數創建一個線性模型
model = ols('考試成績 ~ C(教育水平)', data=data).fit()

# 使用anova_lm函數進行方差分析
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table

結論:p = 0.0102<0.05,拒絕原假設,表明兩變量之間的正向關系很顯著。教育水平與考試成績正相關

有序分類變量 vs 連續型變量

連續型變量離散化后當做有序分類,然后用 有序分類變量 VS 有序分類變量的方法

二分類變量 vs 二分類變量 :檢驗 聯合 Cramer's V

一項研究調查了不同性別的成年人對在公眾場合吸煙的態度,結果如表所示。那么,性別與對待吸煙的態度之間的相關程度

- 贊同 反對
15 10
10 26
import numpy as np
from scipy.stats import chi2_contingency

observed = np.array([[15, 10],
                     [10, 26]])
observed

chi2, p, dof, expected = chi2_contingency(observed,correction =False) # correction =False
# 卡方值 
# P值 
# 自由度: 
# 與原數據數組同維度的對應期望值

chi2, p
#(6.3334567901234555, 0.011848116168529757)

結論:p = 0.0118<0.05,拒絕原假設,表明兩變量之間的正向關系很顯著。

phi = np.sqrt(chi2/n)
print("phi's V:", phi)
# phi's V: 0.3222222222222222

卡方檢驗時有多種指標可表示效應量,可結合數據類型交叉表格類型綜合選擇

  • 第一:如果是2*2表格,建議使用 指標
  • 第二:如果是33,或 44表格,建議使用列聯系數;
  • 第三:如果是n*n(n>4)表格,建議使用 校正列聯系數;
  • 第四:如果是m*n(m不等于n)表格,建議使用 Cramer V指標;
  • 第五:如果X或Y中有定序數據,建議使用 指標;

這里只列出 指標Cramer V指標 的計算,其他計算方式請讀者自行研究。

# 計算Cramer's V
contingency_table = observed
n = contingency_table.sum().sum()
phi_corr = np.sqrt(chi2 / (n * min(contingency_table.shape) - 1))
v = phi_corr / np.sqrt(min(contingency_table.shape) - 1)

print("Cramer's V:", v)
# Cramer's V: 0.22878509151645754

二分類變量(有序) 連續型變量: Biserial

import numpy as np
from scipy.stats import pearsonr

# 生成隨機的二元變量
binary_variable = np.random.choice([0, 1], size=100)

# 生成隨機的連續變量
continuous_variable = np.random.normal(loc=0, scale=1, size=100)


# 注:此處的代碼未經嚴格考證,請謹慎使用
def biserial_correlation(binary_variable, continuous_variable):
    binary_variable_bool = binary_variable.astype(bool)
    binary_mean = np.mean(binary_variable_bool)
    binary_std = np.std(binary_variable_bool)
    
    binary_variable_norm = (binary_variable_bool - binary_mean) / binary_std
    
    corr, _ = pearsonr(binary_variable_norm, continuous_variable)
    biserial_corr = corr * (np.std(continuous_variable) / binary_std)
    
    return biserial_corr

# 計算Biserial相關系數
biserial_corr = biserial_correlation(binary_variable, continuous_variable)

print("Biserial相關系數:", biserial_corr)
Biserial相關系數: -0.2061772328681707

無序分類變量 vs 無序分類變量

參考 檢驗

有序分類變量 vs 無序分類變量

參考 檢驗

有序分類變量 vs 有序分類變量

Kendall秩相關系數

Kendall秩相關系數也是一種非參數的等級相關度量,類似于Spearman等級相關系數。

import random 
import numpy as np
import pandas as pd

np.random.seed(10)
df = pd.DataFrame({'品牌知名度排位':[9,4,3,6,5,8,1,7,10,2],
     '售后服務質量評價排位':[8,2,5,4,7,9,1,6,10,3]})
df
pd.Series.corr(df['品牌知名度排位'], df['售后服務質量評價排位'],method = 'kendall'# Kendall Tau相關系數
# 0.7333333333333333
from scipy.stats import kendalltau

# 兩個樣本數據
x = df['品牌知名度排位']
y = df['售后服務質量評價排位']

# 計算Kendall Tau相關系數
correlation, p_value = kendalltau(x, y)

print("Kendall Tau相關系數:", correlation)
print("p值:", p_value)
# Kendall Tau相關系數: 0.7333333333333333
# p值: 0.002212852733686067

8. 再看t檢驗、F檢驗、檢驗

前面在假設檢驗的部分經學過t檢驗、F檢驗、檢驗,之所以再看,是想通過縱向對比這幾個檢驗統計量以加深理解:

t檢驗

針對不同的場景,主要分為單樣本T檢驗、獨立樣本T檢驗、配對樣本T檢驗:

單樣本的t檢驗

主要用于分析 一組定量數據指定值的差異,例如檢驗食鹽的實際稱重是否不夠標重的份量。

單樣本T檢驗需要滿足正態分布的假設,若不滿足可采用單樣本Wilcoxon檢驗。

例5.2 檢驗汽車實際排放是否低于其聲稱的排放標準

汽車廠商聲稱其發動機排放標準的一個指標平均低于20個單位。在抽查了10臺發動機之后,得到下面的排放數據: 17.0 21.7 17.9 22.9 20.7 22.4 17.3 21.8 24.2 25.4 該樣本均值為21.13.究竟能否由此認為該指標均值超過20?

分析過程: 由于廠家聲稱指標平均低于20個單位,因此原假設為總體均值等于20個單位(被懷疑對象總是放在零假設)。而且由于樣本均值大于20(這是懷疑的根據),把備擇假設設定為總體均值大于20個單位

于是我們有了原假設和備擇假設

:

讀取數據如下

data = [17.021.717.922.920.722.417.321.824.225.4]

分步驟計算過程如下:

步驟一:計算樣本均值 =(17+21.7+...+25.4)/10=21.13

用Python:

x_bar = np.array(data).mean()
x_bar
# 21.13

步驟二:計算樣本標準差

用Python計算:

s = np.sqrt(((data-x_bar)**2).sum()/len(data))
s
# 2.7481084403640255

步驟三:計算統計量

,其中 為整體均值20,自由度n-1為9

t = (x_bar - 20)/(s/np.sqrt(len(data)-1))
t
# 1.2335757753252794

步驟四:查表或用軟件查詢p值與

p_value = scipy.stats.t.sf(t,len(data)-1 )
p_value 
# 0.1243024777589817

結論: 選擇顯著性水平 0.01 的話,P=0.1243 > 0.05, 故無法拒絕原假設。具體來說就是該結果無法支持指標均值超過20的備則假設。說明發動機排放指標是不合格的。

對于以上過程,我們也可以用scipy.stats.ttest_1samp函數,一步到位進行t檢驗,直接返回的就是t統計量和p值:

import scipy.stats
t, pval = scipy.stats.ttest_1samp(a = data, popmean=20,alternative = 'greater')
# 說明  
# 單一樣本的t檢驗,檢驗單一樣本是否與給定的均值popmean差異顯著的函數,第一個參數為給定的樣本,第二個函數為給定的均值popmean,可以以列表的形式傳輸多個單一樣本和均值。
# a  為給定的樣本數據
# popmean 為給定的總體均值
# alternative 定義備擇假設。以下選項可用(默認為“two-sided”):
# ‘two-sided’:樣本均值與給定的總體均值(popmean)不同
# ‘less’:樣本均值小于給定總體均值(popmean)
# ‘greater’:樣本均值大于給定總體均值(popmean)

print(t, pval)

# '''
# P= 0.004793 < 5%, 拒絕原假設,接受備擇假設樣本
# '''

結論: 選擇顯著性水平 0.01 的話,P=0.1243 > 0.05, 故無法拒絕原假設。具體來說就是該結果無法支持指標均值超過20的備則假設。

獨立樣本的t檢驗

主要用于分析定量數據和**定類數據(2組)**的差異。原理是推論差異發生的概率,從而比較兩個平均數的差異是否顯著。通俗的說就是用樣本均數和已知總體均數進行比較,來觀察此組樣本與總體的差異性。

例如有一個班的學生身高數據,如果學生的身高服從正態分布,想要研究身高和性別的關系,這個時候就相當于是兩個獨立樣本。

獨立樣本的T檢驗也需要滿足正態分布的假設,如果不滿足可采用 Wilcoxon檢驗(也稱MannWhitney檢驗); 如果滿足但方差不等可采用 Welch T檢驗

計算公式如下:

、 代表兩組數據的均值,

、 代表樣本數,

、 代表兩組數組的方差。

從計算公式能看出來,t越小則兩組數據差異性越小。具體多小就根據置信度和自由度查表對比理論統計量的大小得出兩組數據差異性是否顯著。

例5.6(數據:drug.txt) 檢驗某藥物在實驗組的指標是否低于對照組

為檢測某種藥物對情緒的影響,對實驗組的100名服藥者和對照組的150名非服藥者進行心理測試,得到相應的某指標。需要檢驗實驗組指標的總體均值是否大于對照組的指標的總體均值。這里假定兩個總體獨立地服從正態分布。相應的假設檢驗問題為:

分析過程:由于目標是檢驗實驗組指標的總體均值是否大于對照組的指標的總體均值,因此選擇上側檢驗

于是我們有了原假設和備擇假設

:

data = pd.read_table("./t-data/drug.txt",sep = ' ')
data.sample(5)
ah id
4.4 2
6.8 2
9.6 2
4.8 2
13.2 1
a = data[data['id']==1]['ah']
b = data[data['id']==2]['ah']
'''
H0: 實驗組的均值等于對照組
H1: 實驗組的均值大于對照組

'''

t, pval = scipy.stats.ttest_ind(a,b,alternative = 'greater')
# 獨立樣本的T檢驗,檢驗兩個樣本的均值差異,該檢驗方法假定了樣本的通過了F檢驗,即兩個獨立樣本的方差相同


# 另一個方法是: 
# stats.ttest_ind_from_stats(mean1, std1, nobs1, mean2, std2, nobs2, equal_var=True)
# 檢驗兩個樣本的均值差異(同上),輸出的參數兩個樣本的統計量,包括均值,標準差,和樣本大小:直接輸入樣本的描述統計量(均值,標準差,樣本數)即可



print(t,pval)
# 0.9109168350628888 0.18161186154576608

結論: 選擇顯著性水平 0.05 的話,p = 0.1816 > 0.05,無法拒絕H0,具體來說就是該結果無法支持實驗組均值大于對照組的備則假設。

配對樣本t檢驗

主要用于分析配對定量數據的差異。

常見的使用場景有:

①同一對象處理前后的對比(同一組人員采用同一種減肥方法前后的效果對比);

②同一對象采用兩種方法檢驗的結果的對比(同一組人員分別服用兩種減肥藥后的效果對比);

③配對的兩個對象分別接受兩種處理后的結果對比(兩組人員,按照體重進行配對,服用不同的減肥藥,對比服藥后的兩組人員的體重)。

例如,假設一個班上男女生的成績不存在差異,顯著性水平為0.05,可理解為只有5%的概率會出現“男女生成績差異顯著”的情況,若計算出的檢驗p值若小于0.05,則可以拒絕原假設。反之不能拒絕原假設。

此外,t檢驗注意事項

①無論哪種t檢驗、都要數據服從正態或者近似正態分布。正態性的檢驗方法有:正態圖、正態性檢驗、P-P圖/Q-Q圖等。

②兩個獨立樣本的t檢驗,通常需要先進行F檢驗(方差齊次檢驗),檢驗兩個獨立樣本的方差是否相同,若兩總體方差相等,則直接用t檢驗,若不等,可采用t’檢驗或變量變換或秩和檢驗等方法。

例5.7(數據: diet.txt) 檢驗減肥前后的重量是否有顯著性差異(是否有減肥效果)

這里有兩列50對減肥數據。其中一列數據(變量名before)是減肥前的重量,另一列(變量名after)是減肥后的重量(單位: 公斤),人們希望比較50個人在減肥前和減肥后的重量。

分析過程:這里不能用前面的獨立樣本均值差的檢驗,這是因為兩個樣本并不獨立。每一個人減肥后的重量都和自己減肥前的重量有關,但不同人之間卻是獨立的,所以應該用配對樣本檢驗。同時,由于研究的是減肥前后的重量變化,期望減肥前的重量大于減肥后的重量,所以備擇假設是期望減肥前的重量大于減肥后的重量

于是我們有了原假設和備擇假設:

:

步驟一、計算兩組樣本數據差值d,即58-50,76-71,69-65,68-76,81-75

d = data['before'] - data['after']

步驟二、計算差值d的平均值 ,即(-1+0+1+0)/4=0

d_bar = ( d).sum()/len(data)

步驟三、計算差值d的標準差 ,計算公式為

s_d = np.sqrt(((d -d_bar)**2).sum()/(len(data)-1))
s_d

步驟四、計算統計量t,計算公式為

t = (d_bar)/(s_d/np.sqrt(len(data))) # 這里mu是0
t
#

計算p值

p_value = scipy.stats.t.sf(t, len(data)-1)
p_value 
# 0.0007694243254842176

其中 為理論總體差值均值0,n為樣本數。

結論 選擇顯著性水平 0.05 的話,p = 0.0007 < 0.05,故應該拒絕原假設。具體來說就是該結果傾向支持減肥前后的重量之差大于零(即減肥前重量大于減肥后,也就是有減肥效果)的備則假設。

同樣的,我們用現成的函數 stats.ttest_rel,一步到位進行t檢驗,直接返回的就是t統計量和p值:

data = pd.read_table("./t-data/diet.txt",sep = ' ')
data.sample(5)
before after
58 50
76 71
69 65
68 76
81 75
a = data['before']
b = data['after']
stats.ttest_rel(a, b,alternative = 'greater')
# #配對T檢驗,檢測兩個樣本的均值差異,輸入的參數是樣本的向量
# Ttest_relResult(statistic=3.3550474801424173, pvalue=0.000769424325484219)

結論 選擇顯著性水平 0.05 的話,p = 0.0007 < 0.05,故應該拒絕原假設。具體來說就是該結果傾向支持減肥前后的重量之差大于零(即減肥前重量大于減肥后,也就是有減肥效果)的備則假設。

F檢驗

F檢驗(F-test),最常用的別名叫做聯合假設檢驗(英語:joint hypotheses test),此外也稱方差比率檢驗、方差齊性檢驗。

用于: 判斷兩組數據方差是否存在顯著差異。

步驟一:分別計算兩組樣本數據的均值

步驟二:分別計算兩組樣本數據的標準方差的平方

步驟三:計算兩組樣本數據標準方差的平方比

,把平方大的作為分子,小的作為分母。

得到F值后根據兩組數據的自由度和置信度查表對比,同樣的,F值也是越小越說明差異性不顯著。

stats模塊中雖然沒有f檢驗的函數,但是卻有著f分布的生成函數,可以利用其進行f檢驗:

import numpy as np
from scipy.stats import f_oneway

# 創建兩個樣本
sample1 = np.array([1, 2, 3, 4, 5])
sample2 = np.array([2, 4, 6, 8, 10])

# 使用 f_oneway 函數進行 F 檢驗
f_statistic, p_value = f_oneway(sample1, sample2)

# 打印檢驗結果
print("F statistic:", f_statistic)
print("p-value:", p_value)

#在上述示例中,我們創建了兩個樣本 sample1 和 sample2,每個樣本包含五個觀測值。然后,我們使用 f_oneway 函數對這兩個樣本進行 F 檢驗。
#f_oneway 函數返回兩個值,第一個是 F 統計量,第二個是對應的 p 值。我們可以根據 p 值來判斷樣本方差是否有顯著差異。如果 p 值小于設定的顯著性水平(通常為 0.05),則可以拒絕原假設,認為樣本方差存在顯著差異。
#在上述示例中,我們可以得到 F 統計量為 4.0,p 值為 0.078。由于 p 值大于 0.05,我們不能拒絕原假設,即無法認為這兩個樣本的方差存在顯著差異。
#需要注意的是,在使用 f_oneway 函數進行 F 檢驗時,輸入的樣本應該是一維數組或列表形式。如果有多個樣本,可以將它們作為函數的參數傳入。

也可以引入sklearn進行f檢驗

# 例子1
from sklearn.datasets import make_classification
from sklearn.feature_selection import f_classif 

# 生成樣本數據集
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=42)

# F檢驗
F, pval = f_classif(X, y)  

# 輸出結果
print(F) 
print(pval)

特征排序(如果不做機器學習可以忽略這一步)
indices = np.argsort(F)[-10:] 
print(indices)
#這里我們生成了一個包含10個特征的樣本分類數據集,其中5個特征包含區分兩類信息,5個特征冗余。
#使用f_classif函數可以計算每個特征的F-score和p值,F-score越高表示該特征越重要。
#最后通過argsort排序,輸出最重要的特征索引。
#F檢驗通過計算每個特征對目標類別的區分能力,來對特征重要性進行評估和排序,是一種常用的過濾式特征選擇方法。

# 例子2
import numpy as np
from sklearn.feature_selection import f_regression

# 創建特征矩陣 X 和目標向量 y
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
y = np.array([1, 2, 3])

# 使用 f_regression 函數進行 F 檢驗
f_values, p_values = f_regression(X, y)

# 打印 F 統計量和 p 值
print("F values:", f_values)
print("p-values:", p_values)

例5.10(兩總體方差之比的假設檢驗) 檢驗修完Python課程的學生是否比修完數據庫課程的學生考CDA的成績方差更大

某高校數據科學專業的學生,修完一門數據庫課程的41名學生考CDA的方差,修完Python課程的31名學生考CDA的方差,這些數據是否表明,修完數據庫的學生要比修完Python的學生CDA成績的方差更大?

分析過程:由于目標是希望修完Python的學生CDA成績的方差更大,因此選擇上側檢驗。兩總體方差之比用F檢驗,將方差較大的數據庫課程的考試成績視為總體1

于是我們有了原假設和備擇假設

:


import numpy as np
from scipy import stats

def f_test_by_s_square(n1, n2, s1_square,s2_square, side ='two-sided'):
    """
    參數
    n1 :樣本1的數量
    n2 :樣本2的數量
    s1_square:樣本1的方差
    s2_square:樣本2的方差
    # 
    # F_value :F統計量的值
    # p_value :對應的p值
    "
""
    F_value = s1_square/s2_square
    F = stats.f(dfn = n1-1, dfd = n2-1)
    if side=='two-sided':
        print("two-sided")
        p_value = 2*min(F.cdf(F_value), 1-F.cdf(F_value))
        return F_value,p_value
    elif  side=='greater':
        print("greater")
        p_value = 1-F.cdf(F_value)
        return F_value,p_value
f_statistic , p_value= f_test_by_s_square(n1=41, n2=31,s1_square=120,s2_square=80,side='greater')# 打印檢驗結果
# 選擇上側檢驗所以side='greater'
print("F statistic:", f_statistic)
print("p-value:", p_value)

結論 選擇顯著性水平 0.05 的話,p = 0.1256 > 0.05,故無法原假設。結果無法支持修完數據庫的學生要比修完Python的學生CDA成績的方差更大的備則假設。

檢驗

卡方檢驗(chi-square test),也就是χ2檢驗,是以 分布為基礎的一種用途廣泛的分析定性數據差異性的方法,通過頻數進行檢驗。

之前假設檢驗一節中,我們知道卡方檢驗可以做指定方差和樣本方差是否有差異

例5.5 檢驗某考試中心升級題庫后考生分數的方差是否有顯著變化

某數據分析師認證考試機構CDA考試中心,歷史上的持證人考試分數的方差,現在升級了題庫,該考試中心希望新型考題的方差保持在原有水平上,為了研究該問題,收集到了30份新考題的考分組成的樣本,樣本方差,在 的顯著性水平下進行假設檢驗。

分析過程:由于目標是希望考試分數的方差保持原有水平,因此選擇雙側檢驗

于是我們有了原假設和備擇假設

:

import numpy as np
from scipy import stats

def chi2test(sample_var, sample_num,sigma_square,side, alpha=0.05):
    '''
    參數:
    sample_var--樣本方差
    sample_num--樣本容量
    sigma_square--H0方差
    返回值:
    pval
    '
''
    chi_square =((sample_num-1)*sample_var)/(sigma_square)
    p_value = None
    if side == 'two-sided':
        p = stats.chi2(df=sample_num-1).cdf(chi_square)
        p_value = 2*np.min([p, 1-p])
    elif side == 'less':
        p_value = stats.chi2(df=sample_num-1).cdf(chi_square)
    elif side == 'greater':
        p_value = stats.chi2(df=sample_num-1).sf(chi_square)
    return chi_square,p_value

p_value = chi2test(sample_var = 162, sample_num = 30, sigma_square = 100,side='two-sided')

print("p值:", p_value)
# p值: 0.07213100536907469

結論: 選擇顯著性水平 0.05 的話,P=0.0721 > 0.05, 故無法拒絕原假設。具體來說就是不支持方差發生了變化的備則假設。換句話說新題型的方差依然保持在原有水平上

那么,卡方檢驗還有什么應用呢?

統計樣本的實際觀測值與理論推斷值之間的偏離程度,實際觀測值與理論推斷值之間的偏離程度就決定卡方值的大小,如果卡方值越大,二者偏差程度越大;反之,二者偏差越??;若兩個值完全相等時,卡方值就為0,表明理論值完全符合。

卡方值計算公式:

①卡方優度檢驗 對一列數據進行統計檢驗,分析單個分類變量實際觀測的比例與期望的比例是否一致。

②配對卡方 研究實驗過程中,用不同方法檢測同一批人,看兩個方法的效果是否有顯著差異。

交叉表卡方

研究兩組分類變量的關系:如性別與看不看直播是否有關系。

例7.5(交叉表卡方):性別與對待吸煙的態度之間的相關性 一項研究調查了不同性別的成年人對在公眾場合吸煙的態度,結果如表所示。那么,性別與對待吸煙的態度之間的相關程度

- 贊同 反對
15 10
10 26

python中stats模塊,同樣有卡方檢驗的計算函數

from  scipy.stats import chi2_contingency
import numpy as np
data = np.array([[15,10], [10,26]])
chi2, p, dof, expected  = chi2_contingency(data,correction =False)
print(f'卡方值={chi2}, p值={p}, 自由度={dof}')
# 卡方值=6.3334567901234555, p值=0.011848116168529757, 自由度=1

結論:p = 0.0118<0.05,拒絕原假設,表明兩變量之間的正向關系很顯著。

sklearn中的特征選擇中也可以進行卡方檢驗。

from sklearn.feature_selection import chi2
import numpy as np

# 假設我們有一個包含100個樣本和5個特征的數據集
X = np.random.randint(0, 10, (40, 5))
y = np.random.randint(0, 2, 40)
# 使用chi2函數計算特征變量與目標變量之間的卡方統計量和p值
chi2_stats, p_values = chi2(X, y)

# 打印每個特征的卡方統計量和p值
for i in range(len(chi2_stats)):
    print(f"Feature {i+1}: chi2_stat = {chi2_stats[i]}, p_value = {p_values[i]}")

#在上面的例子中,我們生成了一個包含100個樣本和5個特征的隨機數據集。然后,我們使用chi2函數計算每個特征與目標變量之間的卡方統計量和p值。最后,我們打印出每個特征的卡方統計量和p值。
#根據卡方統計量和p值,我們可以判斷每個特征與目標變量之間的關聯程度。如果卡方統計量較大且p值較小,則說明特征與目標變量之間存在顯著關聯,可以考慮選擇該特征作為重要的特征進行建模。

至此,統計學的描述性統計、推斷統計基本告一段落,剩下的貝葉斯、線性回歸、邏輯回歸請讀者自行查閱資料進行學習,我們下個系列見!

(PS:可以在評價中寫下你想學的系列,包括不限于SQL、Pandas、Julia、機器學習、數學建模、數據治理

致謝

《統計學極簡入門》圖文系列教程的寫作過程中參考了諸多經典書籍,包括:

人大統計學教授吳喜之老師的 《統計學:從數據到結論》;

浙大盛驟教授的 概率論與數理統計》;

辛辛那提大學 David R. Anderson的 《商務經濟與統計》;

北海道大學的馬場真哉的 《用Python動手學統計學》 ;

千葉大學研究院教授栗原伸一的《統計學圖鑒》;

前阿里巴巴產品專家徐小磊的知乎:磊叔-數據化運營;

知乎舊夢的文章T檢驗、F檢驗、卡方檢驗詳細分析及應用場景總結;

csdn文章T檢驗、卡方檢驗、F檢驗;

以及CDA認證考試中心 提供的部分案例數據集

在此一并感謝以上內容的作者!

一死生為虛誕,齊彭殤為妄作。各位加油!

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢