如何洗牌;DenseMatrix“;在F#

如何洗牌;DenseMatrix“;在F#,matrix,f#,math.net,Matrix,F#,Math.net,在Matlab中,我们可以编写以下代码来洗牌矩阵: data = data(:, randperm(size(data,2))); 下面是我用Math.NET写的内容: let csvfile = @"../UFLDL-tutorial-F#/housing.csv" let housingAsLines = File.ReadAllLines(csvfile) |> Array.map (fun t -> t.Split(',')

在Matlab中,我们可以编写以下代码来洗牌矩阵:

data = data(:, randperm(size(data,2)));
下面是我用Math.NET写的内容:

let csvfile = @"../UFLDL-tutorial-F#/housing.csv"
let housingAsLines = 
    File.ReadAllLines(csvfile)
        |> Array.map (fun t -> t.Split(',')
                            |> Array.map (fun t -> float t))
let housingAsMatrix= DenseMatrix.OfRowArrays housingAsLines
let housingAsMatrixT = housingAsMatrix.Transpose()

let v1 = DenseVector.Create(housingAsMatrixT.ColumnCount,1.0)
housingAsMatrixT.InsertRow(0,v1)

// How to shuffle a "DenseMatrix" in F#
在Matlab中模拟矩阵运算,使用F#切片语法和基于零的索引。但是,它不起作用

housingAsMatrixT.[*,0]
我在vscode中得到了错误信息

未定义字段、构造函数或成员“GetSlice”


对于神经网络,我必须对矩阵数组进行洗牌,并使用以下代码。注意,基本数据结构是一个数组([]),数组中的每个项都是一个矩阵。这不是洗牌矩阵,而是洗牌数组。它应该让你知道如何解决你的问题

type Random() = 
    static member Shuffle (a : 'a[]) =
        let rand = new System.Random()
        let swap (a: _[]) x y =
            let tmp = a.[x]
            a.[x] <- a.[y]
            a.[y] <- tmp
        Array.iteri (fun i _ -> swap a i (rand.Next(i, Array.length a))) a
附录

下面是将
byte[]
转换为双精度
DenseMatrix
的代码

let byteArrayToMatrix (bytes : byte[]) : Matrix<double> =
    let (x : Vector<byte>) = Vector<byte>.Build.DenseOfArray bytes
    let (y : Vector<double>) = x.Map(fun x -> double x)
    let (z : Matrix<double>) = Matrix<double>.Build.DenseOfRowVectors y
    z
let byteArrayToMatrix(字节:字节[]):矩阵=
let(x:Vector)=Vector.Build.denseof数组字节
让(y:Vector)=x.Map(乐趣x->double x)
设(z:Matrix)=Matrix.Build.denseofrow向量y
Z

你实际上有两个问题,1)如何分割矩阵,2)如何洗牌矩阵的列

事实上,你在评论中的链接确实提供了解决方案。但是,您可能正在使用旧版本,或者您可能没有正确引用
F#
扩展:

#r @"..\packages\MathNet.Numerics.3.13.1\lib\net40\MathNet.Numerics.dll"
#r @"..\packages\MathNet.Numerics.FSharp.3.13.1\lib\net40\MathNet.Numerics.FSharp.dll"

open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.Distributions
open System

//let m = DenseMatrix.randomStandard<float> 5 5
let m = DenseMatrix.random<float> 5 5 (ContinuousUniform(0., 1.))
let m' = m.[*,0]
m'
//val it : Vector<float> =
//seq [0.4710989485; 0.2220238937; 0.566367266; 0.2356496324; ...]

由于原始矩阵的第一列移到了新矩阵的第二列,因此这两列应该相等。

@GuyCoder和@s952163,感谢您的帮助。我实现了一个快速而肮脏的版本。这还不够好,但很有效

请随意评论。多谢各位

#load "../packages/FsLab.1.0.2/FsLab.fsx"
open System
open System.IO
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.Distributions

// implementation of the Fisher-Yates shuffle by Mathias
// http://www.clear-lines.com/blog/post/Optimizing-some-old-F-code.aspx
let swap fst snd i =
   if i = fst then snd else
   if i = snd then fst else
   i
let shuffle items (rng: Random) =
   let rec shuffleTo items upTo =
      match upTo with
      | 0 -> items
      | _ ->
         let fst = rng.Next(upTo)
         let shuffled = List.permute (swap fst (upTo - 1)) items
         shuffleTo shuffled (upTo - 1)
   let length = List.length items
   shuffleTo items length

