最强总结,十大统计检验方法 !!

文摘   2024-11-01 11:16   北京  

哈喽,我是小白~

今儿再来和大家聊聊统计检验方法的内容~

统计检验方法 帮助验证模型的假设和结果的显著性,确保模型的有效性和泛化能力。通过统计检验,可以判断模型的表现是否优于基线或仅仅是偶然性结果。它们还用于评估特征的重要性,帮助选择最有意义的变量,从而提高模型的性能。

涉及到的有:

  • T检验
  • 卡方检验
  • 方差分析
  • 皮尔逊相关系数检验
  • 正态性检验
  • 非参数检验
  • 方差齐性检验
  • Kolmogorov-Smirnov检验
  • 逻辑回归检验
  • 线性回归检验

如果需要本文PDF版本的同学,文末获取~

另外,文末有总结性的干货~

一起来看下具体细化内容~

1. T检验 (T-Test)

T检验用于比较两个样本均值是否显著不同。根据具体情况,T检验分为单样本T检验、独立样本T检验和配对样本T检验。T检验的假设是样本数据来自正态分布,且方差齐性。

原理

T检验基于假设检验的框架,利用T统计量比较样本均值差异,并通过查找T分布表来决定是否拒绝原假设。

核心公式

对于独立样本T检验,T统计量的公式为:

其中:

  •  和  是两个样本的均值。
  •  和  是两个样本的方差。
  •  和  是两个样本的样本量。

公式推导

1. 原假设与备择假设:

  • 原假设 ,即两个样本的总体均值相等。
  • 备择假设 ,即两个样本的总体均值不等。

2. 样本均值差:

  • 计算样本均值差:

3. 标准误:

  • 标准误的计算基于两个样本的方差和样本量:
  • 其中, 和  是样本的样本方差,分别表示样本1和样本2的方差, 和  是样本量。

4. T统计量:

  • 计算T统计量:

5. 自由度:

  • 自由度计算公式为:

6. 检验决策:

  • 根据T统计量和自由度,查找T分布表得出p值。如果p值小于显著性水平(通常为0.05),则拒绝原假设,认为两个样本均值显著不同。

Python实现

我们有两组学生的考试成绩,分别来自两个不同的教学方法(方法A和方法B)。我们想要检验这两组学生的平均成绩是否存在显著差异。

  1. 生成两组学生的考试成绩(虚拟数据集)。
  2. 对这两组数据进行T检验。
  3. 画出两组数据的分布图(如直方图、密度图)和箱线图,以可视化数据差异。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import ttest_ind

# 设置随机种子以便重现
np.random.seed(42)

# 生成虚拟数据集
group_A_scores = np.random.normal(loc=75, scale=10, size=100)  # 方法A的成绩,均值75,标准差10
group_B_scores = np.random.normal(loc=70, scale=12, size=100)  # 方法B的成绩,均值70,标准差12

# 进行独立样本T检验
t_stat, p_value = ttest_ind(group_A_scores, group_B_scores)

# 打印T检验结果
print(f"T检验统计量: {t_stat:.2f}")
print(f"P值: {p_value:.4f}")

# 创建一个DataFrame来存储数据
df = pd.DataFrame({
    'Scores': np.concatenate([group_A_scores, group_B_scores]),
    'Group': ['A'] * len(group_A_scores) + ['B'] * len(group_B_scores)
})

# 设置图形大小
plt.figure(figsize=(147))

# 子图1:直方图和密度图
plt.subplot(121)
sns.histplot(df, x="Scores", hue="Group", kde=True, stat="density", common_norm=False, palette="dark", alpha=0.6)
plt.title('Score Distribution (Histogram & Density)')

# 子图2:箱线图和小提琴图
plt.subplot(122)
sns.boxplot(x='Group', y='Scores', data=df, palette="Set2", showmeans=True)
sns.violinplot(x='Group', y='Scores', data=df, palette="Set2", inner=None, alpha=0.3)
plt.title('Boxplot & Violin Plot of Scores')

# 显示图形
plt.tight_layout()
plt.show()
  • group_A_scores 和 group_B_scores 是两个正态分布的虚拟数据集,分别代表使用方法A和方法B的学生成绩。
  • 使用 ttest_ind 进行独立样本T检验,判断两组数据的平均值是否有显著差异。
  • 使用 seaborn 和 matplotlib 生成图表。
    • 第一个子图是成绩的直方图和密度图,用来查看两组数据的分布情况。
    • 第二个子图是成绩的箱线图和小提琴图,用来查看数据的集中趋势和分布差异。

  • 图表会展示两组数据的分布及其差异,并显示出T检验的统计量和P值。
  • 如果P值很小(通常小于0.05),可以认为两组数据的平均值存在显著差异。

2. 卡方检验 (Chi-Square Test)

