MathNumerics.LinearAlgebra Matrix.mapRows 维度问题

MathNumerics.LinearAlgebra Matrix.mapRows dimensionality issues

所以我已经验证了我正在尝试做的事情的起始版本有效,但是由于某种原因,当把它放入 Matrix.map 高阶函数时它崩溃了。

这是失败的函数:

let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
    let m = trainingData.RowCount
    let theta' = theta.ToRowMatrix()
    trainingData     
    |> Matrix.mapRows(fun a r -> (theta' * r) - y.[a] )

这里有一些示例测试

设置:

let tData = matrix [[1.0; 2.0]
                    [1.0; 3.0]
                    [1.0; 3.0]
                    [1.0; 4.0]]   
let yVals = vector [5.0; 6.0; 7.0; 11.0]      
let theta = vector [1.0; 0.2]  

测试基本操作的原始功能(theta 转置 * 矢量 - 实际)

let theta' = theta.ToRowMatrix()
(theta.ToRowMatrix() * tData.[0, 0 .. 1]) - yVals.[0]

实际功能测试:

tData |> SumSquares theta yVals

这是一个 copy/paste 的实际错误。它读起来好像它有问题我将一个较大的向量映射到一个较小的向量。

参数名称:目标

at MathNet.Numerics.LinearAlgebra.Storage.VectorStorage1.CopyToRow(MatrixStorage1 target, Int32 rowIndex, ExistingData existingData)
at FSI_0061.SumSquares(Vector1 theta, Vector1 y, Matrix`1 trainingData) in C:\projects\deleteme\ASPNet5Test\ConsoleApplication1\ConsoleApplication1\MachineLearning.fsx:line 23
at .$FSI_0084.main@() in C:\projects\deleteme\ASPNet5Test\ConsoleApplication1\ConsoleApplication1\MachineLearning.fsx:line 39
Stopped due to error

既然您知道行数,就可以映射到它。可以说这并不漂亮:

let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
    let m = trainingData.RowCount
    let theta' = theta.ToRowMatrix()                                             
    [0..m-1] |> List.map (fun i -> (((theta' * trainingData.[i,0..1]) |> Seq.exactlyOne) - yVals.[i] ))

编辑:
我的猜测是 mapRows 希望所有的东西都是相同的形状,而你的输出向量是不同的。所以如果你想坚持使用 Vector 类型,这将只枚举索引行:

tData.EnumerateRowsIndexed() |> Seq.map (fun (i,r) -> (theta' * r) - yVals.[i])
你也可以使用 Matrix.toRowSeqi 如果你喜欢通过管道传递它,并取回矩阵:

tData 
    |> Matrix.toRowSeqi 
    |> Seq.map (fun (i,x) -> (theta' * x) - yVals.[i]) 
    |> DenseMatrix.ofRowSeq

我找到了一种更简单的方法来执行此操作。我必须感谢 s952163 让我走上了一条好的道路,但这种方法更加优化:

let square (x:Vector<float>) = x * x 
let subtract (x:Vector<float>) (y:Vector<float>) = y - x
let divideBy (x:float) (y:float) = y / x

let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
    let m = trainingData.RowCount |> float
    (trainingData * theta)
    |> subtract y
    |> square
    |> divideBy m