let csvfile = @"/eUSB/sync/fsharp/UFLDL-tutorial-F#/housing.csv"
let housingAsLines = 
    File.ReadAllLines(csvfile)
        |> Array.map (fun t -> t.Split(',')
                            |> Array.map (fun t -> float t))
let housingAsMatrix= DenseMatrix.OfRowArrays housingAsLines
let housingAsMatrixTmp = housingAsMatrix.Transpose()
let v1 = DenseVector.Create(housingAsMatrixTmp.ColumnCount,1.0)
let housingAsMatrixT = housingAsMatrixTmp.InsertRow(0,v1)

let m = housingAsMatrixT.RowCount - 1
let listOfArray = [0..m]
let random = new Random()
let shuffled = shuffle listOfArray random

let z = [for i in shuffled -> (housingAsMatrixT.[i, *])]
let final = DenseMatrix.OfRowVectors z

在数据成为DenseMatrix之后,是否有任何理由必须对其进行洗牌?您能否将数据加载到数组中,例如[],然后洗牌数据,然后使用该数组构建DenseMatrix?为了防止机器学习算法拟合过度和拟合不足,我必须这样做。“我必须这样做”我认为您的意思是,您必须为每次运行的培训课程洗牌数据。可以这样理解,一旦数据进入矩阵,就必须对其进行洗牌,而不是在之前。也许可以使用?每个输入的原始数据是向量还是矩阵?我一直认为数据是一个矩阵,就像一个数字的像素表示一样,但是如果它只是一个向量,那么将
矩阵数组
更改为
向量数组
。谢谢。顺便问一下,如何在DenseMatrix中提取整列/整行?我只给出了一个快速的回答,因为我知道,就F#标记向神经网络提问会得到很少的回答,而且我们中有工作和测试代码的人更少。虽然我能理解你想要学习,但我自己也做过,学习MathNet Numerics Dense Matrix的最好建议是参考这两页。对于可用的方法和一些介绍文档,我学习使用DenseMatrix的方法是编写测试用例并使用函数。此外,我还将工作中的Python代码从转换为F#,因此在实现什么样的数据结构方面,我要做的猜测工作更少。我甚至举了一个例子,我使用了链表而不是数组,因为您总是以顺序的方式在数据中移动,然后从头开始。没有随机性,因此不需要数组。但是没有使用它,因为代码通常是用数组完成的,速度没有提高;DenseMatrix提供了可用的方法、矩阵和向量。根据“”,切片语法可以编写更像Matlab的东西。@NelsonMok当我将原始数据加载到数组中,然后将它们转换为DensMatrix时,我广泛使用了Matrix,直到今天Matrix已经PermuteColumns/PermuteRows
let idx = Combinatorics.GeneratePermutation 5
idx
//val it : int [] = [|2; 0; 1; 4; 3|]
let m2 = idx |> Seq.map (fun i -> m.Column(i)) |> DenseMatrix.ofColumnSeq
m2.Column(1) = m.Column(0)
//val it : bool = true
#load "../packages/FsLab.1.0.2/FsLab.fsx"
open System
open System.IO
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.Distributions

// implementation of the Fisher-Yates shuffle by Mathias
// http://www.clear-lines.com/blog/post/Optimizing-some-old-F-code.aspx
let swap fst snd i =
   if i = fst then snd else
   if i = snd then fst else
   i
let shuffle items (rng: Random) =
   let rec shuffleTo items upTo =
      match upTo with
      | 0 -> items
      | _ ->
         let fst = rng.Next(upTo)
         let shuffled = List.permute (swap fst (upTo - 1)) items
         shuffleTo shuffled (upTo - 1)
   let length = List.length items
   shuffleTo items length

let csvfile = @"/eUSB/sync/fsharp/UFLDL-tutorial-F#/housing.csv"
let housingAsLines = 
    File.ReadAllLines(csvfile)
        |> Array.map (fun t -> t.Split(',')
                            |> Array.map (fun t -> float t))
let housingAsMatrix= DenseMatrix.OfRowArrays housingAsLines
let housingAsMatrixTmp = housingAsMatrix.Transpose()
let v1 = DenseVector.Create(housingAsMatrixTmp.ColumnCount,1.0)
let housingAsMatrixT = housingAsMatrixTmp.InsertRow(0,v1)

let m = housingAsMatrixT.RowCount - 1
let listOfArray = [0..m]
let random = new Random()
let shuffled = shuffle listOfArray random

let z = [for i in shuffled -> (housingAsMatrixT.[i, *])]
let final = DenseMatrix.OfRowVectors z