You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB实现二分K-means报逻辑索引越界错误 如何解决

MATLAB运行K-means聚类时报错:The logical indices in position 1 contain a true value outside of the array bounds,即位置1的逻辑索引在数组边界外存在真值,属于数组索引越界类错误。

报错核心诱因

你遇到的逻辑索引越界问题,根源是代码的聚类结果变量维护逻辑完全不符合二分K-means的实现要求,具体问题点:

  • 每次拆分簇时,直接用拆分小簇生成的idx/C/sumd覆盖了全数据集对应的全局聚类变量。新生成的idx长度仅等于被拆分的那个簇的样本量,远小于原数据集X的总行数,下一轮循环用这个短长度的逻辑数组去索引全量X时,一旦逻辑值出现的位置超过短数组对应到原数组的长度范围,就会触发边界外真值的报错。
  • 没有做聚类结果的全局更新:二分K-means要求每次拆分SSE(即sumd存储的簇内平方和)最大的簇为2个子簇后,要把2个新子簇的标签、质心、SSE更新回全局聚类结果中,总簇数逐轮+1直到达到目标值。原代码没有做这个全局更新步骤,相当于每轮循环都在上一轮拆分出的小数据集上重复聚类,数据规模逐轮缩小,和全局变量的维度差越来越大,必然触发索引错误。

你之前推测的“没有先将所有数据合并为单个簇”不是核心原因,初始化时全量数据本身就是初始单个簇,问题出在拆分后的结果同步逻辑。

修复代码

修复后完全符合二分K-means逻辑,可直接运行:

X = rand(1482,74);
nCluster = 12;

% 初始化:第一次将全量数据拆为2个簇
global_idx = kmeans(X,2);
k_current = 2;
% 预分配质心、簇内平方和存储
global_C = zeros(nCluster, size(X,2));
global_sumd = zeros(nCluster,1);
% 填充初始2个簇的质心和SSE
for i = 1:k_current
    cluster_sample = X(global_idx==i,:);
    global_C(i,:) = mean(cluster_sample,1);
    global_sumd(i) = sum(pdist2(cluster_sample, global_C(i,:)).^2);
end

% 逐轮拆分直到达到目标簇数
for pp = 3:nCluster
    % 找到当前SSE最大的簇(即最需要拆分的簇)
    [~, split_target_id] = max(global_sumd(1:k_current));
    % 取出待拆分簇的所有样本
    split_samples = X(global_idx == split_target_id, :);
    % 对目标簇做2分聚类
    [sub_idx, sub_C, sub_sumd] = kmeans(split_samples, 2);
    
    % 更新全局聚类结果:将被拆分的簇替换为第一个子簇
    global_C(split_target_id,:) = sub_C(1,:);
    global_sumd(split_target_id) = sub_sumd(1);
    % 第二个子簇作为新的簇追加到全局结果中
    new_cluster_id = k_current + 1;
    global_C(new_cluster_id,:) = sub_C(2,:);
    global_sumd(new_cluster_id) = sub_sumd(2);
    % 更新全局样本标签:原属于待拆分簇的样本,按子聚类结果分配标签
    target_sample_pos = find(global_idx == split_target_id);
    global_idx(target_sample_pos(sub_idx==2)) = new_cluster_id;
    
    % 当前总簇数+1
    k_current = k_current + 1;
end

% 最终输出结果:idx为样本聚类标签,C为质心,sumd为各簇SSE
[idx, C, sumd] = deal(global_idx, global_C(1:k_current,:), global_sumd(1:k_current));
关键修复点说明
  • 全程单独维护全局维度的global_idx/global_C/global_sumd变量,所有索引操作始终和原数据集X的维度匹配,从根源避免逻辑索引长度不匹配导致的越界问题
  • 严格按照二分K-means的标准流程更新聚类结果:每轮仅拆分SSE最大的簇,拆分后同步更新全局标签、质心、簇内平方和,总簇数逐轮递增直到达到设定值
  • 修复了原代码直接用小簇聚类结果覆盖全量结果的逻辑错误,聚类结果符合二分K-means的输出要求

内容的提问来源于stack exchange,提问作者Emanuele Gandolfi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:24:28