當你踏入數據分析的大門時,可能會被海量的數據淹沒,感到無從下手。

想象一下,你想了解一座巨大森林裏所有樹木的平均高度,難道要一棵一棵地去測量嗎?這顯然不現實。

這時,“抽樣” 這個強大的工具就該登場了!

本文將帶你全面瞭解各種抽樣方法,並用Python代碼演示實際應用。

1. 抽樣是什麼?

抽樣 是從總體中選取部分樣本進行分析的過程。

這樣做的主要原因是:

  • 節省時間和資源:處理全部數據成本高昂
  • 可行性:當總體無限或無法完全獲取時
  • 效率:快速獲得初步分析結果

抽樣的世界裏,主要有兩種不同的理念,形成了兩大陣營:

  • 非隨機抽樣:抽樣過程不遵循隨機原則,而是根據研究人員的主觀經驗或方便性來選擇樣本。這種方法簡單、快速、成本低,適用於探索性研究或對時效性要求高的場景。
  • 隨機抽樣:也稱為概率抽樣,它遵循隨機原則,確保總體中的每個單位都有一定的機會被抽中。這種方法專業性強,可以客觀地衡量抽樣誤差,是數據分析中更常用、更科學的方法。

接下來,我們將重點介紹幾種主流的抽樣方法。

2. 非隨機抽樣

非隨機抽樣雖然在嚴謹的數據分析中需要謹慎使用,但在某些場景下依然有其價值。

它的實現原理是:根據研究者的主觀判斷、方便程度或特定需求來選擇樣本,不保證每個個體都有被抽中的機會。

常見的非隨機抽樣包括方便抽樣判斷抽樣滾雪球抽樣等。

典型的應用場景有:

  • 產品初期快速的用户訪談:在產品開發的早期階段,為了快速收集用户反饋,可能會在公司門口或附近的咖啡館隨機邀請用户進行簡短訪談。
  • 特定人羣的深度研究:研究某個罕見病羣體時,可以通過醫生推薦或患者社羣來尋找研究對象,這類似於滾雪球抽樣。

下面用Python實現一個簡單的非隨機抽樣的示例。

import pandas as pd
import numpy as np

# 模擬創建一個包含1000名用户的數據集
np.random.seed(42)
data = {
    'user_id': range(1, 1001),
    'age': np.random.randint(18, 60, size=1000),
    'city': np.random.choice(['北京', '上海', '廣州', '深圳', '杭州'], size=1000),
    'activity_score': np.random.randint(1, 101, size=1000) # 活躍度評分,1-100
}
df = pd.DataFrame(data)

# 非隨機抽樣:判斷抽樣
# 我們主觀判斷活躍度分數高於90的用户為高活躍度代表
high_activity_sample = df[df['activity_score'] > 90]

print("判斷抽樣(活躍度>90)的樣本量:", len(high_activity_sample))
print(high_activity_sample.head())

運行結果:

數據分析方法彙總(1)_mob604756f976e6的技術博客_數據

3. 隨機抽樣

隨機抽樣是數據分析的基石,它能確保樣本的代表性,從而讓我們的分析結論更具説服力

隨機抽樣一般有下面四種方式:

3.1. 簡單隨機抽樣

這是最基礎的隨機抽樣方法,確保總體中每個個體被抽中的概率完全相等。

就像從一個裝滿小球的箱子裏隨機摸球一樣,每個球被摸到的機會都是一樣的。

它的典型應用場景有:

  • 滿意度調查:從全體用户中隨機抽取一部分發送滿意度調查問卷。
  • A/B測試用户分組:將參與測試的用户隨機分配到A組B組,確保兩組用户在初始狀態下沒有系統性差異。

下面是Python實現的一個簡單隨機抽樣示例。

先創建測試數據,這些數據在後面其他隨機抽樣示例中也會使用。

# 創建模擬數據集:某公司客户數據
np.random.seed(42)  # 設置隨機種子保證結果可重現
customer_data = pd.DataFrame({
    'customer_id': range(1, 1001),
    'age': np.random.randint(18, 70, 1000),
    'income': np.random.normal(50000, 15000, 1000).astype(int),
    'satisfaction_score': np.random.randint(1, 11, 1000)
})

print("原始數據集概況:")
print(f"數據量:{len(customer_data)}")
print(f"平均收入:{customer_data['income'].mean():.2f}")
print(f"平均滿意度:{customer_data['satisfaction_score'].mean():.2f}")

# 運行結果:
'''
原始數據集概況:
數據量:1000
平均收入:50863.12
平均滿意度:5.39
'''

然後進行簡單隨機抽樣:

