8

マルコフ クラスタリング アルゴリズムの詳細については、次の例を参照してください。

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

これがインフレ関数です

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

そして最後にメインのパススルー機能

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

2 に答える 2

2

あなたの実装は正しいです。例は間違っています。

「定常状態に達するまで手順 5 と 6 を繰り返す (収束)」スライドの 3 つの結果マトリックスは、インフレーションのみを実行した結果です。

アルゴリズムに関するいくつかの点を明確にする。

  1. 拡大の次はインフレ。
  2. 精度は重要な要素です。方程式が数学的に収束することは決してありません。これは、行列内の一部の項目が無限に小さい数値ではなくゼロになる原因となる、CPU での浮動小数点演算の精度が制限されているためです。実際、公式の実装では、カットオフ値を使用して列ごとに一定量のアイテムを削除し、収束を高速化し、アルゴリズムの時間の複雑さを改善しています。元の論文では、著者はこの効果を分析し、カットオフは実際にはインフレ パラメータのわずかな増加と同じ結果をもたらすと結論付けました。
  3. 正規化はインフレ ステップの不可欠な部分です。そのガイドの式をもう一度読んでください。

あなたのコードについて。

  1. array.slice は浅いコピーを作成しますが、matrixExpand で新しい配列を作成するため、これは重要ではありません。
  2. matrixExpand の実装は pow 変数を無視し、常に 2 の累乗を行います。

最初の行にすべて 1 がある結果が期待されます。これは、すべての要素が同じクラスターにあると解釈されます。

于 2012-09-04T21:50:49.547 に答える
0

currentMatrix.slice を使用してマトリックスのクローンを作成するのは疑わしいようです。それは浅いクローンであり、変異しているので、問題を引き起こす可能性があります.

そのパワーポイントのプレゼンテーションでは、正規化ステップの一部として丸めについて言及されていないため、round の使用も少し奇妙に見えます。

于 2012-01-06T23:43:58.940 に答える