今天就以python进行相应的实践操作,今天将深入解析三大核心工具链 ——scipy.stats、pymc3/stan和scikit-learn,通过理论结合代码示例的方式,从基础统计计算到高级机器学习建模的完整流程。

一、scipy.stats

scipy.stats作为 SciPy 库的核心模块,为概率分布计算提供了全方位支持。无论是连续分布(如正态分布、t 分布)还是离散分布(如二项分布、泊松分布),都能通过统一的接口实现概率密度计算、采样和参数估计。

1、分布基础操作

以最常用的正态分布为例,我们可以轻松完成以下操作:

import numpy as np

from scipy import stats

import matplotlib.pyplot as plt

# 定义正态分布(均值0,标准差1)

normal_dist = stats.norm(loc=0, scale=1)

# 计算概率密度函数(PDF)

x = np.linspace(-3, 3, 100)

pdf_values = normal_dist.pdf(x)

# 计算累积分布函数(CDF)

cdf_values = normal_dist.cdf(x)

# 生成1000个符合该分布的随机样本

samples = normal_dist.rvs(size=1000)

# 可视化结果

plt.figure(figsize=(12, 4))

plt.subplot(121)

plt.plot(x, pdf_values, label='PDF')

plt.fill_between(x, pdf_values, alpha=0.3)

plt.title('正态分布概率密度')

plt.subplot(122)

plt.hist(samples, bins=30, density=True, alpha=0.5)

plt.plot(x, pdf_values, 'r-')

plt.title('随机采样结果')

plt.tight_layout()

plt.show()

这段代码直观展示了正态分布的数学特性与随机采样效果。对于非专业人士,只需理解:通过scipy.stats可以轻松获取各种概率分布的数值特征,并生成符合该分布的随机数据。

2、实用统计测试

scipy.stats还包含多种假设检验工具,例如 KS 检验可用于验证样本是否符合特定分布:

# 验证样本是否符合正态分布

statistic, p_value = stats.kstest(samples, 'norm')

print(f"KS统计量: {statistic:.4f}")

print(f"P值: {p_value:.4f}")

print("是否符合正态分布?" + ("是" if p_value > 0.05 else "否"))

当 P 值大于 0.05(通常的显著性水平)时,我们无法拒绝 "样本符合目标分布" 的假设。这种统计测试在数据预处理阶段非常有用,能帮助我们判断数据是否满足建模要求。

二、PyMC3 与 Stan

贝叶斯方法通过概率分布描述参数不确定性,在小样本场景和需要量化置信度的任务中表现出色。PyMC3和Stan是目前最流行的贝叶斯建模工具,分别以 Python 友好性和计算效率著称。

1、PyMC3 线性回归建模

假设我们有一组带有噪声的线性关系数据,使用 PyMC3 构建贝叶斯线性回归模型:


import pymc3 as pm

import pandas as pd

# 生成模拟数据

np.random.seed(42)

x = np.linspace(0, 10, 50)

true_slope = 2.5

true_intercept = 3.0

y = true_slope * x + true_intercept + np.random.normal(0, 1.5, 50)

# 构建贝叶斯模型

with pm.Model() as linear_model:

# 定义先验分布

intercept = pm.Normal('intercept', mu=0, sd=10) # 截距项先验

slope = pm.Normal('slope', mu=0, sd=10) # 斜率项先验

sigma = pm.HalfNormal('sigma', sd=1) # 噪声标准差(半正态分布保证非负)

# 定义似然函数

mu = intercept + slope * x

y_obs = pm.Normal('y_obs', mu=mu, sd=sigma, observed=y)

# 进行MCMC采样

trace = pm.sample(2000, cores=2) # 采样2000次,使用2个CPU核心

模型定义包含三个关键部分:

  • 先验分布:基于领域知识或无信息先验设定参数可能范围
  • 似然函数:描述观测数据如何从模型生成
  • MCMC 采样:通过马尔可夫链蒙特卡洛方法获取参数后验分布

采样完成后,我们可以分析参数的后验分布:

# 查看参数后验统计

print(pm.summary(trace))

# 可视化后验分布

pm.plot_trace(trace)

plt.tight_layout()

plt.show()

# 绘制预测区间

pm.plot_posterior_predictive_glm(trace, samples=100, eval=x,

label='后验预测')

plt.scatter(x, y, alpha=0.5, label='观测数据')

plt.plot(x, true_slope*x + true_intercept, 'r--', label='真实关系')

plt.legend()

plt.show()

贝叶斯模型的优势在于不仅能得到参数估计值,还能获得完整的不确定性分布。例如plot_posterior_predictive_glm生成的预测区间,直观展示了不同 x 值对应的 y 值可能范围。

2、Stan 与 PyMC3 的选择

