Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm matlab代码优化-聚类算法KFCG 背景_Algorithm_Matlab_Optimization_Cluster Analysis - Fatal编程技术网

Algorithm matlab代码优化-聚类算法KFCG 背景

Algorithm matlab代码优化-聚类算法KFCG 背景,algorithm,matlab,optimization,cluster-analysis,Algorithm,Matlab,Optimization,Cluster Analysis,我有一大组向量(轴角度表示中的方向数据…轴就是向量)。我想将聚类算法应用于。我尝试了kmeans,但计算时间太长(从未完成)。因此,我尝试实现更快的KFCG算法(Kirke 2010): 最初,我们有一个包含整个训练向量和作为质心的码向量C1的簇。在算法的第一次迭代中,通过比较训练向量席的第一元素与码向量C1的第一元素来形成聚类。如果XI1<C11,则向量XI被分组到聚类1中,否则矢量席席被分组成簇2,如图2(a)中,码子维数空间为2。在第二次迭代中,通过将属于聚类1的向量席X2的第二元素XI2

我有一大组向量(轴角度表示中的方向数据…轴就是向量)。我想将聚类算法应用于。我尝试了kmeans,但计算时间太长(从未完成)。因此,我尝试实现更快的KFCG算法(Kirke 2010):

最初,我们有一个包含整个训练向量和作为质心的码向量C1的簇。在算法的第一次迭代中,通过比较训练向量席的第一元素与码向量C1的第一元素来形成聚类。如果XI1<C11,则向量XI被分组到聚类1中,否则矢量席席被分组成簇2,如图2(a)中,码子维数空间为2。在第二次迭代中,通过将属于聚类1的向量席X2的第二元素XI2与码矢的第二元素的第二元素XI2进行比较,将簇1分成两个。通过将属于聚类2的向量席XII的第二元素XI2与代码框的第二元素的第二元素XI2进行比较,如图2(b)所示,将簇2分成两个。重复此过程,直到码本大小达到用户指定的大小

我不确定什么比例适合于代码本,但这对于代码优化来说并不重要。另外请注意,我的是三维的,所以同样的过程也适用于三维

我的代码尝试 我已经尝试在Matlab2013(学生版)中实现上述算法。以下是我尝试过的一些不同的结构-但耗时太长(从未见过它完成):

要优化的主块:

%KFCG:
%%cluster = cell(1,Nsel); %Unsure #rows - Don't know how to initialize if need mean...
codevec(1,1:3) = mean(vecA,1);
count1=1;
count2=1;
ind=1;
for kk = 1:NselIter
    hh2 = 1:2:size(codevec,1)*2;
    for hh1 = 1:length(hh2)
        hh=hh2(hh1);
