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(MatrixStorage
1 target, Int32 rowIndex, ExistingData existingData)
at FSI_0061.SumSquares(Vector1 theta, Vector
1 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
所以我已经验证了我正在尝试做的事情的起始版本有效,但是由于某种原因,当把它放入 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.VectorStorage
1.CopyToRow(MatrixStorage
1 target, Int32 rowIndex, ExistingData existingData)
at FSI_0061.SumSquares(Vector1 theta, Vector
1 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