Je dois calculer la matrice de corrélation sur les vecteurs contenus dans un fichier csv de 5 Go. Chaque ligne contient une observation pour chaque variable aléatoire. Pour ce faire, j'ai écrit ce qui suit:Calcul de matrice de corrélation paresseuse en F #
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
Je l'ai testé contre le calcul de R et il correspond. Depuis que je prévois d'utiliser encore et encore si vous avez des commentaires (ou repérer une erreur), il serait grandement apprécié. (Notez que je poste cela parce que je pensais que cela pourrait être utile aux autres aussi).
Merci
Le code de remerciements est beaucoup plus rapide! (Juste découvert votre site Web, très cool!) – jlezard
et 'fun i j -> getCorr i j' peut juste être' getCorr'. :-) –