Matlab:如何将一个聚类代码定制为多级聚类?

Matlab:如何将一个聚类代码定制为多级聚类?,matlab,cluster-analysis,multistage,Matlab,Cluster Analysis,Multistage,我想对大量的数据记录进行集群。我正在处理的数据是字符串类型的。聚类过程需要很长时间。 假设我想将一组电子邮件数据记录集群到集群中,由同一个人编写的电子邮件被分配到同一集群中(考虑到一个人可能以不同的方式书写自己的姓名)。 我想执行多阶段群集: function [IDX, isnoise] = dbscan_strings(X,epsilon,MinPts) C = 0; n = size(X,1); IDX = zeros(n,1); D = pdist2(X,X,@intersection

我想对大量的数据记录进行集群。我正在处理的数据是字符串类型的。聚类过程需要很长时间。
假设我想将一组电子邮件数据记录集群到集群中,由同一个人编写的电子邮件被分配到同一集群中(考虑到一个人可能以不同的方式书写自己的姓名)。
我想执行多阶段群集:

function [IDX, isnoise] = dbscan_strings(X,epsilon,MinPts)
C = 0;
n = size(X,1); 
IDX = zeros(n,1);
D = pdist2(X,X,@intersection);
visited = false(n,1);
isnoise = false(n,1);
for i = 1:n
    if ~visited(i)
        visited(i) = true;
        Neighbors = RegionQuery(i);
        if numel(Neighbors)<MinPts
            % X(i,:) is NOISE
            isnoise(i) = true;
        else
            C = C+1;
            ExpandCluster(i,Neighbors,C);
        end
    end
end

function ExpandCluster(i,Neighbors,C)
    IDX(i) = C;
    k = 1;
    while true
        j = Neighbors(k);
        if ~visited(j)
            visited(j) = true;
            Neighbors2 = RegionQuery(j);
            if numel(Neighbors2)>=MinPts
                Neighbors = [Neighbors Neighbors2];   %#ok
            end
        end
        if IDX(j)==0
            IDX(j) = C;
        end
        k = k + 1;
        if k > numel(Neighbors)
            break;
        end
    end
end

function Neighbors = RegionQuery(i)
    Neighbors = find(D(i,:)<=epsilon);
end
end
  • 基于名称的第一阶段聚类,如果两个记录之间的名称距离小于阈值,则考虑这些簇否则…<李>
  • 数据记录进入基于其他属性(名称除外)的聚类的第二阶段
计算成对距离。现在我处于集群阶段。我想使用以下代码进行
dbscan
群集:

function [IDX, isnoise] = dbscan_strings(X,epsilon,MinPts)
C = 0;
n = size(X,1); 
IDX = zeros(n,1);
D = pdist2(X,X,@intersection);
visited = false(n,1);
isnoise = false(n,1);
for i = 1:n
    if ~visited(i)
        visited(i) = true;
        Neighbors = RegionQuery(i);
        if numel(Neighbors)<MinPts
            % X(i,:) is NOISE
            isnoise(i) = true;
        else
            C = C+1;
            ExpandCluster(i,Neighbors,C);
        end
    end
end

function ExpandCluster(i,Neighbors,C)
    IDX(i) = C;
    k = 1;
    while true
        j = Neighbors(k);
        if ~visited(j)
            visited(j) = true;
            Neighbors2 = RegionQuery(j);
            if numel(Neighbors2)>=MinPts
                Neighbors = [Neighbors Neighbors2];   %#ok
            end
        end
        if IDX(j)==0
            IDX(j) = C;
        end
        k = k + 1;
        if k > numel(Neighbors)
            break;
        end
    end
end

function Neighbors = RegionQuery(i)
    Neighbors = find(D(i,:)<=epsilon);
end
end
function[IDX,isnoise]=dbscan\u字符串(X,epsilon,MinPts)
C=0;
n=尺寸(X,1);
IDX=零(n,1);
D=pdist2(X,X,@交点);
访问=假(n,1);
isnoise=false(n,1);
对于i=1:n
如果访问(i)
访问(i)=真实;
邻居=区域查询(i);
如果numel(邻居)=MinPts
邻居=[邻居邻居2];%#好啊
结束
结束
如果IDX(j)==0
IDX(j)=C;
结束
k=k+1;
如果k>numel(邻居)
打破
结束
结束
结束
函数邻居=区域查询(i)

邻居=find(D(i,:)不要一下子做每件事

你正在计算很多你永远不需要的东西,这使得事情变得很慢。例如,一个好的DBSCAN不使用距离函数,而是使用索引

对于名称,只处理唯一的名称!您可能有许多完全相同的名称,但最终会一次又一次地计算相同的距离

因此,首先,只构建一组唯一的名称。在此基础上执行相似性匹配(不过我建议使用OpenRefine,而不是Matlab!)。
一旦您确定了要合并的名称,为每个名称组构建一个新的数据矩阵。然后运行您想要的任何群集。好的候选者可能是HDBSCAN和OPTICSXi(看看ELKI中可用的群集算法,它可能有最广泛的选择)。可能只从一个普通名称开始,以了解算法的参数。不要一次对所有子集进行聚类。

StackOverflow不是一个真正的代码编写服务,尽管你可能会找到愿意帮助的人(特别是有赏金的人)。为了使这成为一个好的编程问题,你应该展示你自己的努力,并指出你无法解决的问题所在。这可能是一些你缺乏编程技能的概念性想法,或者是一个你尝试过但因无法解决的原因而失败的实现。第二条建议。我没有潜水尝试去理解你已经有了,因为它缺少文档和注释。你有很多函数,在那段代码中有一堆变量,我一眼就看不出它们的意思。试着添加一些总体线索来了解你的代码在做什么以及变量的意思。这将有助于以下几个原因:哟你现在会更好地理解你的代码,但也会回忆起它将来是如何工作的;其他人(程序员或用户)我不会要求编写代码。我的代码已经编写好了。我要求的是总体上的帮助。我要求的是想法?我应该修改代码的哪行?类似这样的东西。我不知道如何执行这一步骤一旦确定要合并的名称,为每个na构建一个新的数据矩阵还有如何组合第一和第二个聚类阶段的结果我不使用Matlab,所以我无法为您解释代码。但是子集运算是一个非常基本的运算。