卡方检验用于检验两个分类变量之间是否存在关联,或检验一个变量的观测频率与期望频率是否有显著差异。常见的卡方检验包括独立性检验和拟合优度检验。

原理

卡方检验通过计算观测频率与期望频率之间的差异,判断该差异是否足够显著以拒绝原假设。卡方统计量遵循卡方分布,用于判断变量之间的独立性或分布的适合度。

核心公式

卡方统计量的计算公式为:

其中:

  •  是第i个类别的观测频率。
  •  是第i个类别的期望频率。

公式推导

1. 原假设与备择假设:

  • 原假设 :观测频率与期望频率相符,或两个变量独立。
  • 备择假设 :观测频率与期望频率不符,或两个变量不独立。

2. 计算期望频率:

  • 对于独立性检验,期望频率的计算公式为:

其中  是行总和, 是列总和, 是样本总数。

3. 计算卡方统计量:

  • 计算每个类别的卡方值:
  • 将所有类别的卡方值相加,得到总的卡方统计量:

4. 自由度:

  • 对于独立性检验,自由度为:

其中r是行数,c是列数。

5. 检验决策:

  • 查表或计算p值,如果p值小于显著性水平,则拒绝原假设。

Python实现

假设有一个虚拟的市场调查数据集,数据集包含以下两个分类变量:

  1. 购买的产品类型(Product Type):包括A类产品、B类产品和C类产品。
  2. 客户年龄组(Age Group):包括18-25岁、26-35岁和36-45岁。

想通过卡方检验来判断客户的年龄组与购买的产品类型是否存在关联性。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import chi2_contingency

# 创建虚拟数据集
np.random.seed(42)
data = {
    'Age Group': np.random.choice(['18-25''26-35''36-45'], size=300, p=[0.30.40.3]),
    'Product Type': np.random.choice(['Product A''Product B''Product C'], size=300, p=[0.40.30.3])
}

df = pd.DataFrame(data)

# 创建交叉表(列联表)
contingency_table = pd.crosstab(df['Age Group'], df['Product Type'])

# 执行卡方检验
chi2, p, dof, expected = chi2_contingency(contingency_table)

# 输出卡方检验结果
print("Chi-Square Statistic:", chi2)
print("P-value:", p)
print("Degrees of Freedom:", dof)
print("Expected Frequencies:\n", expected)

# 绘制数据分析的图形
fig, ax = plt.subplots(22, figsize=(1512))

# 图1:热力图(显示实际的交叉表数据)
sns.heatmap(contingency_table, annot=True, fmt='d', cmap='Blues', ax=ax[00])
ax[00].set_title('Observed Frequencies (Heatmap)')
ax[00].set_xlabel('Product Type')
ax[00].set_ylabel('Age Group')

# 图2:热力图(显示期望的频数数据)
sns.heatmap(expected, annot=True, fmt='.2f', cmap='Oranges', ax=ax[01])
ax[01].set_title('Expected Frequencies (Heatmap)')
ax[01].set_xlabel('Product Type')
ax[01].set_ylabel('Age Group')

# 图3:堆叠条形图(展示不同年龄组的产品购买情况)
contingency_table.plot(kind='bar', stacked=True, ax=ax[10], colormap='viridis')
ax[10].set_title('Product Type by Age Group (Stacked Bar)')
ax[10].set_xlabel('Age Group')
ax[10].set_ylabel('Frequency')

# 图4:群组条形图(展示不同产品类型的年龄组分布)
contingency_table.T.plot(kind='bar', ax=ax[11], colormap='Set2')
ax[11].set_title('Age Group by Product Type (Grouped Bar)')
ax[11].set_xlabel('Product Type')
ax[11].set_ylabel('Frequency')

plt.tight_layout()
plt.show()
  1. 虚拟数据集创建:数据集包含300个样本,Age Group 和 Product Type 为分类变量,按照给定概率随机生成。

  2. 卡方检验:使用pd.crosstab生成交叉表,并用chi2_contingency执行卡方检验,得到卡方统计量、p值、自由度和期望频数。

  3. 数据可视化

  • 热力图:第一幅热力图展示了实际的观测频数(Observed Frequencies)。第二幅热力图展示了卡方检验计算出的期望频数(Expected Frequencies)。
  • 堆叠条形图:展示了不同年龄组购买不同产品的分布情况,条形堆叠显示各类产品的占比。
  • 群组条形图:展示了每种产品类型在不同年龄组中的分布情况。

3. 方差分析 (ANOVA)

方差分析(ANOVA)用于比较三个或更多组的均值是否存在显著差异。ANOVA的核心在于分析组间方差与组内方差的比值,通常用于处理多个样本的情况。

原理

ANOVA通过计算F统计量,即组间方差与组内方差的比值,来评估组均值之间的差异是否显著。F分布用于确定该比值是否大到足以拒绝原假设。