# 簡單隨機抽樣
simple_random_sample = customer_data.sample(n=50, random_state=42)

print("簡單隨機抽樣結果:")
print(f"樣本量:{len(simple_random_sample)}")
print(f"樣本平均收入:{simple_random_sample['income'].mean():.2f}")
print(f"樣本平均滿意度:{simple_random_sample['satisfaction_score'].mean():.2f}")

# 運行結果:
'''
簡單隨機抽樣結果:
樣本量:50
樣本平均收入:48647.12
樣本平均滿意度:4.76
'''

抽樣數據總體數據相比,收入分佈滿意度分佈情況如下:

數據分析方法彙總(1)_mob604756f976e6的技術博客_應用場景_02

3.2. 分層隨機抽樣

分層隨機抽樣是先將總體按照某種特徵分成若干個互不重疊的“層”,然後在每個層內部分別進行簡單隨機抽樣。

這種方法可以保證樣本的結構與總體的結構相似,特別適用於總體內部差異較大的情況。

它的典型應用場景有:

  • 不同城市用户的消費習慣分析:為了解全國用户的消費習慣,可以先將用户按城市(如一線、新一線、二線城市)分層,再從每一層中按比例抽取用户進行研究,確保樣本中各城市的用户比例與總體一致。
  • 不同年級學生的學習情況調查:將學生按年級分層,再從各年級中抽取一定比例的學生進行調查。

下面是Python實現的一個分層隨機抽樣示例。

# 創建分層:按年齡分組
customer_data["age_group"] = pd.cut(
    customer_data["age"],
    bins=[0, 30, 45, 60, 100],
    labels=["青年", "中青年", "中年", "中老年"],
)

print("各年齡組人數:")
print(customer_data["age_group"].value_counts())

# 分層隨機抽樣:每層按比例抽取
stratified_sample = (
    customer_data.groupby("age_group", observed=False)
    .apply(
        lambda x: x.sample(frac=0.05, random_state=42),
        include_groups=False,
    )
    .reset_index()
)

print("\n分層隨機抽樣結果:")
print(f"樣本量:{len(stratified_sample)}")
print("樣本中各年齡組分佈:")
print(stratified_sample["age_group"].value_counts())

# 運行結果:
'''
各年齡組人數:
age_group
中青年    297
中年     282
青年     238
中老年    183
Name: count, dtype: int64

分層隨機抽樣結果:
樣本量:50
樣本中各年齡組分佈:
age_group
中青年    15
中年     14
青年     12
中老年     9
Name: count, dtype: int64
'''

分層隨機抽樣簡單隨機抽樣,以及總體數據對於平均收入的估計如下:

數據分析方法彙總(1)_mob604756f976e6的技術博客_數據_03

從圖中可以看出,分層隨機抽樣更接近於總體的值。

3.3. 系統隨機抽樣

系統隨機抽樣是將總體中的所有單位按一定順序排列,然後按照固定的間隔(步長)來抽取樣本。

比如,從1000人中抽取100人,可以每隔10人抽取1人。

它的典型應用場景有:

  • 生產線產品質量檢測:每隔100件產品,抽取1件進行質量檢測。
  • 電話調查:從電話號碼簿中,每隔50個號碼抽取一個進行訪問。

下面是Python實現的一個系統隨機抽樣示例。

# 系統隨機抽樣
def systematic_sampling(data, step):
    start = np.random.randint(0, step)
    indices = range(start, len(data), step)
    return data.iloc[indices]


systematic_sample = systematic_sampling(customer_data, 20)  # 每20個抽1個

print("系統隨機抽樣結果:")
print(f"樣本量:{len(systematic_sample)}")
print(f"樣本平均收入:{systematic_sample['income'].mean():.2f}")

# 運行結果:
'''
系統隨機抽樣結果:
樣本量:50
樣本平均收入:50763.34
'''

系統隨機抽樣的示意圖如下:

數據分析方法彙總(1)_mob604756f976e6的技術博客_Python_04

3.4. 整羣隨機抽樣

整羣隨機抽樣是將總體劃分為若干個互不重疊的“羣”,然後隨機抽取其中的若干個羣,對抽中的羣裏的所有單位進行調查。

它的典型應用場景是:

  • 城市居民健康調查:將城市劃分為若干個社區(羣),隨機抽取幾個社區,然後對這幾個社區的所有居民進行健康調查。
  • 全國多所學校的學生視力普查:將全國的學校作為“羣”,隨機抽取幾十所學校,然後對這些學校的所有學生進行視力檢查。

下面是Python實現的一個整羣隨機抽樣示例。

