2011-07-27 8 views
0

私はF#を初めて使いました。学習するために、クラスタリングアルゴリズムを実装するのは楽しいと思いました。 私は反復処理が必要なリストの入力リストを持っています。これらの入力ベクトルのそれぞれに対して、重みを更新し、リストのリスト(重み行列)を返す関数を適用する必要があります。私はその部分をnewMatrix関数で行うことができます。問題は、次の反復で更新されたウェイト行列を使用する必要があり、これを行う方法が失われていることです。ここに重要な部分がありますが、簡潔にするために残された機能がいくつかあります。リストを反復処理してfuncitonの結果を次の繰り返しに渡すには

let inputList = [[1; 1; 0; 0]; [0; 0; 0; 1]; [1; 0; 0; 0]; [0; 0; 1; 1;]] 
let weights = [[.2; .6; .5; .9]; [.8; .4; .7; .3]] 
let newMatrix xi matrix = 
    List.map2(fun w wi -> 
     if wi = (yiIndex xi) then (newWeights xi) 
     else w) matrix [0..matrix.Length-1] 
printfn "%A" (newMatrix inputList.Head weights) 
> > 
[[0.2; 0.6; 0.5; 0.9]; [0.92; 0.76; 0.28; 0.32]] 

だから私の質問は、私が以前newMatrix結果を用いて、各inputVectorについてnewMatrixを計算inputListを反復んか、でしょうか?

編集:追加擬似アルゴリズム:

for input vector 1 
    given weight matrix calculate new weight matrix 
    return weight matirx prime 
for input vector 2 
    given weight matrix prime calculate new weight matrix 
and so on... 
... 

脇:私はKohonen SOMアルゴリズムFOM thisブックを実装しています。

+0

@Ankur&@Tomas私はあなたに男の子を投げた質問でタイプミスがありました。私は説明の中で 'newWeights'を参照していました。私は' newMatrix'を参照していたはずです。謝罪。 – nathan

答えて

3

私はあなたがList.foldを探していると思います。 のような何か:

let inputList = [[1; 1; 0; 0]; [0; 0; 0; 1]; [1; 0; 0; 0]; [0; 0; 1; 1;]] 
let weights = [[0.2; 0.6; 0.5; 0.9]; [0.8; 0.4; 0.7; 0.3]] 
let newWeights w values = w //Fake method which returns old weight as it is 
inputList |> List.fold (newWeights) weights 

注:この場合newWeights機能が重みと入力ベクトルを取り、新しい重みに

を返すか、あなたはまた、中間の計算された重みを必要とする場合にはList.scanかもしれれる

let inputList = [[1; 1; 0; 0]; [0; 0; 0; 1]; [1; 0; 0; 0]; [0; 0; 1; 1;]] 
let weights = [[0.2; 0.6; 0.5; 0.9]; [0.8; 0.4; 0.7; 0.3]] 
let newWeights w values = w 
inputList |> List.scan (newWeights) weights 
+0

私は、私の質問をより明確にする方法を理解しようとしていますが、それは複雑です。私は中間計算重量が必要です。その中間の重みは、次の反復の入力である必要があります。 – nathan

+0

@ Nathan、Fold関数のためのもの、つまりリストの各項目(あなたの場合はリストの各ベクトル)が重みを計算し、次にこの計算された重みがリスト内の次のベクトルの重みを計算するのに使用されます。 。最終的には単一のウエイトが最終的に得られます – Ankur

+0

はい私は今理解しています – nathan

4

F#の学習を始めたばかりの方は、最初に再帰を使用して明示的に実装してみると便利です。 Ankurが指摘するように、この特定の再帰パターンはList.foldによってキャプチャされますが、実際にはList.foldの仕組みを理解することは非常に便利です。だから、明示的なバージョンは、次のようになります。

// Takes vectors to be processed and an initial list of weights. 
// The result is an adapted list of weights. 
let rec processVectors weights vectors = 
    match vectors with 
    | [] -> 
     // If 'vectors' is empty list, we're done and we just return current weights 
     weights 
    | head::tail -> 
     // We got a vector 'head' and remaining vectors 'tail' 
     // Adapt the weights using the current vector... 
     let weights2 = newweights weights head 
     // and then adapt weights using the remaining vectors (recursively) 
     processVectors weights2 tail 

これはList.foldが何をするか、本質的にですが、あなたがそうのように記述されたコード(List.fold関数は再帰的な処理を隠蔽し、見ればそれを理解する方が簡単な場合があり引数として使用されるラムダ関数は、新しい重みを計算する関数にすぎません)。

その他、私はあなたのnewMatrix機能をよく理解していません。それについての詳細を教えてください。一般的に、リストを使って作業する場合、インデックスを使う必要はなく、特定のインデックスの要素にアクセスする必要があるようです。それを書く良い方法があるかもしれません....

+0

newMatrix関数はKohonenアルゴリズムの核心であり、基本的に最小ユークリッド距離の重みに基づいて新しい重み行列を計算します。最小のベクトルが重み行列の元のベクトルを置き換えます。したがって、インデックス付けが行われます。私はもっ​​と良い方法があると確信していますが、私が言ったように、私はまだノーベルです:D – nathan

+0

これは、アルゴリズムを再帰的コンテキストに入れる方法を理解する助けになりました。ありがとう。 – nathan

関連する問題