gpt4 book ai didi

f# - F# 中的惰性相关矩阵计算

转载 作者:行者123 更新时间:2023-12-01 07:57:02 24 4
gpt4 key购买 nike

我必须计算 5GB 的 csv 文件中包含的向量的相关矩阵。每行包含每个随机变量的一个观察值。为此,我编写了以下内容:

let getCorrMatrix data =   

let getMatrixInfo nCol (count,crossProd:float array array,sumVector:float array,sqVector:float array) (newLine:float array) =

for i in 0..(nCol-1) do
sumVector.[i]<-sumVector.[i]+newLine.[i]
sqVector.[i]<-sqVector.[i]+(newLine.[i]*newLine.[i])
for j in (i+1)..(nCol-1) do
crossProd.[i].[j-(i+1)]<-crossProd.[i].[j-(i+1)]+newLine.[i]*newLine.[j]

let newCount = count+1
//(newCount,newMatrix,newSumVector,newSqVector)
(newCount,crossProd,sumVector,sqVector)

//Get number of columns
let nCol = data|>Seq.head|>Seq.length

//Initialize objects for the fold
let matrixStart = Array.init nCol (fun i -> Array.create (nCol-i-1) 0.0)
let sumVector = Array.init nCol (fun _ -> 0.0)
let sqVector = Array.init nCol (fun _ -> 0.0)

let init = (0,matrixStart,sumVector,sqVector)

//Run the fold and obtain all the elements to build te correlation matrix
let (count,crossProd,sum,sq) =
data
|>PSeq.fold(getMatrixInfo nCol) init

//Compute averages standard deviations, and finally correlations
let averages = sum|>Array.map(fun s ->s/(float count))
let std = Array.zip3 sum sq averages
|> Array.map(fun (elemSum,elemSq,av)-> let temp = elemSq-2.0*av*elemSum+float(count)*av*av
sqrt (temp/(float count-1.0)))

//Map allteh elements to correlation
let rec getCorr i j =
if i=j then
1.0
elif i<j then
(crossProd.[i].[j-(i+1)]-averages.[i]*sum.[j]-averages.[j]*sum.[i]+(float count*averages.[i]*averages.[j]) )/((float count-1.0)*std.[i]*std.[j])
else
getCorr j i

let corrMatrix = Array2D.init nCol nCol (fun i j -> getCorr i j)

corrMatrix

我已经针对 R 计算对其进行了测试并且它匹配。由于我打算一次又一次地使用它,如果您有一些反馈(或发现错误),我们将不胜感激。 (请注意,我发布此内容是因为认为它也可能对其他人有用)。

谢谢

最佳答案

主要问题在下面的代码中:

    //Update crossproduct
let newMatrix =
[| for i in 0..(nCol-1) do
yield [| for j in (i+1)..(nCol-1) -> crossProd.[i].[j-(i+1)]+newLine.[i]*newLine.[j] |]
|]

您为数据 中的每一行创建一个新矩阵。这是低效的,你只能使用一个这样的矩阵。

有一些小的 F# 需要注意:

  1. 使用 sqrt 作为 System.Math.Sqrt 的快捷方式。

  2. 避免使用列表理解来初始化简单数组。例如。你的代码

    let matrixStart = [| for i in 0..(nCol-1) do
    yield [| for j in (i+1)..(nCol-1) -> 0.0 |]
    |]

    可以使用标准程序编写:

    let matrixStart = Array.init nCol (fun i -> Array.create (nCol-i-1) 0.0)

    另一个例子,对于

    let corrMatrix = 
    [| for i in 0..(nCol-1) do
    yield [| for j in 0..(nCol-1) -> getCorr i j |]
    |]

    您可以使用 float [,] 而不是使用 float [][] 并编写

    let corrMatrix = Array2D.init nCol nCol (fun i j -> getCorr i j)

关于f# - F# 中的惰性相关矩阵计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3842214/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com