我是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
结果为每个inputVector迭代newMatrix
计算newMatrix
?
编辑:添加了伪造算法
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算法this本书。
答案 0 :(得分:5)
如果你刚刚开始学习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
功能。你能提供更多细节吗?通常,在使用列表时,您不需要使用索引,并且您似乎正在执行需要访问特定索引处的元素的操作。可能有更好的方法来写这个....
答案 1 :(得分: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.scanlet 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