高斯混合模型GMM,实现二维平面点聚类,附代码

1、随机生成点

    def generate_points_in_circle(self, center, num_points, radius):
        """
        在圆形区域内生成点,使用高斯分布生成偏移量
        """
        x_center, y_center = center
        points = []
        for _ in range(num_points):
            # 生成极坐标表示的偏移量
            r = np.random.normal(0, radius / 3)  # 高斯分布生成径向偏移
            theta = np.random.uniform(0, 2 * np.pi)  # 均匀分布生成角向偏移

            # 转换极坐标到直角坐标
            x_offset = r * np.cos(theta)
            y_offset = r * np.sin(theta)

            # 计算新点的坐标
            x = x_center + x_offset
            y = y_center + y_offset

            points.append((x, y))

        return points

2、定义点类,class POINTS

class POINTS():
    def __init__(self, center: object = (200, 200), number: object = 50, radius: object = 120,
                 pltsize: object = (10, 10), xlim: object = (0, 640), ylim: object = (0, 640),
                 xyticks: object = (0, 640, 100), marker: object = '.', markersize: object = 120,
                 color: object = 'blue', centercolor: object = 'red', showlegend: object = False,
                 point_list: object = None) -> object:

3、创建点对象

    points_blue1 = POINTS(center=(200, 200), number=400, radius=250,
                         pltsize=(10, 10), xlim=(0, 640), ylim=(0, 640), xyticks=(0, 640, 100),
                         marker='.', markersize=120, color='blue', centercolor='blue',
                         showlegend=False, point_list=points_1)

    points_blue2 = POINTS(center=(350, 350), number=400, radius=250,
                        pltsize=(10, 10), xlim=(0, 640), ylim=(0, 640), xyticks=(0, 640, 100),
                        marker='.', markersize=120, color='blue', centercolor='blue',
                        showlegend=False, point_list=points_2)

4、画点

plot_points([points_blue1, points_blue2])

def plot_points(POINTS_list):
    assert isinstance(POINTS_list, list) and len(POINTS_list) > 0, "points is not list"
    points_num = len(POINTS_list)
    # 设置坐标系大小
    plt.figure(figsize=POINTS_list[0].plot_size)
    # 设置坐标轴长度
    plt.xlim(POINTS_list[0].xlim)
    plt.ylim(POINTS_list[0].ylim)

    for p in POINTS_list:
        x_center, y_center = p.center_point
        # 提取点的 x 和 y 坐标
        x_points, y_points = zip(*p.points)
        # 绘制中心点
        if p.isRandom:
            plt.scatter(x_center, y_center, color=p.centercolor, label='Center', marker='o')
        # 绘制随机生成的点
        plt.scatter(x_points, y_points, color=p.color, label='Random Points', marker=p.marker, s=p.marker_sz)
        # 显示图例
        if p.showlegend:
            plt.legend()

    # 显示图形
    plt.xlabel('X-axis')
    plt.ylabel('Y-axis')
    plt.title('Random Points around Center')
    plt.grid(True)
    # 添加刻度及刻度间隔
    plt.xticks(np.arange(*POINTS_list[0].xyticks))
    plt.yticks(np.arange(*POINTS_list[0].xyticks))
    plt.show()

用不同颜色区分两次随机点

5、使用GMM聚类

定义GMM

def GMM(data):
    gmm = GaussianMixture(n_components=2, covariance_type='full', tol=1e-6, max_iter=1000)
    gmm.fit(data)
    predict = gmm.predict(data)
    cluster_list = [data[predict == i] for i in np.unique(predict)]
    return cluster_list

聚类

    data = np.row_stack((points_1, points_2))  # 800X2   800个点(x,y)
    cluster_list = GMM(data)
    points_1, points_2 = cluster_list

聚类结果

    points_blue = POINTS(center=(200, 200), number=400, radius=250,
                         pltsize=(10, 10), xlim=(0, 640), ylim=(0, 640), xyticks=(0, 640, 100),
                         marker='.', markersize=120, color='blue', centercolor='blue',
                         showlegend=False, point_list=points_1)

    points_red = POINTS(center=(350, 350), number=400, radius=250,
                        pltsize=(10, 10), xlim=(0, 640), ylim=(0, 640), xyticks=(0, 640, 100),
                        marker='.', markersize=120, color='red', centercolor='red',
                        showlegend=False, point_list=points_2)


    plot_points([points_blue, points_red])

左图聚类结果,右图原始随机点

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值