知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息
如若转载,请标明出处,谢谢!
正态分布概念是由法国数学家和天文学家棣莫弗(Abraham de Moivre)于1733年首次提出的,后由德国数学家Gauss率先将其应用于天文学研究,故正态分布又叫高斯分布
若随机变量 X X X服从一个数学期望为 μ μ μ、方差为 σ 2 σ^{2} σ2的正态分布,记为 N ( μ , σ 2 ) N(μ,σ^{2}) N(μ,σ2)。其概率密度函数为正态分布的期望值μ决定了其位置,其标准差 σ σ σ决定了分布的幅度。当 μ = 0 , σ = 1 μ = 0,σ = 1 μ=0,σ=1时的正态分布是标准正态分布
正态分布对应的概率密度函数:
f ( x ) = 1 2 π σ e x p ( − ( x − μ ) 2 2 σ 2 ) f(x) = \frac{1}{\sqrt{2\pi}σ}exp(-\frac{(x-μ)^{2}}{2σ^{2}}) f(x)=2πσ1exp(−2σ2(x−μ)2)标准正态分布对应的概率密度函数:
f ( x ) = 1 2 π e ( − x 2 2 ) f(x) = \frac{1}{\sqrt{2\pi}}e^{(-\frac{x^{2}}{2})} f(x)=2π1e(−2x2)正态分布曲线呈钟型,两头低,中间高,左右对称因其曲线呈钟形,因此人们又经常称之为钟形曲线。
对于数据分析过程中的正态分布的理解:
编程环境是在jupyter notebook中
这里随机生成数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
s = pd.DataFrame(np.random.randn(1000)+10,
columns = ['values'])
fig = plt.figure(figsize=(10,6),dpi = 500)
ax1 = fig.add_subplot(2,1,1)
ax1.scatter(s.index,s.values,edgecolor = 'black')
ax2 = fig.add_subplot(2,1,2)
s.hist(bins = 20,ax = ax2,edgecolor = 'black')
s.plot(kind = 'kde', secondary_y = True, ax = ax2)
输出结果为:(可以发现绘制的密度曲线满足正态分布的曲线样式)
QQ图通过把测试样本数据的分位数与已知分布相比较,从而来检验数据的分布情况
QQ图是一种散点图,对应于正态分布的QQ图,就是由标准正态分布的分位数为横坐标,样本值为纵坐标的散点图
参考直线:四分之一分位点和四分之三分位点这两点确定,看散点是否落在这条线的附近
绘制思路:
第一步求解样本数据的均值和标准差
s = pd.DataFrame(np.random.randn(1000)+10,
columns = ['values'])
mean = s['values'].mean()
std = s['values'].std()
print('均值为:{},标准差为:{}'.format(mean,std))
输出结果为:(由于是随机数,这里的均值和标准差会每次运行都有所不同)
均值为:10.032453869072762,标准差为:1.0290379115139239
第二步,进行数值排序
s_r = s.sort_values(by = 'values').reset_index()
s_r
s_r['p'] = (s_r.index - 0.5) / len(s_r)
s_r
st = s['values'].describe()
x1,y1 = 0.25, st['25%']
x2,y2 = 0.75, st['75%']
plt.figure(figsize = (10,4),dpi = 200)
plt.plot(s_r['p'],s_r['values'],'k.',alpha = 0.1)
plt.plot([x1,x2],[y1,y2],'-r')
Kolmogorov–Smirnov test (K-S test) 是比较一个频率分布f(x)与理论分布g(x)或者两个观测值分布的检验方法
以样本数据的累计频数分布与特定的理论分布比较(比如正态分布),如果两者之间差距小,则推论样本分布取自某特定分布
假设检验的问题:
H0:样本的总体分布服从某特定分布
H1:样本的总体分布不服从某特定分布
F n ( x ) ⇒ F_{n}(x) \Rightarrow Fn(x)⇒ 样本的累计分布函数
F 0 ( x ) ⇒ F_{0}(x) \Rightarrow F0(x)⇒理论分布的分布函数
D ⇒ F n ( x ) 与 F 0 ( x ) D \Rightarrow F_{n}(x)与F_{0}(x) D⇒Fn(x)与F0(x)差值的绝对值最大值,即 D = m a x ( ∣ F n ( x ) − F 0 ( x ) ∣ ) D = max(|F_{n}(x) - F_{0}(x)|) D=max(∣Fn(x)−F0(x)∣)
判断依据: D > D ( n , α ) D > D(n,\alpha) D>D(n,α)
如果p>0.05则接受H0,p<0.05则拒绝H0,接受H1
第一步,准备样本数据:35位健康男性在未进食之前的血糖浓度,并求解出均值和标准差
data = [87,77,92,68,80,78,84,77,81,80,80,77,92,86,
76,80,81,75,77,72,81,72,84,86,80,68,77,87,
76,77,78,92,75,80,78]
df = pd.DataFrame(data, columns = ['value'])
u = df['value'].mean()
std = df['value'].std()
print('均值为:{},标准差为:{}'.format(u,std))
输出结果为:
均值为:79.74285714285715,标准差为:5.937631024648968
第二步,值计数后按照索引排序,接着求解出累计次数和对应的标准取值
s = df['value'].value_counts().sort_index()
df_s = pd.DataFrame({'血糖浓度':s.index, '次数':s.values})
df_s['累计次数'] = df_s['次数'].cumsum()
df_s['累计频率'] = df_s['累计次数']/len(data)
df_s['标准化取值'] = (df_s['血糖浓度'] - u) / std
df_s
输出结果为:
既然求解出标准化的取值,然后对照着下表就可以求解出理论分布对应的值,比如最后一个2.064315,查表后对应的分布值为0.9803,若是负值,比如-1.977701,则先取正值对应的结果后,用1减去就是最终的结果,这里1.977701查表为0.9756,最终的结果就为0.0244。由此可以计算出所有的理论分布
第三步,查表得理论分布后,求解D值
df_s['理论分布'] =[0.0244,0.0968,0.2148,0.2643,0.3228,0.3859,0.5160,0.5832,0.7611,0.8531,0.8888,0.9803] # 通过查阅正太分布表
df_s['D'] = np.abs(df_s['累计频率'] - df_s['理论分布'])
dmax = df_s['D'].max()
print("实际观测D值为:%.4f" % dmax)
# D值序列计算结果表格
输出结果为:
实际观测D值为:0.1597
第四步,根据显著性表核实p值大小。参考上表,这里的样本为35,D值为0.1597,那么对应的p值为0.2-0.4之间,要大于0.05,故可以认定样本是服从正态分布的)
data = [87,77,92,68,80,78,84,77,81,80,80,77,92,86,
76,80,81,75,77,72,81,72,84,86,80,68,77,87,
76,77,78,92,75,80,78]
df = pd.DataFrame(data, columns =['value'])
u = df['value'].mean()
std = df['value'].std()
stats.kstest(df['value'], 'norm', (u, std))
# .kstest方法:KS检验,参数分别是:待检验的数据,检验方法(这里设置成norm正态分布),均值与标准差
# 结果返回两个值:statistic → D值,pvalue → P值
# p值大于0.05,为正态分布
输出结果为:(pvalue=0.3066,D值也和之前算的值约相等)
KstestResult(statistic=0.1590180704824098, pvalue=0.3066297258358026)
相关性分析是指对两个或者多个具备相关性的变量元素进行分析,从而衡量两个因素的相关密切程度
相关性的元素之间需要存在一定的联系或者概率才可以进行相关性分析
分析的方式也是有多种:
data1 = pd.Series(np.random.rand(50)*100).sort_values()
data2 = pd.Series(np.random.rand(50)*50).sort_values()
data3 = pd.Series(np.random.rand(50)*500).sort_values(ascending = False)
# 创建三个数据:data1为0-100的随机数并从小到大排列,data2为0-50的随机数并从小到大排列,data3为0-500的随机数并从大到小排列,
fig = plt.figure(figsize = (10,4))
ax1 = fig.add_subplot(1,2,1)
ax1.scatter(data1, data2)
plt.grid()
# 正线性相关
ax2 = fig.add_subplot(1,2,2)
ax2.scatter(data1, data3)
plt.grid()
# 负线性相关
输出结果:(这里是两个因素之间的相关性比较)
如果是多个因素,那么就可以使用散点矩阵
# (2)散点图矩阵初判多变量间关系
data = pd.DataFrame(np.random.randn(200,4)*100, columns = ['A','B','C','D'])
pd.plotting.scatter_matrix(data,figsize=(8,8),
c = 'k',
marker = '+',
diagonal='hist',
alpha = 0.8,
range_padding=0.1)
最常见的衡量相关性的标准,输出的结果范围为:-1到1之间,0代表着无相关性,负值代表着负相关,正值为正相关。前提:样本必须是正态分布
0 < ∣ r ∣ < 1 0<|r|<1 0<∣r∣<1表示不同程度的线性相关
data1 = pd.Series(np.random.rand(100)*100).sort_values()
data2 = pd.Series(np.random.rand(100)*50).sort_values()
data = pd.DataFrame({'value1':data1.values,
'value2':data2.values})
print(data.head())
print('------')
# 创建样本数据
u1,u2 = data['value1'].mean(),data['value2'].mean() # 计算均值
std1,std2 = data['value1'].std(),data['value2'].std() # 计算标准差
print('value1正态性检验:\n',stats.kstest(data['value1'], 'norm', (u1, std1)))
print('value2正态性检验:\n',stats.kstest(data['value2'], 'norm', (u2, std2)))
print('------')
# 正态性检验 → pvalue >0.05
data['(x-u1)*(y-u2)'] = (data['value1'] - u1) * (data['value2'] - u2)
data['(x-u1)**2'] = (data['value1'] - u1)**2
data['(y-u2)**2'] = (data['value2'] - u2)**2
print(data.head())
print('------')
# 制作Pearson相关系数求值表
r = data['(x-u1)*(y-u2)'].sum() / (np.sqrt(data['(x-u1)**2'].sum() * data['(y-u2)**2'].sum()))
print('Pearson相关系数为:%.4f' % r)
# 求出r
# |r| > 0.8 → 高度线性相关
使用pandas的.corr()
方法
data1 = pd.Series(np.random.rand(100)*100).sort_values()
data2 = pd.Series(np.random.rand(100)*50).sort_values()
data = pd.DataFrame({'value1':data1.values,
'value2':data2.values})
print(data.head())
print('------')
# 创建样本数据
data.corr()
# pandas相关性方法:data.corr(method='pearson', min_periods=1) → 直接给出数据字段的相关系数矩阵
# method默认pearson
皮尔逊相关系数主要用于服从正态分布的连续变量,不服从正态分布的变量,分类的关联性可以采用Sperman秩相关系数,也称等级相关系数
计算逻辑:
data = pd.DataFrame({'智商':[106,86,100,101,99,103,97,113,112,110],
'每周看电视小时数':[7,0,27,50,28,29,20,12,6,17]})
print(data)
print('------')
# 创建样本数据
data.sort_values('智商', inplace=True)
data['range1'] = np.arange(1,len(data)+1)
data.sort_values('每周看电视小时数', inplace=True)
data['range2'] = np.arange(1,len(data)+1)
print(data)
print('------')
# “智商”、“每周看电视小时数”重新按照从小到大排序,并设定秩次index
data['d'] = data['range1'] - data['range2']
data['d2'] = data['d']**2
print(data)
print('------')
# 求出di,di2
n = len(data)
rs = 1 - 6 * (data['d2'].sum()) / (n * (n**2 - 1))
print('Pearson相关系数为:%.4f' % rs)
# 求出rs
输出结果为:(可以看出每周看电视的小时数和智商没有太大相关性)
参数中有个method,换一下即可
data = pd.DataFrame({'智商':[106,86,100,101,99,103,97,113,112,110],
'每周看电视小时数':[7,0,27,50,28,29,20,12,6,17]})
print(data)
print('------')
# 创建样本数据
data.corr(method='spearman')
# pandas相关性方法:data.corr(method='pearson', min_periods=1) → 直接给出数据字段的相关系数矩阵
# method默认pearson
(1)正态分布直接先通过柱状图和密度曲线查看
(2)正态性检验:stats.kstest(df['value'], 'norm', (u, std))
(3)Pearson相关系数:前提是正态分布,data.corr()
(4)Sperman秩相关系数:不要求是正态分布,data.corr(method='spearman')