核心公式

ANOVA中F统计量的计算公式为:

其中:

  • 组间均方差 (MSB) 计算公式:
  • 组内均方差 (MSW) 计算公式:

其中:

  •  是组间平方和
  •  是组内平方和
  •  是第i组的样本数
  •  是总样本数
  •  是组的数量

公式推导

1. 原假设与备择假设:

  • 原假设 :所有组的均值相等,即 
  • 备择假设 :至少有一个组的均值不同。

2. 组间平方和 (SSB):

  • 组间平方和  反映了各组均值与总体均值的差异:

其中  是第i组的均值, 是总体均值, 是第i组的样本量。

3. 组内平方和 (SSW):

  • 组内平方和  反映了各组内部的变

异性:

其中  是第i组第j个样本的值。

4. 组间均方差 (MSB):

  • 组间均方差  为组间平方和除以自由度:

5. 组内均方差 (MSW):

  • 组内均方差  为组内平方和除以自由度:

6. F统计量:

  • 计算F统计量:

如果F值较大,说明组间方差较大,相比组内方差,更有可能拒绝原假设。

7. 检验决策:

  • 查表或计算p值,p值小于显著性水平时,拒绝原假设。

Python实现

假设有三个不同的药物(A, B, C),它们对患者的血压变化有不同的效果。我们希望通过 ANOVA 检验药物种类对血压变化是否有显著的影响。

我们生成一个虚拟的数据集,其中包括三个药物的血压变化数据:

  1. 一个箱线图(Boxplot)来展示各组的分布情况。
  2. 一个平均值的误差条形图(Error Bar Plot)来展示各组的均值和标准误。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import scipy.stats as stats
import statsmodels.api as sm
from statsmodels.formula.api import ols

# 设置随机种子以保证结果可重复
np.random.seed(42)

# 生成虚拟数据集
n = 300  # 每组样本数量
group_A = np.random.normal(loc=120, scale=5, size=n)  # 药物A的血压变化
group_B = np.random.normal(loc=115, scale=7, size=n)  # 药物B的血压变化
group_C = np.random.normal(loc=130, scale=6, size=n)  # 药物C的血压变化

# 创建数据框
df = pd.DataFrame({
    'Blood_Pressure_Change': np.concatenate([group_A, group_B, group_C]),
    'Drug': ['A']*n + ['B']*n + ['C']*n
})

# 方差分析 (ANOVA)
model = ols('Blood_Pressure_Change ~ C(Drug)', data=df).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
print(anova_table)

# 画图
plt.figure(figsize=(147))

# 子图1:箱线图
plt.subplot(121)
sns.boxplot(x='Drug', y='Blood_Pressure_Change', data=df)
plt.title('Blood Pressure Change by Drug (Boxplot)')
plt.xlabel('Drug')
plt.ylabel('Blood Pressure Change')

# 子图2:均值误差条形图
plt.subplot(122)
sns.pointplot(x='Drug', y='Blood_Pressure_Change', data=df, capsize=.2)
plt.title('Mean Blood Pressure Change by Drug with Error Bars')
plt.xlabel('Drug')
plt.ylabel('Mean Blood Pressure Change')

plt.tight_layout()
plt.show()
  1. 数据生成group_Agroup_Bgroup_C 分别代表三种药物的血压变化数据,遵循正态分布,但均值和标准差不同。这些数据通过 np.random.normal() 生成。

  2. 方差分析:使用 ols 函数建立线性模型,并通过 anova_lm 进行方差分析。输出的 anova_table 用于显示方差分析的结果。

  3. 图表绘制

    1. 箱线图:展示了三组数据的分布情况,可以直观地看到不同药物组的中位数、分布范围以及异常值。
    2. 均值误差条形图:展示了各组的平均血压变化以及误差条,误差条代表均值的置信区间,从中可以看出均值的差异是否具有统计学意义。

4. 皮尔逊相关系数检验 (Pearson Correlation Test)

皮尔逊相关系数用于衡量两个连续变量之间的线性相关性,值介于-1到1之间。皮尔逊相关系数为0表示没有线性相关性。

原理

皮尔逊相关系数通过计算两个变量的协方差与标准差的比值来衡量它们的线性关系。如果协方差为正,说明两个变量同向变化;协方差为负,说明两个变量反向变化。

核心公式

皮尔逊相关系数的计算公式为:

其中:

  •  和  是变量X和Y的均值
  •  和  是变量X和Y的样本值

公式推导

1. 计算均值:

  • 计算变量X和Y的均值:

2. 计算协方差:

  • 计算协方差:

3. 计算标准差:

  • 计算X和Y的标准差:

4. 计算皮尔逊相关系数:

  • 计算皮尔逊相关系数:

