生成k折交叉验证集F#
Generate k fold Cross validation sets F#
我想知道如何生成k折交叉验证集。我想知道是否可以通过折叠等高阶函数来避免递归。 从矩阵或数组中随机生成 3 个子集(相同大小)。有什么想法吗??
val matrizz : Matrix<float> =
DenseMatrix 6x5-Double
5,1 3,5 1,4 0,2 -1
4,9 3 1,4 0,2 -1
4,7 3,2 1,3 0,2 -1
4,6 3,1 1,5 0,2 -1
5 3,6 1,4 0,2 -1
5,4 3,9 1,7 0,4 -1
我同意你的问题含糊不清,所以我在这里做出我最好的猜测。这不是一个特别好的或有效的解决方案,但它可能会让您入门。
let chooseBut (array: 'a[][]) index =
[| for i=0 to (array.Length - 1) do if i <> index then yield array.[i] |]
|> Array.concat
let kfoldSplit k (input: 'a[]) =
let partition = Array.chunkBySize (input.Length/k) input
[ 0..k-1 ]
|> List.map (chooseBut partition)
[| 1..50 |]
|> kfoldSplit 5
请注意,对于 [|1..52|]
.
这样的输入数组,这可能不会产生预期的结果
编辑: 没有列表理解的版本
let chooseBut array index =
array
|> Array.mapi (fun i v -> if i <> index then (Some v) else None)
|> Array.choose id
|> Array.concat
此外,要获得随机分区,您可以这样做
let partition = Array.chunkBySize 5 [| 1..50 |]
partition.SelectPermutation()
我将使用 F# 列表(数字列表的列表),因为这比矩阵更容易入手。所以,假设我们有一个样本输入和一个随机数生成器:
let rnd = System.Random()
let inputMatrix =
[ [ 1.1; 1.2; 1.3 ]
[ 2.1; 2.2; 2.3 ]
[ 3.1; 3.2; 3.3 ] ]
我认为生成具有随机顺序行的列表的最简单方法是使用 List.map
遍历行,为每一行生成随机数,然后对行进行排序:
inputMatrix
|> List.map (fun row -> rnd.Next(), row)
|> List.sortBy fst
|> List.map snd
这非常实用,而且我认为它的可读性很强,所以它是我的首选解决方案。它需要对列表进行几次迭代,所以你不能只用一个 fold
来做到这一点。
您可以使用 fold
解决此问题,但您需要不同的策略。您可以遍历行并将当前行随机插入到您在遍历行时构建的新矩阵中:
([], inputMatrix)
||> List.fold (fun matrix row ->
let split = rnd.Next(matrix.Length + 1)
List.take split matrix @ [row] @ List.skip split matrix)
这从一个空矩阵 []
开始,inputMatrix
上的每一步都会选择一个拆分点并在那里插入新行。这部分效率很低,但它是使用 fold
.
的解决方案
请注意,这都是很好的函数式处理方式,但如果您关心高效的矩阵运算,最好为这样的基本函数执行一些较低级别的命令式编码 - 除非您正在使用的库已经提供了。
我想知道如何生成k折交叉验证集。我想知道是否可以通过折叠等高阶函数来避免递归。 从矩阵或数组中随机生成 3 个子集(相同大小)。有什么想法吗??
val matrizz : Matrix<float> =
DenseMatrix 6x5-Double
5,1 3,5 1,4 0,2 -1
4,9 3 1,4 0,2 -1
4,7 3,2 1,3 0,2 -1
4,6 3,1 1,5 0,2 -1
5 3,6 1,4 0,2 -1
5,4 3,9 1,7 0,4 -1
我同意你的问题含糊不清,所以我在这里做出我最好的猜测。这不是一个特别好的或有效的解决方案,但它可能会让您入门。
let chooseBut (array: 'a[][]) index =
[| for i=0 to (array.Length - 1) do if i <> index then yield array.[i] |]
|> Array.concat
let kfoldSplit k (input: 'a[]) =
let partition = Array.chunkBySize (input.Length/k) input
[ 0..k-1 ]
|> List.map (chooseBut partition)
[| 1..50 |]
|> kfoldSplit 5
请注意,对于 [|1..52|]
.
编辑: 没有列表理解的版本
let chooseBut array index =
array
|> Array.mapi (fun i v -> if i <> index then (Some v) else None)
|> Array.choose id
|> Array.concat
此外,要获得随机分区,您可以这样做
let partition = Array.chunkBySize 5 [| 1..50 |]
partition.SelectPermutation()
我将使用 F# 列表(数字列表的列表),因为这比矩阵更容易入手。所以,假设我们有一个样本输入和一个随机数生成器:
let rnd = System.Random()
let inputMatrix =
[ [ 1.1; 1.2; 1.3 ]
[ 2.1; 2.2; 2.3 ]
[ 3.1; 3.2; 3.3 ] ]
我认为生成具有随机顺序行的列表的最简单方法是使用 List.map
遍历行,为每一行生成随机数,然后对行进行排序:
inputMatrix
|> List.map (fun row -> rnd.Next(), row)
|> List.sortBy fst
|> List.map snd
这非常实用,而且我认为它的可读性很强,所以它是我的首选解决方案。它需要对列表进行几次迭代,所以你不能只用一个 fold
来做到这一点。
您可以使用 fold
解决此问题,但您需要不同的策略。您可以遍历行并将当前行随机插入到您在遍历行时构建的新矩阵中:
([], inputMatrix)
||> List.fold (fun matrix row ->
let split = rnd.Next(matrix.Length + 1)
List.take split matrix @ [row] @ List.skip split matrix)
这从一个空矩阵 []
开始,inputMatrix
上的每一步都会选择一个拆分点并在那里插入新行。这部分效率很低,但它是使用 fold
.
请注意,这都是很好的函数式处理方式,但如果您关心高效的矩阵运算,最好为这样的基本函数执行一些较低级别的命令式编码 - 除非您正在使用的库已经提供了。