Haskell 岭回归需要多少空间?

Haskell 岭回归需要多少空间?,haskell,machine-learning,linear-algebra,hmatrix,Haskell,Machine Learning,Linear Algebra,Hmatrix,在Haskell中,可以表示为: import Numeric.LinearAlgebra createReadout :: Matrix Double → Matrix Double → Matrix Double createReadout a b = oA <\> oB where μ = 1e-4 oA = (a <> (tr a)) + (μ * (ident $ rows a)) oB = a <> (tr b) 导入

在Haskell中,可以表示为:

import Numeric.LinearAlgebra 

createReadout :: Matrix Double → Matrix Double → Matrix Double
createReadout a b = oA <\> oB
  where
   μ = 1e-4

   oA = (a <> (tr a)) + (μ * (ident $ rows a))
   oB = a <> (tr b)
导入Numeric.linearlgebra
createReadout::矩阵双精度→ 矩阵双精度→ 矩阵双精度
创建a b=oA oB
哪里
μ=1e-4
oA=(a(tr a))+(μ*(标识$a行))
oB=a(tr b)
但是,此操作的内存非常昂贵。下面是一个最简单的示例,在我的机器上需要超过2GB的内存,执行起来需要3分钟

import Numeric.LinearAlgebra
import System.Random

createReadout :: Matrix Double -> Matrix Double -> Matrix Double
createReadout a b = oA <\> oB
  where
    mu = 1e-4
    oA = (a <> (tr a)) + (mu * (ident $ rows a))
    oB = a <> (tr b)

teacher :: [Int] -> Int -> Int -> Matrix Double
teacher labelsList cols' correctRow = fromBlocks $ f <$> labelsList
  where ones = konst 1.0 (1, cols')
        zeros = konst 0.0 (1, cols')
        rows' = length labelsList
        f i | i == correctRow = [ones]
            | otherwise = [zeros]

glue :: Element t => [Matrix t] -> Matrix t
glue xs = fromBlocks [xs]

main :: IO ()
main = do

  let n = 1500  -- <- The constant to be increased
      m = 10000
      cols' = 12

  g <- newStdGen

  -- Stub data
  let labels = take m . map (`mod` 10) . randoms $ g :: [Int]
      a = (n >< (cols' * m)) $ take (cols' * m * n) $ randoms g :: Matrix Double
      teachers = zipWith (teacher [0..9]) (repeat cols') labels
      b = glue teachers

  print $ maxElement $ createReadout a b
  return ()
导入Numeric.linearlgebra
导入系统。随机
createReadout::矩阵双精度->矩阵双精度->矩阵双精度
创建a b=oA oB
哪里
mu=1e-4
oA=(a(tr a))+(mu*(标识$a行))
oB=a(tr b)
老师::[Int]->Int->Int->Matrix Double
教师标签列表cols'correctRow=fromBlocks$f标签列表
其中1=konst 1.0(1,cols')
零=konst 0.0(1,cols')
行'=长度标签列表
f i | i==正确行=[个]
|否则=[零]
glue::元素t=>[矩阵t]->矩阵t
胶水xs=fromBlocks[xs]
main::IO()
main=do

设n=1500--简单高斯-乔丹消去法只需要存储输入和输出矩阵的空间加上常数辅助空间。如果我读对了,你需要反转的矩阵是
n
x
n
,所以这不是问题


存储输入矩阵
a
(至少使用1500*120000*8=1.34 GB)完全控制了内存的使用<代码>n=4000
将是4000*120000*8=3.58 GB,这超过了您空间预算的一半。我不知道您使用的是什么矩阵库,也不知道它是如何存储矩阵的,但是如果它们在Haskell堆上,那么GC效果可以很容易地解释空间使用的另一个因素2。

简单的Gauss-Jordan消元法只需要存储输入和输出矩阵的空间以及常量辅助空间。如果我读对了,你需要反转的矩阵是
n
x
n
,所以这不是问题


存储输入矩阵
a
(至少使用1500*120000*8=1.34 GB)完全控制了内存的使用<代码>n=4000将是4000*120000*8=3.58 GB,这超过了您空间预算的一半。我不知道您使用的是什么矩阵库,也不知道它是如何存储矩阵的,但如果它们在Haskell堆上,那么GC效果可以很容易地解释空间使用的另一个因素2。

您可以使用3*m+nxn空间,但我不确定这在数值上有多稳定

基础是身份

inv( inv(Q) + A'*A)) = Q - Q*A'*R*A*Q
where R = inv( I + A*Q*A')
如果A是你的A矩阵

Q = inv( mu*I*mu*I) = I/(mu*mu)
那么岭回归的解决方案是

inv( inv(Q) + A'*A)) * A'*b
再多学一点代数

inv( inv(Q) + A'*A)) = (I - A'*inv( (mu2 + A*A'))*A)/mu2
where mu2 = mu*m
注意,因为A是nxm,所以A*A'是nxn

所以一个算法是

计算C=A*A'+mu2

对C进行cholesky分解(求上三角U,使U'*U=C)

计算向量y=A'*b

计算向量z=A*y

在z中求U'*U=z

求解z中v的U*v=z

计算w=A'*z


计算x=(y-w)/mu2。

你可以使用3*m+nxn空间,但我不确定这在数值上有多稳定

基础是身份

inv( inv(Q) + A'*A)) = Q - Q*A'*R*A*Q
where R = inv( I + A*Q*A')
如果A是你的A矩阵

Q = inv( mu*I*mu*I) = I/(mu*mu)
那么岭回归的解决方案是

inv( inv(Q) + A'*A)) * A'*b
再多学一点代数

inv( inv(Q) + A'*A)) = (I - A'*inv( (mu2 + A*A'))*A)/mu2
where mu2 = mu*m
注意,因为A是nxm,所以A*A'是nxn

所以一个算法是

计算C=A*A'+mu2

对C进行cholesky分解(求上三角U,使U'*U=C)

计算向量y=A'*b

计算向量z=A*y

在z中求U'*U=z

求解z中v的U*v=z

计算w=A'*z


计算x=(y-w)/mu2。

我读对了吗,
a
是1500 x 120000矩阵吗?完全正确。它可能更大,是矩阵吗?这可以为您节省大量的空间和时间(但您可能需要像这样的专用算法)。不幸的是,它们不是稀疏的。我读对了吗,
a
是1500 x 120000矩阵?完全正确。它可能更大,是矩阵吗?这可以为你节省大量的空间和时间(但你可能需要一个专门的算法,比如)。不幸的是,它们不是稀疏的。里德,谢谢你的回答。事实上,我必须提到我正在使用hmatrix库,它与C例程(BLAS和LAPACK)接口。矩阵然后存储为Data.Vector.Storable array.Reid,谢谢你的回答。事实上,我必须提到我正在使用hmatrix库,它与C例程(BLAS和LAPACK)接口。矩阵然后存储为Data.Vector.Storable数组。