在Haskell中,ridge regression可以表示为:
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)
但是,此操作非常耗费内存。这是一个简约的示例,在我的机器上需要超过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 ()
$ cabal exec ghc - -O2 Test.hs
$ time ./Test
./Test 190.16s用户5.22s系统106%cpu 3:03.93总计
问题是增加常数 n ,至少增加到n = 4000,而RAM限制为5GB。矩阵求逆运算在理论上需要的最小空间是多少?如何在空间方面优化此操作?可以用更便宜的方法有效地替换岭回归吗?
答案 0 :(得分:1)
简单高斯 - 乔丹消除只占用空间来存储输入和输出矩阵以及恒定的辅助空间。如果我正确阅读,您需要反转的矩阵oA
为n
x n
,这样就不会有问题。
存储输入矩阵a
完全控制了你的内存使用量,输入矩阵n = 4000
使用至少1500 * 120000 * 8 = 1.34 GB。 a[i]=Integer.parseInt(s[i]);
为4000 * 120000 * 8 = 3.58 GB,超出您预算空间的一半。我不知道你正在使用什么矩阵库或它如何存储它的矩阵,但如果它们在Haskell堆上,那么GC效应可以很容易地在空间使用中考虑另一个因子2。
答案 1 :(得分:1)
嗯,你可以获得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是n×m,A * A&#39;是n x n。
所以一种算法就是
计算C = A * A&#39; + mu2
做一个胆怯的C分解,即找到上三角形U,这样U&#39; * U = C
计算向量y = A&#39; * b
计算向量z = A * y
在z
中解决U&#39; * u = z for u对于z
中的v求解U * v = z计算w = A&#39; * z
计算x =(y - w)/ mu2。