5. 检验相关性显著性:

  • 使用T检验判断相关性显著性:

其中自由度为 

6. 检验决策:

  • 根据T值查表判断p值,如果p值小于显著性水平,认为相关性显著。

Python实现

这个案例模拟了研究两个变量之间的线性关系,一个变量是学生的学习时间,另一个变量是他们的考试成绩。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr
from sklearn.linear_model import LinearRegression

# 生成虚拟数据
np.random.seed(42)
study_hours = np.random.normal(52100)  # 学习时间(小时)
exam_scores = 50 + 10 * study_hours + np.random.normal(05100)  # 考试成绩

# 创建 DataFrame
data = pd.DataFrame({
    'Study Hours': study_hours,
    'Exam Scores': exam_scores
})

# 计算皮尔逊相关系数
corr, p_value = pearsonr(data['Study Hours'], data['Exam Scores'])

# 线性回归
X = data['Study Hours'].values.reshape(-11)
y = data['Exam Scores'].values.reshape(-11)
reg = LinearRegression().fit(X, y)
data['Predicted Scores'] = reg.predict(X)
data['Residuals'] = y - data['Predicted Scores']

# 绘图
fig, axs = plt.subplots(22, figsize=(1512))

# 散点图和回归线
sns.scatterplot(x='Study Hours', y='Exam Scores', data=data, ax=axs[00])
sns.lineplot(x='Study Hours', y='Predicted Scores', data=data, color='red', ax=axs[00])
axs[00].set_title('Scatter Plot with Regression Line')
axs[00].text(0.050.95f'Pearson r = {corr:.2f}\nP-value = {p_value:.2e}'
               transform=axs[00].transAxes, fontsize=12, verticalalignment='top')

# 残差图
sns.residplot(x='Study Hours', y='Exam Scores', data=data, ax=axs[01])
axs[01].set_title('Residual Plot')

# 学习时间和成绩的分布图
sns.histplot(data['Study Hours'], kde=True, color='blue', ax=axs[10], bins=15)
sns.histplot(data['Exam Scores'], kde=True, color='green', ax=axs[10], bins=15)
axs[10].set_title('Distribution of Study Hours and Exam Scores')
axs[10].legend(['Study Hours''Exam Scores'])

# 相关系数热力图
corr_matrix = data[['Study Hours''Exam Scores']].corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', ax=axs[11])
axs[11].set_title('Correlation Heatmap')

plt.tight_layout()
plt.show()
  • 虚拟数据集: 使用正态分布生成100个学生的学习时间,并使用一个简单的线性模型(加上噪声)生成对应的考试成绩。
  • 皮尔逊相关系数检验: 通过pearsonr函数计算学习时间和考试成绩之间的皮尔逊相关系数。
  • 线性回归: 通过线性回归拟合学习时间与考试成绩的关系,并计算预测值和残差。
  • 绘制图形: 生成四个图:
  1. 散点图和回归线: 展示两个变量的关系并添加线性回归线。
  2. 残差图: 显示残差,以检验线性模型的适合程度。
  3. 分布图: 展示两个变量的分布情况。
  4. 相关系数热力图: 直观展示两个变量之间的相关性。

5. 正态性检验 (Normality Test, 如Shapiro-Wilk Test)

正态性检验用于判断样本数据是否来自正态分布。Shapiro-Wilk检验是一种常用的正态性检验方法,尤其适用于小样本。

原理

Shapiro-Wilk检验通过比较样本数据的排序统计量与正态分布的理论排序值,计算W统计量以检测数据的正态性。

核心公式

Shapiro-Wilk检验的W统计量公式为:

其中  是由正态分布期望排序值和样本协方差矩阵计算得到的常数, 是排序后的样本数据, 是样本均值。

公式推导

1. 排序样本:

  • 将样本数据从小到大排序,得到排序后的样本 

2. 计算权重 :

  •  是基于样本量n和期望值计算得到的常数,具体计算较为复杂,通常依赖于统计软件。

3. 计算W统计量:

  • 计算W统计量:

4. 检验决策:

  • 根据样本大小查表或使用统计软件计算p值,如果p值小于显著性水平,拒绝正态性假设。

Python实现

使用虚拟数据集进行Shapiro-Wilk检验,并通过多个图形来可视化数据的分布情况和检验结果。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import shapiro, probplot

# 生成虚拟数据集
np.random.seed(0)
# 正态分布数据
normal_data = np.random.normal(loc=0, scale=1, size=1000)
# 非正态分布数据(对数正态分布)
non_normal_data = np.random.lognormal(mean=0, sigma=1, size=1000)

# Shapiro-Wilk 检验
shapiro_normal = shapiro(normal_data)
shapiro_non_normal = shapiro(non_normal_data)

# 创建图形
plt.figure(figsize=(1410))

