1 理解多元正态分布
1.0 什么是多元正态分布
多元正态分布是指一个随机向量的各个分量都服从正态分布,并且这些分量之间可以存在一定的相关性。一个 k维随机向量 X=(X1,X2,…,Xk)T服从多元正态分布,记作 X∼N(μ,Σ),其中:
- μ是 k 维均值向量,表示每个分量的均值。
- Σ是 k×k的协方差矩阵,描述各个分量之间的方差和协方差。
从图形上理解,可以从下面几个方面进行理解:
1、对于一个维度本身,可以从标准正态分布来理解,数据点数量的集中中心由这个维度的均值决定,数据点的分布的拉伸程度由这个维度的方差决定。越小的方差范围内,数据点的个数越多。
以下是生成上面图的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# 设置随机种子以便复现
np.random.seed(42)
# 生成符合正态分布的数据
mean = 0 # 均值
std_dev = 1 # 标准差
num_samples = 1000 # 数据点数量
# 生成数据点
data_points = np.random.normal(loc=mean, scale=std_dev, size=num_samples)
# 创建数轴
x = np.linspace(-4, 4, 1000) # 数轴范围
# 计算正态分布的概率密度
pdf = norm.pdf(x, loc=mean, scale=std_dev)
# 绘制概率密度曲线
plt.plot(x, pdf, color='blue', label='Probability Density Function', linewidth=2)
# 绘制数据点
plt.scatter(data_points, np.zeros_like(data_points), color='red', alpha=0.5, label='Data Points', s=10)
# 设置图形属性
plt.title('Normal Distribution and Data Points')
plt.xlabel('Value')
plt.ylabel('Probability Density')
plt.axhline(0, color='black', linewidth=0.5, linestyle='--') # 添加水平线
plt.legend()
plt.grid()
# 显示图形
plt.show()
2、由于是多维数据之间的分布,势必要描述每个维度和每个维度数据点之间的关系。这个关系是由相关性来描述。范围在[-1,1]。
我们假设以二维正态分布举例,x对y的协方差(等同于y对x的协协方差,因为如此,方差协方差矩阵是对称的)假设是0,那么x和y分布完全独立。(请只关注紫色的点):
x对y的协方差(等同于y对x的协协方差)假设是0.5,那么x和y是正相关,并且这意味着当 x 的值增加时,y的值也倾向于增加,概率是0.5(意味着同时会有0.5的概率不增加)。(请只关注紫色的点):
x对y的协方差(等同于y对x的协协方差)假设是1,那么x和y是完全正相关,并且这意味着当 x 的值增加时,y的值必然增加。同时,这样的分布也转化成了一维的正态分布(请只关注紫色的点):
x对y的协方差(等同于y对x的协协方差)假设是-0.5,那么x和y是负相关,并且这意味着当 x 的值增加时,y的值有0.5的概率减小。(请只关注紫色的点):
x对y的协方差(等同于y对x的协协方差)假设是-1,那么x和y是完全负相关,并且这意味着当 x 的值增加时,y的值必然减小。同时,这样的分布也转化成了一维的正态分布(请只关注紫色的点):
1.1 明确自己要生成多少个数据点、每个数据点的维度
生成这样的样本点:
1、一个点、一个点、一个点……点的个数X是样本的个数
2、每个点用几维的向量表示,这个几维向量Y表示了每个点的坐标
那么张量(X,Y)表示了这样的数据集。可以确定的是,X的形状是(x,),其中x是样本的个数。Y的形状是y列的列表,y表示维度。
1.2 明确数据点的维度的均值和方差
这里描述的是每个数轴。这个分布在某个数轴的均值是多少,方差是多少。
1.3 理解协方差的含义
这里描述的是数轴与数轴之间的关系。一个数轴的数变化,另一个数轴有多少概率怎样变化。
2 如何使用Numpy实现,并且可视化
我的目标是生成两个服从于二元正态分布的点簇。两个簇的均值不同,方差和协方差一样。
2.1 生成数据点
以下以negative_samples为例
明确数据点个数num_samples_per_class为1000
明确在x轴上的均值是0,y轴上的均值是3
明确在x轴上的自方差是1,y轴上的自方差是1(对自己的方差是在对角线上的)
import numpy as np
num_samples_per_class = 1000
negative_samples = np.random.multivariate_normal(
mean=[0,3],
cov=[[1,0.5],[0.5,1]],
size=num_samples_per_class
)
positive_samples = np.random.multivariate_normal(
mean=[3,0],
cov=[[1,0.5],[0.5,1]],
size=num_samples_per_class
)
2.2 制作适用于可视化的张量
为了使得流程更加的规范,一般在前一步先准备好一簇一簇的数据,再准备一簇一簇的标签。最后先将数据堆叠起来,然后将标签堆叠起来。
准备好数据,进行堆叠。
inputs = np.vstack((negative_samples,positive_samples)).astype(np.float32)
准备好标签,进行堆叠。我的预期是对第一个簇创建一个(num_samples_per_class,1)形状的张量,这个1中存储的全是1,用来标记第一簇。同理标记第二簇,1中用0标记。
label_1=np.zeros(shape=(num_samples_per_class,1),dtype="float32")
label_2=np.ones(shape=(num_samples_per_class,1),dtype="float32")
targets=np.vstack(tup=(label_1,label_2))
2.3 可视化
用plt.scatter散点图进行可视化。我想展示的是二维坐标点,每一簇用不同的颜色表示。
其中的x参数要传入坐标点的x坐标,就是input的第二维张量(其是一个二维向量),取其中的第一列。
其中的y参数要传入坐标点的y坐标,就是input的第二维张量(其是一个二维向量),取其中的第二列。
c参数是类别的缩写,plt.scatter对不同标记点标签自动分配不同的颜色。这里对对应的簇分配了不同的标签,第一簇是0,第二簇是1。
plt.scatter
是 Matplotlib 库中用于绘制散点图的函数。我们来详细解释plt.scatter
函数中的参数含义:1.
x=inputs[:,0]
- 含义:这是散点图中每个点的 x 坐标。
- 解释:
inputs
是一个二维数组,其中每一行代表一个样本,每一列代表一个特征。inputs[:,0]
表示取出inputs
数组的第一列,即所有样本的第一个特征值(x 坐标)。2.
y=inputs[:,1]
- 含义:这是散点图中每个点的 y 坐标。
- 解释:
inputs[:,1]
表示取出inputs
数组的第二列,即所有样本的第二个特征值(y 坐标)。因此,散点图中的每个点的坐标由inputs
数组中的两个特征值决定。3.
c=targets[:,0]
- 含义:这是用于设置散点颜色的参数。
- 解释:
targets
是一个二维数组,其中每一行表示一个样本的目标标签(类别)。targets[:,0]
表示取出targets
数组的第一列,即所有样本的标签值。这里,标签值为 0 表示负样本,标签值为 1 表示正样本。c
参数将根据这些标签值为散点图中的点着色。4. 其他参数(未显示)
虽然在这段代码中没有使用其他参数,但
plt.scatter
函数还可以接受许多其他参数,例如:
s
:设置散点的大小。marker
:设置散点的形状(如圆形、方形等)。alpha
:设置散点的透明度。cmap
:设置颜色映射。
import matplotlib.pyplot as plt
plt.scatter(x=inputs[:,0],y=inputs[:,1],c=targets[:,0])
plt.show()
3 拓展应用:三维三簇的可视化
数据准备都一样,绘图要使用mpl_toolkits.mplot3d
中的 Axes3D
以支持三维绘图。
1. 创建三维图形
fig = plt.figure()
- 含义:这行代码用于创建一个新的图形窗口。
- 解释:
plt.figure()
是 Matplotlib 中的一个函数,用于初始化一个新的图形对象。图形对象是所有绘图的基础,包含了坐标轴、标题、图例等元素。每次调用plt.figure()
都会创建一个新的图形窗口。
ax = fig.add_subplot(111, projection='3d')
- 含义:这行代码用于在图形中添加一个三维坐标轴。
- 解释:
fig.add_subplot(111)
:这个方法用于在图形中添加一个子图。参数111
表示将图形划分为 1 行 1 列,并选择第 1 个子图。这里的1
表示行数,第二个1
表示列数,第三个1
表示选择的子图索引。projection='3d'
:这个参数指定该子图为三维坐标轴。通过设置projection='3d'
,Matplotlib 将会使用三维绘图的功能,使得后续的绘图操作可以在三维空间中进行。2. 绘制三维散点图
ax.scatter(...)
- 含义:这行代码用于在三维坐标轴上绘制散点图。
- 解释:
ax.scatter
是 Matplotlib 中用于绘制三维散点图的方法。它接受多个参数来定义散点的坐标、颜色、大小等属性。- 常用参数包括:
x
:散点的 x 坐标数组。y
:散点的 y 坐标数组。z
:散点的 z 坐标数组。c
:散点的颜色,可以是颜色数组或类别标签。s
:散点的大小,可以是一个标量或数组,表示每个点的大小。alpha
:散点的透明度,取值范围在 0(完全透明)到 1(完全不透明)之间。
代码和结果如下:
import numpy as np
num_samples_per_class = 1000
A_samples = np.random.multivariate_normal(
mean=[0,3,5],
cov=[[1,0.5,0.5],[0.5,1,0.5],[0.5,0.5,1]],
size=num_samples_per_class
)
B_samples = np.random.multivariate_normal(
mean=[3,0,-3],
cov=[[1,0.5,0.5],[0.5,1,0.5],[0.5,0.5,1]],
size=num_samples_per_class
)
C_samples = np.random.multivariate_normal(
mean=[7,5,0],
cov=[[1,0.5,0.5],[0.5,1,0.5],[0.5,0.5,1]],
size=num_samples_per_class
)
inputs = np.vstack((A_samples,B_samples,C_samples)).astype(np.float32)
# 创建标签
label_0 = np.zeros(shape=(num_samples_per_class, 1), dtype="float32") # 类别 0
label_1 = np.ones(shape=(num_samples_per_class, 1), dtype="float32") # 类别 1
label_2 = np.full(shape=(num_samples_per_class, 1), fill_value=2, dtype="float32") # 类别 2
targets=np.vstack(tup=(label_0,label_1,label_2))
from mpl_toolkits.mplot3d import Axes3D
# 创建三维图形
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制三维散点图
scatter = ax.scatter(xs=inputs[:, 0], ys=inputs[:, 1], zs=inputs[:, 2], c=targets[:, 0], s=20)
# 添加图例
legend1 = ax.legend(*scatter.legend_elements(), title="Classes")
ax.add_artist(legend1)
# 设置坐标轴标签
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
fig
标签:plt,0.5,生成,协方差,num,可视化,samples,np,正态分布
From: https://blog.csdn.net/weixin_65259109/article/details/144924299