马尔可夫聚类算法

met*_*din 8 javascript cluster-analysis markov

我一直在研究Markov聚类算法细节的以下示例:

http://www.cs.ucsb.edu/~xyan/classes/CS595D-2009winter/MCL_Presentation2.pdf

我觉得我已经准确地表示了算法,但我得到的结果与本指南至少得到的结果相同.

当前代码位于:http: //jsfiddle.net/methodin/CtGJ9/

我不确定是否我错过了一个小事实,或者只是需要在某个地方进行小调整,但我尝试了一些变化,包括:

  1. 交换通货膨胀/扩张
  2. 根据精度检查相等性
  3. 删除规范化(因为原始指南不需要它,尽管官方MCL文档规定在每次传递时规范化矩阵)

所有这些都返回了相同的结果 - 节点只影响自身.

我甚至在VB中找到了类似的算法实现:http: //mcl.codeplex.com/SourceControl/changeset/changes/17748#MCL%2fMCL%2fMatrix.vb

我的代码似乎与它们的编号(例如600 - 距离)相匹配.

这是扩展功能

// Take the (power)th power of the matrix effectively multiplying it with
// itself pow times
this.matrixExpand = function(matrix, pow) {
    var resultMatrix = [];
    for(var row=0;row<matrix.length;row++) {
        resultMatrix[row] = [];
        for(var col=0;col<matrix.length;col++) {
            var result = 0;
            for(var c=0;c<matrix.length;c++)
                result += matrix[row][c] * matrix[c][col];
            resultMatrix[row][col] = result;
        }
    }
    return resultMatrix;
}; 
Run Code Online (Sandbox Code Playgroud)

这就是通胀功能

// Applies a power of X to each item in the matrix
this.matrixInflate = function(matrix, pow) {
    for(var row=0;row<matrix.length;row++) 
        for(var col=0;col<matrix.length;col++)
            matrix[row][col] = Math.pow(matrix[row][col], pow);
};
Run Code Online (Sandbox Code Playgroud)

最后是主要的passthru功能

// Girvan–Newman algorithm
this.getMarkovCluster = function(power, inflation) {
    var lastMatrix = [];

    var currentMatrix = this.getAssociatedMatrix();
    this.print(currentMatrix);        
    this.normalize(currentMatrix);  

    currentMatrix = this.matrixExpand(currentMatrix, power);    
    this.matrixInflate(currentMatrix, inflation);                               
    this.normalize(currentMatrix);

    while(!this.equals(currentMatrix,lastMatrix)) {
        lastMatrix = currentMatrix.slice(0);

        currentMatrix = this.matrixExpand(currentMatrix, power);                
        this.matrixInflate(currentMatrix, inflation);         
        this.normalize(currentMatrix);            
    }
    return currentMatrix;
};
Run Code Online (Sandbox Code Playgroud)

Mic*_*ski 2

您的实施是正确的。这个例子只是错误的。

“重复步骤 5 和 6 直到达到稳定状态(收敛)”幻灯片上的三个结果矩阵是仅执行膨胀的结果。

澄清有关算法的一些要点。

  1. 扩张然后通货膨胀。
  2. 精度是一个重要因素。这些方程永远不会导致数学上的收敛。cpu 上浮点运算的精度有限,导致矩阵中的某些项变为零而不是无限小数字。事实上官方的实现是使用一个截止值来消除每列一定数量的项,以加快收敛速度​​并提高算法的时间复杂度。在最初的论文中,作者分析了这一点的影响,并得出结论:在实践中,截止值与稍微增加通货膨胀参数会产生相同的结果。
  3. 标准化是通货膨胀步骤的一个组成部分,请再次阅读该指南中的方程式。

关于你的代码。

  1. array.slice 创建一个浅拷贝,但这对于您的情况并不重要,因为您在 matrixExpand 中创建了一个新数组。
  2. 您的matrixExpand 实现会忽略pow 变量,并且始终执行2 的幂。

第一行中包含所有元素的结果是预期的,这被解释为所有元素都在同一簇中。