# 1. 正态分布数据的直方图和核密度图
plt.subplot(221)
sns.histplot(normal_data, kde=True, color='skyblue')
plt.title(f'Normal Data Histogram & KDE\nShapiro-Wilk p-value: {shapiro_normal.pvalue:.4f}')

# 2. 非正态分布数据的直方图和核密度图
plt.subplot(222)
sns.histplot(non_normal_data, kde=True, color='salmon')
plt.title(f'Non-Normal Data Histogram & KDE\nShapiro-Wilk p-value: {shapiro_non_normal.pvalue:.4f}')

# 3. 正态分布数据的Q-Q图
plt.subplot(223)
probplot(normal_data, dist="norm", plot=plt)
plt.title('Normal Data Q-Q Plot')

# 4. 非正态分布数据的Q-Q图
plt.subplot(224)
probplot(non_normal_data, dist="norm", plot=plt)
plt.title('Non-Normal Data Q-Q Plot')

# 调整布局
plt.tight_layout()
plt.show()
  1. 数据生成:生成一个遵循正态分布的虚拟数据集 (normal_data) 和一个遵循对数正态分布的虚拟数据集 (non_normal_data)。
  2. Shapiro-Wilk检验:对两个数据集分别进行Shapiro-Wilk正态性检验,并计算出p值。
  3. 数据可视化
  • 直方图和核密度估计图:分别展示正态分布和非正态分布数据的直方图和核密度图,并在图中标注Shapiro-Wilk检验的p值。
  • Q-Q图:展示正态分布和非正态分布数据的Q-Q图(Quantile-Quantile plot),用于判断数据分布与正态分布的吻合程度。

6. 非参数检验 (Non-parametric Tests, 如Mann-Whitney U检验)

非参数检验用于比较两个独立样本的中位数或分布形态,适用于数据不满足正态性假设或方差齐性假设的情况。Mann-Whitney U检验是常用的非参数检验之一。

原理

Mann-Whitney U检验通过比较两个样本的秩和来判断两个样本是否来自相同的分布。U统计量用于评估样本分布的差异。

核心公式

Mann-Whitney U检验的U统计量计算公式为:

其中:

  •  和  是两个样本的大小
  •  是第一个样本的秩和

公式推导

1. 排序:

  • 将两个样本的数据合并后,从小到大排序,并为每个数据赋予秩次。

2. 计算秩和:

  • 计算每个样本的秩和,分别为  和 

3. 计算U统计量:

  • 计算U统计量:
  • 同样计算 ,并取较小者作为U统计量:

4. 正态近似(适用于大样本):

  • 当样本量较大时,U统计量可近似服从正态分布:

其中  和  分别是U统计量的均值和标准差。

5. 检验决策:

  • 根据U统计量查表或计算p值,如果p值小于显著性水平,则拒绝原假设。

Python实现

假设有两个不同药物A和B的治疗效果数据,我们想要比较这两种药物在两组患者中的疗效是否有显著差异。因为我们无法确定数据是否服从正态分布,所以使用非参数检验中的Mann-Whitney U检验来进行比较。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import mannwhitneyu

# 设置随机种子
np.random.seed(42)

# 生成虚拟数据集
group_A = np.random.normal(loc=55, scale=10, size=100)
group_B = np.random.normal(loc=60, scale=15, size=100)

# 创建DataFrame
df = pd.DataFrame({
    'Treatment': ['A']*100 + ['B']*100,
    'Effectiveness': np.concatenate([group_A, group_B])
})

# Mann-Whitney U检验
stat, p = mannwhitneyu(group_A, group_B)
print(f'Mann-Whitney U 检验结果: 统计量={stat}, p值={p}')

# 设置绘图样式
sns.set(style="whitegrid")

# 创建图形对象
plt.figure(figsize=(147))

# 子图1: 箱线图
plt.subplot(121)
sns.boxplot(x='Treatment', y='Effectiveness', data=df, palette="Set3")
plt.title('Boxplot of Treatment Effectiveness')

# 子图2: 小提琴图
plt.subplot(122)
sns.violinplot(x='Treatment', y='Effectiveness', data=df, palette="Set3")
plt.title('Violin Plot of Treatment Effectiveness')

# 显示图形
plt.tight_layout()
plt.show()
  1. 数据生成:我们生成了两个不同的正态分布数据,分别代表两种药物的治疗效果。group_A 和 group_B表示药物A和B的数据,分别有100个样本。

  2. Mann-Whitney U 检验:我们使用 scipy.stats.mannwhitneyu 函数对两个药物的数据进行Mann-Whitney U检验,计算统计量和p值。

  3. 可视化

  • 我们使用Seaborn库绘制两个子图:箱线图和小提琴图,展示药物A和B的治疗效果分布。
  • 箱线图展示了数据的中位数、四分位数和潜在的异常值。
  • 小提琴图结合了箱线图和密度图的信息,能够展示出数据分布的更多细节。

