2011-07-27 47 views
0

我是F#的新手,爲了努力學習,認爲實現聚類算法會很有趣。 我有我需要迭代的列表輸入列表。對於這些輸入向量中的每一個,我需要應用更新權重並返回列表(權重矩陣)的函數。我可以通過newMatrix函數來完成該部分。問題是,我需要在下一次迭代中使用更新的權重矩陣,並且我失去了如何執行此操作。這裏是重要的部分,爲簡潔起見省略了一些功能。如何遍歷列表並將函數結果傳遞給下一個迭代

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]] 

所以我的問題是,我該如何遍歷inputList計算newMatrix使用以前newMatrix結果每個inputVector?

編輯:加入僞算法:

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,即摺疊函數的用途,即列表中的每個項目(在您的情況下,列表中的每個矢量)計算權重,然後使用此計算的權重計算列表中下一個向量的權重,依此類推。 。並在年底你將有一個最終的單件重量 – 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函數隱藏了遞歸處理,所以用作參數的lambda函數只是計算新權重的函數)。

另外,我不太瞭解你的newMatrix函數。你能提供更多的細節嗎?一般來說,在處理列表時,您不需要使用索引,而且您似乎正在做某些事情,需要訪問特定索引處的元素。有可能是一個更好的方式來寫...

+0

的newMatrix功能是Kohonen的算法的心臟,它基本上是計算基於與最小歐幾里得距離的權重一個新的權重矩陣。最小的向量替換權重矩陣中的原始向量,因此是索引。我敢肯定有一個更好的辦法,但正如我所說,我仍然是一個小白:d – nathan

+0

這幫助我瞭解如何把算法遞歸上下文。謝謝。 – nathan

相關問題