从300个点中选择使得方差最小的200个点

为了从300个点中选择200个点,使得这200个点的方差最小(即点集在特征空间中最紧凑),可以采用以下优化方法。核心思路是通过迭代优化逼近局部最优解,结合多组初始解避免陷入不良局部最优。以下是具体步骤:


方法概述

  1. 目标函数:最小化选出的200个点的总方差(Trace of Covariance),即各维度方差之和:
    Vartotal=∑i∈S(∥xi−μS∥2) \text{Var}_{\text{total}} = \sum_{i \in S} \left( \| \mathbf{x}_i - \boldsymbol{\mu}_S \|^2 \right) Vartotal=iS(xiμS2)
    其中 SSS 是选中的点集,μS\boldsymbol{\mu}_SμS 是其质心。

  2. 算法选择:使用 迭代重定位算法(类似K-Means的思想),通过交替更新质心和重新选择最近点逐步降低方差。

  3. 关键技巧

    • 多组初始化:结合中心点初始化和随机初始化,避免局部最优。
    • 早停机制:当目标函数变化小于阈值时停止迭代。

具体步骤

1. 初始化策略
  • 中心初始化:计算所有300个点的质心,选择离质心最近的200个点作为初始解(快速且通常接近优解)。
  • 随机初始化:生成多组随机选择的200个点,用于探索不同区域。
2. 迭代优化

对每组初始解进行迭代:

  • Step 1:计算当前200个点的质心 μS\boldsymbol{\mu}_SμS
  • Step 2:计算所有300个点到 μS\boldsymbol{\mu}_SμS 的欧氏距离平方。
  • Step 3:选择距离最小的200个点作为新子集。
  • Step 4:计算新子集的目标函数值(总方差)。
  • 停止条件
    • 目标函数变化量 < 阈值(如 1e-6
    • 或达到最大迭代次数(如 100 次)。
3. 选择最优解

保留所有初始化中目标函数值最小的子集作为最终结果。


Python代码实现

import numpy as np
import random

def select_min_variance_points(points, n_select=200, n_inits=10, max_iters=100, tol=1e-6):
    """
    从points中选择n_select个点,使其方差最小
    :param points: np数组, 形状为(300, 2)
    :param n_select: 需选择的点数
    :param n_inits: 初始化次数
    :param max_iters: 最大迭代次数
    :param tol: 收敛阈值
    :return: 选中的点索引, 最终目标函数值
    """
    n_points = points.shape[0]
    best_subset = None
    best_obj = float('inf')

    # 初始化策略
    initial_subsets = []
    
    # 1. 中心初始化: 基于全局质心
    centroid_all = np.mean(points, axis=0)
    dists_to_center = np.sum((points - centroid_all)**2, axis=1)
    center_init = np.argsort(dists_to_center)[:n_select]
    initial_subsets.append(center_init)
    
    # 2. 随机初始化
    for _ in range(n_inits - 1):
        random_init = random.sample(range(n_points), n_select)
        initial_subsets.append(random_init)

    # 迭代优化每组初始解
    for subset in initial_subsets:
        obj_val = compute_objective(points[subset])
        for _ in range(max_iters):
            # Step 1: 计算当前子集质心
            centroid = np.mean(points[subset], axis=0)
            
            # Step 2: 计算所有点到质心的距离平方
            dists = np.sum((points - centroid)**2, axis=1)
            
            # Step 3: 选择最近的n_select个点
            new_subset = np.argpartition(dists, n_select)[:n_select]
            new_obj = compute_objective(points[new_subset])
            
            # 停止判断: 目标函数变化小于阈值
            if abs(obj_val - new_obj) < tol:
                break
                
            subset = new_subset
            obj_val = new_obj
        
        # 更新全局最优解
        if new_obj < best_obj:
            best_obj = new_obj
            best_subset = subset

    return best_subset, best_obj

def compute_objective(subset_points):
    """计算子集的总方差 (目标函数)"""
    centroid = np.mean(subset_points, axis=0)
    return np.sum((subset_points - centroid)**2)


# 使用示例
if __name__ == "__main__":
    # 生成示例数据: 300个2维点
    np.random.seed(0)
    points = np.random.rand(300, 2) * 100  # (x, y)坐标
    
    # 选择方差最小的200个点
    selected_indices, min_variance = select_min_variance_points(points)
    print("选中的点索引:", selected_indices)
    print("最小总方差:", min_variance)

算法特点

  • 时间复杂度:每组初始化迭代计算 O(max_iters×300)O(\text{max\_iters} \times 300)O(max_iters×300),总开销 O(n_inits×max_iters×300)O(\text{n\_inits} \times \text{max\_iters} \times 300)O(n_inits×max_iters×300),对300个点可瞬时完成。
  • 最优性保证:多组初始化(中心+随机)显著降低陷入局部最优的风险。
  • 扩展性:可调整参数(如 n_initstol)平衡精度与速度。

数学解释

目标函数 Vartotal\text{Var}_{\text{total}}Vartotal 在迭代中单调下降:

  1. 固定质心时,选择最近点最小化当前距离和。
  2. 更新质心后,目标函数值进一步降低(因质心是方差最小点)。
  3. 每次迭代目标函数值非增,最终收敛到局部最优。

通过多组初始化,算法以高概率逼近全局最优解。此方法在点集精简(Subset Selection)、核心集(Coreset)构建等任务中广泛应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高山莫衣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值