Haskell 岭回归需要多少空间?
在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) 导入
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
xn
,所以这不是问题
存储输入矩阵a
(至少使用1500*120000*8=1.34 GB)完全控制了内存的使用<代码>n=4000
将是4000*120000*8=3.58 GB,这超过了您空间预算的一半。我不知道您使用的是什么矩阵库,也不知道它是如何存储矩阵的,但是如果它们在Haskell堆上,那么GC效果可以很容易地解释空间使用的另一个因素2。简单的Gauss-Jordan消元法只需要存储输入和输出矩阵的空间以及常量辅助空间。如果我读对了,你需要反转的矩阵是n
xn
,所以这不是问题
存储输入矩阵
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数组。