马尔可夫聚类算法

时间:2012-01-06 20:50:56

标签: 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文档规定在每次传递时规范化矩阵)
  4. 所有这些都返回了相同的结果 - 节点只影响自身。

    我甚至在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;
    }; 
    

    这是通胀函数

    // 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);
    };
    

    最后是主要的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;
    };
    

2 个答案:

答案 0 :(得分:2)

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

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

澄清有关该算法的一些观点。

  1. 膨胀然后膨胀。
  2. 精确度是一个重要因素。方程式永远不会导致数学收敛。它在cpus上的浮点运算的精度有限,导致矩阵中的某些项变为零而不是无限小的数。事实上,官方实现使用截止值来消除每列的一定数量的项目,以加速收敛并提高算法的时间复杂度。在原始论文中,作者分析了其影响并得出结论,截止在实践中给出的结果与通胀参数的略微增加相同。
  3. 归一化是充气步骤的一个组成部分,再次阅读该指南中的等式。
  4. 关于你的代码。

    1. array.slice创建一个浅拷贝,但这在你的情况下并不重要,因为你在matrixExpand中创建了一个新数组。
    2. 您对matrixExpand的实现忽略了pow变量,并始终使用2的幂。
    3. 预期第一行中存在所有元素的结果,这被解释为所有元素都在同一个集群中。

答案 1 :(得分:0)

使用currentMatrix.slice克隆矩阵看起来很可疑。这是一个浅薄的克隆,因为你正在改变,这可能会带来麻烦。

使用round也看​​起来有点奇怪,因为没有提到舍入作为powerpoint演示文稿中规范化步骤的一部分。