求数据密度函数python代码_Python:三维空间的概率密度函
数(附代码数据集)
⼆维⾼斯分布
概率密度函数
数据集
实战
优化
坐标轴与图像优化
图像再次优化
概率密度函数
⼤家肯定都有听说过正态分布,其实正态分布只是概率密度分布的⼀种,正态分布的概率密度函数均值为μ ,标准差σ是⾼斯函数的⼀个实例:
f ( x ; μ , σ ) = 1 σ 2 π exp ( − ( x − μ ) 2 2 σ 2 ) f(x ; \mu, \sigma)=\frac{1}{\sigma \sqrt{2 \pi}} \exp \left(-\frac{(x-
\mu)^{2}}{2 \sigma^{2}}\right)f(x;μ,σ)=σ2π1e xp(−2σ2(x−μ)2)
在⼀维上只有x⼀个变量,μ 均值,σ标准差。
正态分布具有两个参数μ和σ的连续型随机变量的分布,第⼀
查重名null什么意思参数μ是服从正态分布的随机变量的均值,第⼆个参数σ^2是此随机变量的⽅差,所以正态分布记作N(μ,σ2)。
实际⼯作中,正态曲线下横轴上⼀定区间的⾯积反映该区间的例数占总例数的百分⽐,或变量值落在该区间的概率。
因此⼀维的概率密度分布即正态分布,很好的表⽰数据在哪个区间集中,使我们对整体数据有⼀个⼤概的把握。
本⽂的重点在于⼆维概率密度函数:
最新电影网f ( x , y ) = ( 2 π σ 1 σ 2 1 − ρ 2 ) − 1 exp [ − 1 2 ( 1 − ρ 2 ) ( ( x − μ 1 ) 2 σ 1 2 − 2 ρ ( x − μ 1 ) ( y − μ 2 ) σ 1 σ
2 + ( y − μ 2 ) 2 σ 2 2 ) ] f(x, y)=\left(2 \pi \sigma_{1} \sigma_{2} \sqrt{1-\rho^{2}}\right)^{-1} \exp \left[-\frac{1}
{2\left(1-\rho^{2}\right)}\left(\frac{\left(x-\mu_{1}\right)^{2}}{\sigma_{1}^{2}}-\frac{2 \rho\left(x-\mu_{1}\right)\left(y-
\mu_{2}\right)}{\sigma_{1} \sigma_{2}}+\frac{\left(y-\mu_{2}\right)^{2}}{\sigma_{2}^{2}}\right)\right]f(x,y)=(2πσ1σ2
1−ρ2)−1exp[−2(1−ρ2)1(σ12(x−μ1)2−σ1σ22ρ(x−μ1)(y−μ2)+σ22(y−μ2)2)]
因为⽣活中的很多数据都是⾼维度的,从简单的⼆维说起。⼆维上的数据⽣活中有很多:⾝⾼和体重,⾎压和⾎脂等等。如果能够像⼀维正态分布那样做出图像来看,就⼗分直观,⽽本⽂就是介绍如何作⼆维概率密度函数的图像。
数据集
⾸先贴上数据集:
链接:pan.baidu/s/1RJCwi4-8_hByY6-rCepJgQpython基础代码实例
提取码:88ew
数据是截⾄4.25⽇的重点国家新冠肺炎感染⼈数,有中国、美国、法国、意⼤利等。
本⽂采取的是中国和意⼤利进⾏对⽐分析。
import numpy as np
import matplotlib.pyplot as plt
import math
import mpl_toolkits.mplot3d
import math
import pandas as pd
shell是什么国家的品牌data = pd.read_csv('D:/桌⾯/1.csv')
print(data.head())
x = data.iloc[:,1]
y = data.iloc[:,7]
x = x.values
y = y.values
实战
⾸先根据公式我们先把2个维度的均值和⽅差分别计算出来,以及公式中需要的相关系数。
u1 = x.mean()
u2 = y.mean()
o1 = x.std()
o2 = y.std()
from scipy.stats import pearsonr
p = pearsonr(x, y)[0]
print(u1, u2, o1, o2, p)
# 输出:(r, p)
# r:相关系数[-1,1]之间
# p:相关系数显著性
相关系数也就是⽪尔逊系数,把2个维度数据给⼊后,会输出相关系数和相关系数显著性。
相关系数取值范围是(-1,1),越接近1则说明越相关。不过我们也不能说中国感染⼈数和西班⽛感染⼈数相关,这⾥更确切地解释应该是感染⼈数的趋势⽐较。
X, Y = np.meshgrid(x, y)
z = (1/(2*math.pi*o1*o2*pow(1-pow(p,2),0.5)))*np.exp(-1/(2*(1-p*p))*(((X-u1)*(X-u1))/(o1*o1)-2*p*(X-u1)*(Y-u2)/(o1*o2)+ (Y-u2)*(Y-u2)/(o2*o2)))
这⾥X,Y是对原始数据进⾏⽹格化,其实就相当于最后成果图的横纵坐标,只是转换⼀下得以输⼊作图。
z就是上⽂的⼆维密度函数⽤python来表达了。⽐较⿇烦,注意⾥⾯有上⾯算出的2个维度的均值,⽅差和⽪尔逊系数。
列表html页面模板Params['axes.unicode_minus'] = False
plt.figure(figsize=(10,10), dpi=300)
ax = plt.subplot(111, projection='3d')
ax.plot_surface(X, Y, z,
cmap='rainbow', alpha=0.9)
ax.set_xlabel('中国感染⼈数')
ax.set_ylabel('西班⽛感染⼈数')
ax.set_zlabel('频率')
ax.set_title("⼆维⾼斯分布")
plt.savefig('D:/桌⾯/1.png', bbox_inches='tight', pad_inches=0.0)
这就是很基础的⼀些画图设置了,相似的就不再赘述,重点 谈谈plot_surface。
plot_surface中的X,Y,z其实上⽂以及解释过了,就是相应的坐标和函数,那么cmap是什么呢,camp是颜⾊盘,值定位rainbow就是彩虹⾊,从下图就可以看出,数据越集中的地⽅,颜⾊就越深。这⾥还有⼀个颜⾊盘是coolwarm,不过个⼈感觉没rainbow好看,不妨⼩伙伴们试⼀试。
到此我们就⼤概的画出了中国感染⼈数和西班⽛感染⼈数在4.25之前的密度函数。
这个图我们看出,中国感染⼈数⼤概在4-5万就开始达到⾼峰,之后开始下降,⽽西班⽛到了12万左右才开始下降。整个国家感染⼈数的增幅⼀⽬了然,对于整体数据的把握也有较好的认知。但这样似乎不太好看,⽽且到底⾼峰是不是在我说的那个数值呢,根据⾁眼都不好判断。所以我们接下来进⾏优化。
优化
坐标轴与图像优化
plt.figure(figsize=(10,10), dpi=300)
ax = plt.subplot(111, projection='3d')
ax.plot_surface(X, Y, z, rstride=1, cstride=1,
cmap='rainbow', alpha=0.9)
ax.set_xlabel('中国感染⼈数', fontsize=15)
ax.set_ylabel('西班⽛感染⼈数', fontsize=15)
ax.set_zlabel('频率', fontsize=15)
ax.set_title("⼆维⾼斯分布", fontsize=25, y=1.02)
ax.set_xticks(np.arange(0,100000,20000))
ax.set_yticks(np.arange(0,200000,40000))
plt.savefig('D:/桌⾯/3.png', bbox_inches='tight', pad_inches=0.0)
可能⼀眼还没看出来。我来讲解⼀下。博主在plot_surface⾥⾯加了 rstride=1, cstride=1,这两个参数有什么作⽤?相当于步长。这么理解吧,这个颜⾊实际上是由⽆数个点组成的,但是实际上就像房⼦顶上的⽡⽚⼀样,如果⽡⽚⽐较⼤,那么房顶⾯积⼀定,⽡⽚就⽤的少,就像上图⼀样显得⼀块⼀块的,⾮常⼤,不过不平滑。⽽下图呢,加⼊ rstride=1, cstride=1就相当于定制了⽡⽚长宽,⽡⽚⽐较⼩那么看起来就舒服,颜⾊过渡得⽐上⾯那个⾃然多。
把标题和坐标轴都修改⼀下,title的x,y参数是调位置的,如何使⽤的话⼩伙伴们多试⼏个值就明⽩了。
plt.savefig⾥⾯的bbox_inches=‘tight’, pad_inches=0.0在这⾥看起⾥效果似乎不明显。这个作⽤是减⼩图⽚旁边的⽩⾊区域。如果感兴趣的⼩伙伴可以试⼀下不加和加了这些参数保存出来是什么样的。
图像再次优化
plt.figure(figsize=(10,10), dpi=300)
ax = plt.subplot(111, projection='3d')
ax.plot_surface(X, Y, z, rstride=1, cstride=1,
cmap='rainbow', alpha=0.9)
ax.set_xlabel('中国感染⼈数', fontsize=15)
ax.set_ylabel('西班⽛感染⼈数', fontsize=15)
ax.set_zlabel('频率', fontsize=15)
ax.set_title("⼆维⾼斯分布", fontsize=25, y=1.02)
ax.set_xticks(np.arange(0,100000,20000))
ax.set_yticks(np.arange(0,200000,40000))
ax.w_xaxis.set_pane_color((135/255, 206/255, 250/255, 0.3))
ax.w_yaxis.set_pane_color((135/255, 206/255, 250/255, 0.3))
ax.w_zaxis.set_pane_color((135/255, 206/255, 250/255, 0.3))
plt.savefig('D:/桌⾯/4.png', bbox_inches='tight', pad_inches=0.0)
作图⼀⽅⾯为了好看,⼀⽅⾯是对数据整体把握更加直观,这⾥加了ax.w_xaxis.set_pane_color这个⽅法是对x平⾯进⾏上⾊,个⼈感觉更好看吧。⾥⾯的参数是rgba。
细⼼的⼩伙伴已经发现了,这个图⽐上⾯的多了好多等⾼线。这些等⾼线是这个密度函数在xoy平⾯的投影,能够更直观的看出到底数据的⾼峰是在哪。我们直观看出,中国感染⼈数到达⾼峰是在6w⼈左右,⽽西班⽛也是在6w⼈左右,这和我们前⾯⽬测估计的有⼀点误差。所以ax.contour这个⽅法将密度函数投影到平⾯来,更细致的观察数据的分布。其中ax.contour中
15代表是有多少条等⾼线,zdir=z表⽰投影到z=?这个平⾯,⽽?的数值就是由offset表⽰,这⾥显然投影到z=0平⾯,camp也是和上⽂意思差不多是颜⾊盘,彩虹⾊的。
效果还是很直观的。
>htmlcss静态网页模板
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论