7. 方差齐性检验 (Levene's Test)

Levene检验用于检验多个组的方差是否相等。方差齐性检验是方差分析等统计方法的前提假设之一。

原理

Levene检验通过计算各组到组内中位数或均值的绝对偏差,并比较这些偏差之间的差异,评估各组

方差是否相等。

核心公式

Levene检验的F统计量计算公式为:

其中:

  •  是第i组的偏差均值
  •  是总体偏差均值
  •  是第i组的样本量
  •  是组数

公式推导

1. 计算偏差:

  • 计算每个样本的偏差 

2. 计算各组的偏差均值:

  • 计算每组的偏差均值 

3. 计算总体偏差均值:

  • 计算所有样本的总体偏差均值 

4. 计算F统计量:

  • 计算Levene检验的F统计量:

5. 检验决策:

  • 查表或计算p值,如果p值小于显著性水平,则拒绝方差齐性假设。

Python实现

使用Python进行Levene's Test(方差齐性检验)的完整代码,包括生成虚拟数据、进行方差齐性检验以及绘制数据分析图形。

import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns

# 生成虚拟数据集
np.random.seed(42)

# 组1:正态分布,较小方差
group1 = np.random.normal(loc=50, scale=5, size=100)

# 组2:正态分布,较大方差
group2 = np.random.normal(loc=50, scale=15, size=100)

# 组3:偏态分布,较大方差
group3 = np.random.gamma(shape=2, scale=10, size=100)

# 整合数据
data = pd.DataFrame({
    'Value': np.concatenate([group1, group2, group3]),
    'Group': ['Group 1']*100 + ['Group 2']*100 + ['Group 3']*100
})

# 进行Levene's Test
levene_stat, levene_p = stats.levene(group1, group2, group3)

print(f"Levene's Test Statistic: {levene_stat:.3f}")
print(f"P-value: {levene_p:.3f}")

# 图形可视化
plt.figure(figsize=(148))

# 子图1: 箱线图
plt.subplot(221)
sns.boxplot(x='Group', y='Value', data=data, palette='Set2')
plt.title("Boxplot of Values by Group")
plt.xlabel("Group")
plt.ylabel("Value")

# 子图2: 散点图(带抖动)
plt.subplot(222)
sns.stripplot(x='Group', y='Value', data=data, jitter=True, palette='Set1')
plt.title("Stripplot of Values by Group")
plt.xlabel("Group")
plt.ylabel("Value")

# 子图3: 密度图
plt.subplot(223)
sns.kdeplot(group1, shade=True, label='Group 1', color='blue')
sns.kdeplot(group2, shade=True, label='Group 2', color='orange')
sns.kdeplot(group3, shade=True, label='Group 3', color='green')
plt.title("Density Plot of Values by Group")
plt.xlabel("Value")
plt.ylabel("Density")
plt.legend()

# 子图4: Q-Q图
plt.subplot(224)
stats.probplot(group2, dist="norm", plot=plt)
plt.title("Q-Q Plot of Group 2")

plt.tight_layout()
plt.show()
  1. 数据生成:生成了三个不同组的数据,其中Group 1Group 2为正态分布,但具有不同的方差;Group 3则来自于伽马分布,并且方差较大。

  2. Levene's Test:使用scipy.stats.levene函数来进行Levene's方差齐性检验,以确定这三个组的方差是否相同。

  3. 数据可视化:

  • 箱线图: 直观地展示各组数据的分布和离群值。
  • 散点图: 带有抖动的散点图展示每个样本数据点的分布情况。
  • 密度图: 对比不同组的概率密度分布。
  • Q-Q图: 检查Group 2是否符合正态分布。

8. 科尔莫哥洛夫-斯米尔诺夫检验 (Kolmogorov-Smirnov Test, KS检验)

KS检验用于比较样本分布与理论分布的相似性,或比较两个样本分布是否相同。它是一种非参数检验方法,常用于正态性检验等场景。

原理

KS检验通过计算经验分布函数与理论分布函数之间的最大差值,判断它们的差异。KS统计量衡量这个最大差值,并通过它来判断两个分布的相似性。

核心公式

KS检验的统计量  计算公式为:

其中:

  •  是样本的经验分布函数
  •  是理论分布函数

公式推导

1. 计算经验分布函数:

  • 经验分布函数  是样本在每个点的累积频率:

2. 计算理论分布函数:

  • 根据假设的分布(如正态分布),计算理论分布函数 

3. 计算KS统计量:

  • KS统计量  是两个分布函数之间的最大绝对差值:

4. 检验决策:

  • 根据样本量和KS统计量查表或计算p值。如果p值小于显著性水平,拒绝原假设。

Python实现

下面是一个使用虚拟数据集来进行科尔莫哥洛夫-斯米尔诺夫检验(Kolmogorov-Smirnov Test, KS检验)的案例,给大家展示的是如何比较两个样本的分布,以及如何使用KS检验来检验它们是否来自同一个分布。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# 生成两个虚拟数据集
np.random.seed(42)
data1 = np.random.normal(loc=0, scale=1, size=1000)  # 正态分布, 均值为0, 标准差为1
data2 = np.random.normal(loc=0.5, scale=1.2, size=1000)  # 正态分布, 均值为0.5, 标准差为1.2

# 进行KS检验
ks_statistic, p_value = stats.ks_2samp(data1, data2)

# 打印检验结果
print(f"KS Statistic: {ks_statistic}")
print(f"P-value: {p_value}")

# 创建图形
fig, ax = plt.subplots(12, figsize=(146))

# 图1: 数据分布图(直方图)
ax[0].hist(data1, bins=30, alpha=0.5, label='Data1: N(0, 1)', color='blue')
ax[0].hist(data2, bins=30, alpha=0.5, label='Data2: N(0.5, 1.2)', color='red')
ax[0].legend(loc='upper right')
ax[0].set_title('Histogram of Data1 and Data2')
ax[0].set_xlabel('Value')
ax[0].set_ylabel('Frequency')

# 图2: 累积分布函数(CDF)图
# 计算CDF
x = np.linspace(min(data1.min(), data2.min()), max(data1.max(), data2.max()), 1000)
cdf1 = np.array([np.sum(data1 <= xi) / len(data1) for xi in x])
cdf2 = np.array([np.sum(data2 <= xi) / len(data2) for xi in x])

# 绘制CDF
ax[1].plot(x, cdf1, label='Data1 CDF', color='blue')
ax[1].plot(x, cdf2, label='Data2 CDF', color='red')
ax[1].legend(loc='lower right')
ax[1].set_title('CDF of Data1 and Data2')
ax[1].set_xlabel('Value')
ax[1].set_ylabel('Cumulative Probability')

# 显示图形
plt.suptitle(f'Kolmogorov-Smirnov Test: KS Statistic={ks_statistic:.3f}, P-value={p_value:.3f}', fontsize=16)
plt.show()
  1. 数据生成data1data2分别生成了两个正态分布的数据集。其中data1均值为0,标准差为1,而data2的均值为0.5,标准差为1.2。
  2. KS检验:使用scipy.stats.ks_2samp函数对两个数据集进行KS检验,输出KS统计量和p值。
  3. 图形展示
  • 第一个图展示两个数据集的直方图,用于比较它们的分布形态。
  • 第二个图展示了两个数据集的累积分布函数(CDF),用于可视化KS检验中的关键概念。

9. 逻辑回归检验 (Logistic Regression Test)

逻辑回归用于分析因变量为二分类变量的回归模型。它通过估计各自变量对因变量取1的概率的影响,常用于二分类问题。

原理

逻辑回归通过最大似然估计拟合模型,估计回归系数,并使用这些系数来预测二分类因变量的概率。Wald检验、似然比检验等方法用于评估模型的显著性。

核心公式

逻辑回归的模型为:

其中  是因变量取1的概率。

公式推导

1. 定义模型:

  • 逻辑回归模型为:

2. 最大似然估计:

  • 通过最大似然估计(MLE)求解参数 。似然函数为:

其中  是第i个样本的因变量值(0或1)。

3. 对数似然函数:

  • 对数似然函数为:

4. Wald检验:

  • 使用Wald检验来检验每个回归系数  的显著性:

其中  是估计系数的标准误。

5. 似然比检验:

  • 通过比较带和不带某个变量的模型的似然值,检验该变量的显著性:

G统计量服从卡方分布。

6. 检验决策:

  • 使用Wald检验或似然比检验计算p值,判断各自变量的显著性。

Python实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay, roc_curve, auc

# 生成虚拟数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5
                           n_classes=2, random_state=42)