# 創建模擬的羣組數據:假設客户按地區分組
regions = ['北京', '上海', '廣州', '深圳', '杭州', '成都', '武漢', '西安']
customer_data['region'] = np.random.choice(regions, len(customer_data))

print("各地區客户數量:")
print(customer_data['region'].value_counts())

# 整羣隨機抽樣:隨機選擇3個地區,調查這些地區的所有客户
selected_regions = np.random.choice(regions, size=3, replace=False)
cluster_sample = customer_data[customer_data['region'].isin(selected_regions)]

print(f"\n抽中的地區:{selected_regions}")
print("整羣隨機抽樣結果:")
print(f"樣本量:{len(cluster_sample)}")
print(f"樣本平均收入:{cluster_sample['income'].mean():.2f}")
print(f"總體平均收入:{customer_data['income'].mean():.2f}")

# 運行結果:
'''
各地區客户數量:
region
武漢    141
廣州    133
成都    132
杭州    124
北京    120
上海    118
深圳    116
西安    116
Name: count, dtype: int64

抽中的地區:['杭州' '深圳' '武漢']
整羣隨機抽樣結果:
樣本量:381
樣本平均收入:50319.75
總體平均收入:50863.12
'''

整羣隨機抽樣得到的平均收入與總體數據的比較如下圖:它們的值非常接近。

數據分析方法彙總(1)_mob604756f976e6的技術博客_應用場景_05

4. 隨機抽樣綜合比較

為了更直觀地感受不同抽樣方法帶來的差異,我們從同一個數據集中,使用不同的方法抽取大約相同規模的樣本,來比較各種抽樣方法。

# 創建更復雜的數據集來演示各種抽樣方法
np.random.seed(42)
company_data = pd.DataFrame(
    {
        "employee_id": range(1, 1001),
        "department": np.random.choice(
            ["技術", "銷售", "市場", "人事", "財務"],
            1000,
            p=[0.3, 0.25, 0.2, 0.15, 0.1],
        ),
        "salary": np.random.normal(80000, 20000, 1000).astype(int),
        "experience": np.random.exponential(5, 1000).astype(int) + 1,
    }
)

# 修正可能的負工資
company_data["salary"] = company_data["salary"].clip(lower=30000)

print("公司員工數據概況:")
print(f"總員工數:{len(company_data)}")
print(f"平均工資:{company_data['salary'].mean():.2f}")
print("\n各部門人數:")
print(company_data["department"].value_counts())

# 應用不同抽樣方法
samples = {
    "簡單隨機抽樣": company_data.sample(n=100, random_state=42),
    "分層隨機抽樣": company_data.groupby("department")
    .apply(lambda x: x.sample(frac=0.1, random_state=42), include_groups=False)
    .reset_index(),
    "系統隨機抽樣": systematic_sampling(company_data, 10),
    "整羣隨機抽樣": company_data[
        company_data["department"].isin(
            np.random.choice(company_data["department"].unique(), 2, replace=False)
        )
    ],
}

# 比較結果
comparison = pd.DataFrame(
    {
        "方法": ["總體"] + list(samples.keys()),
        "樣本量": [len(company_data)] + [len(sample) for sample in samples.values()],
        "平均工資": [company_data["salary"].mean()]
        + [sample["salary"].mean() for sample in samples.values()],
        "工資誤差": [0]
        + [
            abs(sample["salary"].mean() - company_data["salary"].mean())
            for sample in samples.values()
        ],
    }
)

print("\n各種抽樣方法比較:")
print(comparison)

# 運行結果:
'''
公司員工數據概況:
總員工數:1000
平均工資:82015.16

各部門人數:
department
技術    319
銷售    240
市場    198
人事    143
財務    100
Name: count, dtype: int64
'''

數據分析方法彙總(1)_mob604756f976e6的技術博客_Python_06

數據分析方法彙總(1)_mob604756f976e6的技術博客_應用場景_07

5. 總結

本文介紹了常用的抽樣方法,並給出了各種抽樣方法的典型應用場景以及Python代碼實現方式。

重點是四種隨機抽樣的方法,選擇抽樣方法時需要考慮:

  • 研究目的:探索性分析可用非隨機抽樣,正式研究需用隨機抽樣
  • 總體特徵:如果總體有明顯分層,考慮分層抽樣
  • 資源限制:整羣抽樣通常成本較低
  • 精度要求:分層抽樣通常精度較高

記住,沒有 "最好" 的抽樣方法,只有 "最合適" 的。

在實際工作中,要根據具體情況靈活選擇和組合使用不同的抽樣方法。