%        for ii = 1:roA
%            if vecA(ii,ind) < codevec(hh1,ind)
%                cluster{1,hh}(count1,1:4) = Atgood(ii,:); %want all 4 elements
%                count1=count1+1;
%            else
%                cluster{1,hh+1}(count2,1:4) = Atgood(ii,:); %want all 4
%                count2=count2+1;
%            end
%        end
        %EDIT: My ATTEMPT at optimizing above for loop:
        repcv=repmat(codevec(hh1,ind),[size(vecA,1),1]); 
        splitind = vecA(:,ind)>=repcv; 
        splitind2 = vecA(:,ind)<repcv;
        cluster{1,hh}=vecA(splitind,:); 
        cluster{1,hh+1}=vecA(splitind2,:);
    end
    clear codevec
    %Only mean the 1x3 vector portion of the cluster - for centroid
    codevec = cell2mat((cellfun(@(x) mean(x(:,1:3),1),cluster,'UniformOutput',false))');
    if ind < 3
        ind = ind+1;
    else
        ind=1;
    end 
end
if length(codevec) ~= Nsel
    warning('codevec ~= Nsel');
end
或者,我认为3D矩阵会比细胞更快?我尝试过,但使用每次迭代都追加下一行的方法(for…temp=[temp;new];)速度较慢

此外,我也不确定什么是最好的循环方式,无论何时:

%If initialize cell to full length
while length(find(~cellfun('isempty',cluster))) < Nsel

您最大的问题是对每个代码向量重新迭代所有的vecA,而不仅仅是对应集群的一部分。你应该在它的代码向量上分割每个簇。事实上,集群结构不断增长,每次迭代都在处理越来越多的样本

第二个问题是围绕比较的循环,以及添加样本以构建集群。这两个问题都可以通过矢量化比较操作来解决。哦,我刚看到你的编辑,这是优化。好多了。但是
codevec(hh1,ind)
只是一个标量,所以您甚至不需要repmat

请尝试以下版本:

% (preallocs added in edit)
cluster = cell(1,Nsel);
codevec = zeros(Nsel, 3);

codevec(1,:) = mean(Atgood(:,1:3),1);
cluster{1} = Atgood;

nClusters = 1;
ind = 1;
while nClusters < Nsel
    for c = 1:nClusters
        lower_cluster_logical = cluster{c}(:,ind) < codevec(c,ind);
        cluster{nClusters+c} = cluster{c}(~lower_cluster_logical,:);
        cluster{c} = cluster{c}(lower_cluster_logical,:);
        codevec(c,:) = mean(cluster{c}(:,1:3), 1);
        codevec(nClusters+c,:) = mean(cluster{nClusters+c}(:,1:3), 1);
    end
    ind = rem(ind,3) + 1;
    nClusters = nClusters*2;
end
%(在编辑中添加了预分配)
集群=单元(1,Nsel);
codevec=零(Nsel,3);
codevec(1,:)=平均值(Atgood(:,1:3),1);
簇{1}=Atgood;
nClusters=1;
ind=1;
而nClusters
也许为了删除循环,我可以重新绘制codevec,然后进行减法(而不是if语句),然后以负数分隔这些索引?您上面发布的最小示例对您有用吗?如果我复制/粘贴它,我会在
cellfun(@(x)mean(x(:,1:3),1)中得到一个
索引超过矩阵维度的错误,…
哇,取出
集群
变量的初始化。请参见编辑。仍然不确定代码是否达到我认为的效果…也许可以使用repmat:
repcv=repmat(codevc,[size])删除(vecA,1),1]);
splitind=find(vecA>repcv);
splitind2=find(顺便说一句,Nsel似乎有问题。你真的想要数据点一半的集群吗?平均2点的集群大小?这似乎很奇怪。哇,感谢你澄清,我看到了第一个问题中我的错误……就像我在问题中说的,我不确定我能压缩多少数据;0.5太高了,谢谢为了指出这一点,…Nsel=0.2*总计给出了约373秒的运行时间…是否有任何方法可以预分配
群集
?当然:群集=单元格(1,Nsel)你是对的,这可能会有很大的不同。操作,预分配codevec,我的1e6点时间下降到28秒。编辑后添加预分配。所以,我不太明白集群是如何填充的-这个循环是否覆盖了集群?(第一次通过for循环:
nClusters=1
c=1
,所以
cluster{2}
集群{1}
已填充。)(第二次通过:
nClusters=1
c=2
,所以
集群{3}
集群{2}
已填充。)-所以2被覆盖???一些集群是空的,这就是我问的原因。
for ii=1:1000 %My size is ~ 1,000,000
    omega = 2*rand(3,1)-1;
    omega = (omega/norm(omega))';
    Atgood(ii,1:4) = [omega,57];
end
% (preallocs added in edit)
cluster = cell(1,Nsel);
codevec = zeros(Nsel, 3);

codevec(1,:) = mean(Atgood(:,1:3),1);
cluster{1} = Atgood;

nClusters = 1;
ind = 1;
while nClusters < Nsel
    for c = 1:nClusters
        lower_cluster_logical = cluster{c}(:,ind) < codevec(c,ind);
        cluster{nClusters+c} = cluster{c}(~lower_cluster_logical,:);
        cluster{c} = cluster{c}(lower_cluster_logical,:);
        codevec(c,:) = mean(cluster{c}(:,1:3), 1);
        codevec(nClusters+c,:) = mean(cluster{nClusters+c}(:,1:3), 1);
    end
    ind = rem(ind,3) + 1;
    nClusters = nClusters*2;
end