这类博客针对算法学习时可能遇到的数学知识补充,但不会太多废话,主要是公式结合Python代码精美绘图理解!
本期重点:
bash
参数:期望、标准差
曲线:概率密度曲线PDF、累积概率密度函数CDF、百分点函数PPF
应用:68-95-99.7法则、参数估计、经验分布函数ECDF、QQ图。
一、一元高斯分布基本知识
一元高斯分布,也即正态分布!
①PDF函数(对应概率密度):
期望影响PDF曲线的位置(位置参数),方差影响PDF的形状(形状参数),方差越大曲线越扁平,越小曲线越瘦高。
PDF曲线下的总面积为"1",即PDF函数积分结果为"1",这也是分母除以根号下2pi的缘故。
②CDF函数(对应概率值):
标准一元高斯分布的PDF和CDF曲线如下(y轴含义不同):
③百分点函数PPF(CDF的逆函数):
④Z分数(一种标准化度量尺度):
Z分数也叫标准分数,运算为如下:
这个过程也叫数据的标准化,样本数据的Z分数构成的分布------均值为0,方差为1,标准正态分布的Z值大小上等于样本X值,只不过Z分数无单位。(每一个x对应一个z,所有的z值数量与样本x数量对应)
标准正态分布中,以 z 值(在标准正态中z其实就是样本值x)为节点划分四类面积。z取不同值时,四类面积(概率值)不同,对应有一个 标准概率表格 ,这个表格在 Z检验(Z-test) 常被用到。
Z分数可以看作一种 标准化的"距离度量 "。原始样本X的Z分数表示 距离均值若干倍的标准差偏移,如某个样本数据点x对应z值为3,说明这个数据点距均值有3倍的标准差偏移(右偏)------表示一个 偏移的倍数!!!
有了Z分数,不同分布、不同单位的样本数据有了可比性,如下是鸢尾花数据集四个特征的Z分数:(横轴是Z分数值,纵轴是概率密度)
python
#导入库与数据集
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.datasets import load_iris
from statsmodels.distributions.empirical_distribution import ECDF
from scipy.stats import norm
import scipy
iris = load_iris()
X = iris.data
y = iris.target
feature_names = ['Sepal length, $X_1$','Sepal width, $X_2$',
'Petal length, $X_3$','Petal width, $X_4$']
x_array = np.linspace(0,8,100)
# Convert X array to dataframe
X_df = pd.DataFrame(X, columns=feature_names)
计算Z分数然后绘制图像代码如下:
python
# %% generate Z score
z_array = np.linspace(-4, 4, 100)
Z_score_df = (X_df - X_df.mean()) / X_df.std()
for feature in feature_names:
sample = Z_score_df[feature]
hist = np.histogram(sample, bins=40, range=(-4, 4))
hist_dist = scipy.stats.rv_histogram(hist)
mu = sample.mean()
std = sample.std()
N_pdf = norm.pdf(z_array, loc=mu, scale=std)
epdf_y = hist_dist.pdf(z_array)
fig, ax = plt.subplots()
# plot empirical PDF
plt.step(z_array, epdf_y, color='#0070C0')
ax.fill_between(z_array, epdf_y, step="pre", color='#DBEEF3')
plt.axvline(x=mu, color='r', linestyle='--')
plt.axvline(x=mu + std, color='r', linestyle='--')
plt.axvline(x=mu - std, color='r', linestyle='--')
# plot parametric (normal) PDF
plt.plot(z_array, N_pdf, 'r')
plt.xlabel(feature.replace('X', 'Z') + ' ($\sigma$)')
plt.ylabel('PDF, probability density')
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)
plt.gca().yaxis.set_ticks_position('left')
plt.gca().xaxis.set_ticks_position('bottom')
plt.xlim(-4, 4)
plt.ylim(0, 1)
plt.yticks(np.linspace(0, 1, 6))
plt.grid(color=[0.7, 0.7, 0.7])
plt.show()
这样不同的四个特征用Z分数标准化后,变得可比!!
68-95-99.7法则不说了,大家都知道68%、95%、99.7%分别对应距离均值1倍、2倍、3倍标准差的偏移。
二、参数估计------估计概率密度
机器学习中,概率密度估计是一个常见问题------从离散的样本数据中估计得到连续的概率密度函数曲线。
python
#%% compare PDF curves
for feature in feature_names:
sample = X_df[feature]
hist = np.histogram(sample, bins=30, range = (0,8))
hist_dist = scipy.stats.rv_histogram(hist)
mu = sample.mean()
std = sample.std()
N_pdf = norm.pdf(x_array, loc = mu, scale = std)
epdf_y = hist_dist.pdf(x_array)
fig, ax = plt.subplots()
# plot empirical PDF
plt.step(x_array,epdf_y, color = '#0070C0')
ax.fill_between(x_array, epdf_y, step="pre", color = '#DBEEF3')
plt.axvline(x=mu, color = 'r', linestyle = '--')
plt.axvline(x=mu + std, color = 'r', linestyle = '--')
plt.axvline(x=mu - std, color = 'r', linestyle = '--')
# plot parametric (normal) PDF
plt.plot(x_array,N_pdf, 'r')
plt.xlabel(feature)
plt.ylabel('PDF, probability density')
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)
plt.gca().yaxis.set_ticks_position('left')
plt.gca().xaxis.set_ticks_position('bottom')
plt.xlim(0,8)
plt.ylim(0,1)
plt.yticks(np.linspace(0,1,5))
plt.grid(color = [0.7,0.7,0.7])
plt.show()
用一元高斯分布估计单一特征概率密度函数很简单;但是问题很明显,如上图鸢尾花数据集前两个特征估计效果很好,但是 后两个特征似乎用一元高斯分布进行估计不太合适。------后续将会用 核密度估计解决这一问题。
三、经验分布函数(ECDF)
经验分布函数(ECDF)是一个用来描述样本数据分布情况的统计工具,可以理解为数据的实际概率分布:
- 将数据按大小排序
- 计算每个数据点对应的累积比例,形成类似阶梯函数的曲线
- 横坐标为样本数据取值,纵坐标表示小于等于横坐标的数据比例(实际的)
- 双射函数,每个输入正好有一个输出,每个输出值正好都有一个输入值
- 常与CDF分布函数(估计的、理想的)比较,以检验数据是否符合某种假设的分布。下面是鸢尾花4个特征的ECDF和CDF对比图代码和结果:
python
#%% compare CDF curves
for feature in feature_names:
sample = X_df[feature]
mu = sample.mean()
std = sample.std()
N_cdf = norm.cdf(x_array, loc = mu, scale = std)
ecdf = ECDF(sample)
ecdf_y = ecdf(x_array)
fig, ax = plt.subplots()
# plot empirical CDF
plt.step(x_array,ecdf_y)
# plot parametric (normal) CDF
plt.plot(x_array,N_cdf, 'r')
plt.axvline(x=mu, color = 'r', linestyle = '--')
plt.axvline(x=mu + std, color = 'r', linestyle = '--')
plt.axvline(x=mu - std, color = 'r', linestyle = '--')
plt.xlabel(feature)
plt.ylabel('CDF, probability')
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)
plt.gca().yaxis.set_ticks_position('left')
plt.gca().xaxis.set_ticks_position('bottom')
plt.xlim(0,8)
plt.ylim(0,1)
plt.yticks(np.linspace(0,1,5))
plt.grid(color = [0.7,0.7,0.7])
plt.show()
-
据此更可以形象的看出,后两个鸢尾花特征的数据分布是不太适合用一元高斯分布进行描述的!
三、分位-分位图(QQ图)
- "Q"代表分位数。二分位数即中位数;四分位数把所有数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数,例如第一四分位数(Q1),等于该样本中所有数值由小到大排列后第25%的数字;第二四分位数(Q2)即中位数;
- QQ图是散点图,横坐标为假定分布(如标准正态)的分位数,纵坐标为待检验样本的分位数------类似于理想与实际;
- 比较相似度,若完全符合假定分布则QQ图呈现理想y=x的对角线;
- QQ图横坐标一般是正态分布,也可是其他分布;
- 也用于检查数据是否符合某个分布的统计图形,可以看作ECDF曲线的另一种可视化方式;
python
#%% QQ plot
import pylab
import scipy.stats as stats
for feature in feature_names:
sample = X_df[feature]
mu = sample.mean()
std = sample.std()
fig = plt.figure(figsize=(7, 7))
stats.probplot(sample, dist="norm", plot=pylab)
plt.axhline(y=mu, color = 'r', linestyle = '--')
plt.axhline(y=mu + std, color = 'r', linestyle = '--')
plt.axhline(y=mu - std, color = 'r', linestyle = '--')
plt.axhline(y=mu + 2*std, color = 'r', linestyle = '--')
plt.axhline(y=mu - 2*std, color = 'r', linestyle = '--')
plt.axvline(x=0, color = 'r', linestyle = '--')
plt.axvline(x=1, color = 'r', linestyle = '--')
plt.axvline(x=-1, color = 'r', linestyle = '--')
plt.axvline(x=2, color = 'r', linestyle = '--')
plt.axvline(x=-2, color = 'r', linestyle = '--')
plt.xlabel('Theoretical (standard normal) quantiles')
plt.ylabel('Empirical quantiles')
pylab.show()
实际应用中,高斯分布常用于建模和分析连续数据 ;在数据分析机器学习中,高斯分布被广泛用于分类、聚类、离群点检测等问题!
仅仅一元高斯分布还不够,后续将继续二元、多元高斯分布、条件高斯分布、协方差矩阵等!
如有兴趣欢迎订阅该专栏,和我一起领略机器学习算法的奥妙!!