# 分割数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 建立逻辑回归模型
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]

# 混淆矩阵
cm = confusion_matrix(y_test, y_pred)
cmd = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=model.classes_)

# ROC曲线
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)

# 绘图
fig, ax = plt.subplots(12, figsize=(146))

# 绘制混淆矩阵
cmd.plot(ax=ax[0])
ax[0].set_title('Confusion Matrix')

# 绘制ROC曲线
ax[1].plot(fpr, tpr, color='blue', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
ax[1].plot([01], [01], color='gray', linestyle='--')
ax[1].set_xlim([0.01.0])
ax[1].set_ylim([0.01.05])
ax[1].set_xlabel('False Positive Rate')
ax[1].set_ylabel('True Positive Rate')
ax[1].set_title('Receiver Operating Characteristic')
ax[1].legend(loc='lower right')

# 显示图形
plt.tight_layout()
plt.show()
  1. 生成数据集:使用make_classification函数生成一个有1000个样本和20个特征的二元分类数据集。
  2. 分割数据集:将数据集分割为训练集和测试集。
  3. 模型训练:使用逻辑回归模型进行训练。
  4. 模型预测:对测试集进行预测,并计算预测概率。
  5. 绘制混淆矩阵:使用ConfusionMatrixDisplay展示预测结果的混淆矩阵。
  6. 绘制ROC曲线:计算并绘制ROC曲线,显示模型的分类性能。

10. 线性回归检验 (Linear Regression Test)

线性回归用于分析因变量与一个或多个自变量之间的线性关系。最小二乘法用于拟合回归模型,并使用统计检验评估模型和自变量的显著性。

原理

线性回归通过最小化残差平方和拟合模型,估计回归系数。通过T检验和F检验分别检验回归系数的显著性和模型的整体显著性。

核心公式

线性回归模型为:

其中  是因变量, 是误差项。

公式推导

1. 定义模型:

  • 线性回归模型为:

2. 最小二乘法 (OLS):

  • 通过最小化残差平方和来估计参数 

3. 求解回归系数:

  • 求解OLS估计的矩阵形式为:

4. T检验:

  • T检验用于检验单个回归系数  的显著性:

其中  是估计系数的标准误。

5. F检验:

  • F检验用于检验整体模型的显著性:

F统计量服从  分布。

6. 检验决策:

  • 使用T检验和F检验计算p值,判断各自变量和整体模型的显著性。

Python实现

这个案例中,我们创建一个包含两列数据的虚拟数据集:X(自变量)和Y(因变量)。我们假设 Y 与 X存在线性关系,但带有一定的噪声。我们将使用线性回归来拟合这些数据:

  1. X 与 Y 的散点图及其线性回归拟合线。
  2. 线性回归残差的分布图。
  3. 残差图(Residual Plot):显示残差与预测值之间的关系。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# 生成虚拟数据集
np.random.seed(42)
X = 2 * np.random.rand(1001)
Y = 4 + 3 * X + np.random.randn(1001)

# 拟合线性回归模型
model = LinearRegression()
model.fit(X, Y)
Y_pred = model.predict(X)

# 计算残差
residuals = Y - Y_pred

# 创建子图
fig, axes = plt.subplots(22, figsize=(1410))

# 图1:散点图和拟合线
axes[00].scatter(X, Y, color='blue', label='Data')
axes[00].plot(X, Y_pred, color='red', linewidth=2, label='Fitted line')
axes[00].set_title('Scatter Plot with Linear Regression Line')
axes[00].set_xlabel('X')
axes[00].set_ylabel('Y')
axes[00].legend()

# 图2:残差的分布直方图
axes[01].hist(residuals, bins=20, color='green', edgecolor='black')
axes[01].set_title('Distribution of Residuals')
axes[01].set_xlabel('Residuals')
axes[01].set_ylabel('Frequency')

# 图3:残差图
axes[10].scatter(Y_pred, residuals, color='purple')
axes[10].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[10].set_title('Residual Plot')
axes[10].set_xlabel('Predicted Values')
axes[10].set_ylabel('Residuals')

# 图4:残差与自变量X的关系
axes[11].scatter(X, residuals, color='orange')
axes[11].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[11].set_title('Residuals vs. X')
axes[11].set_xlabel('X')
axes[11].set_ylabel('Residuals')

# 调整布局和显示图形
plt.tight_layout()
plt.show()
  1. 生成虚拟数据:我们假设自变量 X 与因变量 Y 之间存在线性关系,并添加一些随机噪声来模拟真实数据。
  2. 线性回归模型:使用 LinearRegression 模型拟合数据,并预测 Y 值。
  3. 残差计算:残差是实际值 Y 与预测值 Y_pred 之间的差值。
  4. 图形
  • 散点图和拟合线:展示数据点和拟合的线性回归线。
  • 残差分布直方图:查看残差的分布是否接近正态分布。
  • 残差图:验证残差是否均匀分布,是否存在模式或趋势。
  • 残差与 X 的关系:检查残差是否与 X 有相关性,这可能表明模型存在未捕捉的非线性关系。

 

最后

以上就是今天所有的内容了。
获取本文PDF,点击名片回复「十大算法模型」即可~
 
另外, 我们整理了机器学习算法册子,总共16大块的内容,124个问题的总结点击领取!
如果对你来说比较有用,记得点赞、转发,收藏起来慢慢学习~
下期会有更多干货等着你!~

Python和机器学习初学者
Python和机器学习分享,只写干货,一起学习~
 最新文章