Stan采用 C++ 后端,计算速度通常比 PyMC3 快,尤其适合复杂模型和大规模数据。其 Python 接口pystan使用方式与 PyMC3 类似,但语法略有差异:


import pystan

# Stan模型代码

stan_code = """

data {

int<lower=0> N;

vector[N] x;

vector[N] y;

}

parameters {

real intercept;

real slope;

real<lower=0> sigma;

}

model {

// 先验

intercept ~ normal(0, 10);

slope ~ normal(0, 10);

sigma ~ normal(0, 1);

// 似然

y ~ normal(intercept + slope * x, sigma);

}

"""

# 准备数据

stan_data = {'N': len(x), 'x': x, 'y': y}

# 编译并采样

model = pystan.StanModel(model_code=stan_code)

fit = model.sampling(data=stan_data, iter=2000, chains=2)

选择建议:对于初学者和快速原型开发,PyMC3 的 Python 式语法更易上手;对于生产环境和性能敏感场景,Stan 是更好的选择。

三、scikit-learn

scikit-learn提供了统一接口的机器学习算法实现,包括贝叶斯方法中的朴素贝叶斯和高斯混合模型(GMM),让开发者可以轻松构建预测模型。

1、朴素贝叶斯分类器

朴素贝叶斯通过 "特征条件独立" 假设简化贝叶斯计算,在文本分类等场景表现优异:

from sklearn.naive_bayes import GaussianNB, MultinomialNB

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score, classification_report

# 加载数据集

iris = load_iris()

X, y = iris.data, iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 训练高斯朴素贝叶斯模型

gnb = GaussianNB()

gnb.fit(X_train, y_train)

# 预测与评估

y_pred = gnb.predict(X_test)

print(f"准确率: {accuracy_score(y_test, y_pred):.4f}")

print("\n分类报告:")

print(classification_report(y_test, y_pred, target_names=iris.target_names))

这段代码在鸢尾花数据集上实现了 97.78% 的分类准确率。对于文本数据,通常使用MultinomialNB,配合CountVectorizer或TfidfVectorizer进行特征提取:


from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.pipeline import make_pipeline

# 示例文本数据

texts = [

"机器学习是人工智能的一个分支",

"人工智能研究如何使计算机智能化",

"贝叶斯方法是一种概率统计方法",

"统计学习包含多种机器学习算法"

]

labels = [0, 0, 1, 1] # 0: 人工智能, 1: 统计学习

# 构建文本分类 pipeline

text_clf = make_pipeline(

TfidfVectorizer(),

MultinomialNB()

)

text_clf.fit(texts, labels)

# 预测新文本

new_texts = ["贝叶斯模型属于机器学习方法"]

print("预测类别:", "人工智能" if text_clf.predict(new_texts)[0] == 0 else "统计学习")

2、高斯混合模型聚类

GMM 是一种基于概率的聚类算法,假设数据由多个高斯分布混合生成:


from sklearn.mixture import GaussianMixture

from sklearn.datasets import make_blobs

# 生成三维聚类数据

X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# 训练GMM模型

gmm = GaussianMixture(n_components=4, random_state=42)

y_pred = gmm.fit_predict(X)

# 可视化聚类结果(取前两维)

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10, 7))

ax = fig.add_subplot(111, projection='3d')

scatter = ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=y_pred, s=50, cmap='viridis')

ax.set_title('GMM聚类结果')

plt.colorbar(scatter, label='聚类标签')

plt.show()

# 输出每个样本属于各聚类的概率

print("前5个样本的聚类概率:\n", gmm.predict_proba(X)[:5])

GMM 相比 K-means 的优势是能提供 "软聚类" 结果 —— 每个样本属于不同聚类的概率,这在需要量化分类不确定性的场景非常有用。

四、工具链协同工作流

在实际项目中,这些工具通常协同使用,形成完整的数据分析 pipeline:

  • 数据探索:使用scipy.stats分析变量分布特性
  • 模型选择:若需要完整的不确定性量化,使用PyMC3/Stan构建贝叶斯模型;若追求预测性能和开发效率,使用scikit-learn的算法
  • 模型评估:结合统计测试和机器学习评估指标综合判断

例如在客户流失预测项目中:

  • 先用scipy.stats检验用户特征的分布特性
  • 再用scikit-learn的朴素贝叶斯快速构建基线模型
  • 最后用PyMC3深入分析关键因素对流失率的影响及不确定性

最后小结:

Python 的 AI 工具链为不同需求和背景的使用者提供了灵活选择:从scipy.stats的基础统计计算,到PyMC3/Stan的高级贝叶斯建模,再到scikit-learn的高效机器学习实现,形成了覆盖数据科学全流程的生态系统。理解这些工具的特性和适用场景,不仅能提高开发效率,更能帮助我们选择合适的方法解决实际问题 —— 无论是需要精确量化不确定性的科学研究,还是追求高预测精度的商业应用。未完待续........

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