I'm trying to project new data rows into a prior SVD space. ie. I want to solve for u
in x = udv'
which I think is u = xvd(-1)
(e.g. from here https://blog.statsbot.co/singular-value-decomposition-tutorial-52c695315254 ).
From the output below I guess I must be wrong. Can some kind person help please?
x <- scale(iris[-5])
# svd
eg <- svd(x)
u <- eg$u
d <- diag(eg$d)
v <- eg$v
# check x = udv'
head(x)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width
#> [1,] -0.8976739 1.01560199 -1.335752 -1.311052
#> [2,] -1.1392005 -0.13153881 -1.335752 -1.311052
#> [3,] -1.3807271 0.32731751 -1.392399 -1.311052
#> [4,] -1.5014904 0.09788935 -1.279104 -1.311052
#> [5,] -1.0184372 1.24503015 -1.335752 -1.311052
#> [6,] -0.5353840 1.93331463 -1.165809 -1.048667
head(u %*% d %*% t(v))
#> [,1] [,2] [,3] [,4]
#> [1,] -0.8976739 1.01560199 -1.335752 -1.311052
#> [2,] -1.1392005 -0.13153881 -1.335752 -1.311052
#> [3,] -1.3807271 0.32731751 -1.392399 -1.311052
#> [4,] -1.5014904 0.09788935 -1.279104 -1.311052
#> [5,] -1.0184372 1.24503015 -1.335752 -1.311052
#> [6,] -0.5353840 1.93331463 -1.165809 -1.048667
# project onto u = xvd(-1)
head(x %*% v %*% d^-1)
#> [,1] [,2] [,3] [,4]
#> [1,] NaN NaN NaN NaN
#> [2,] Inf NaN NaN NaN
#> [3,] NaN NaN NaN NaN
#> [4,] NaN -Inf NaN NaN
#> [5,] -Inf -Inf -Inf -Inf
#> [6,] NaN NaN NaN -Inf
Created on 2019-04-01 by the reprex package (v0.2.1)
You're trying to find the inverse of the matrix d
by d^(-1)
, which is wrong.
If you write A ^ k
in R, where A
is a matrix and k
is a scalar, R will try to compute it elementwise, which obviously you don't want. Since d
is diagonal, all non-diagonal entries will lead to Inf
and hence you're facing this error.
To find the inverse, use the solve function. See below:
X <- scale(x = iris[-5])
svd_X <- svd(x = X)
U <- svd_X$u
D <- diag(x = svd_X$d)
V <- svd_X$v
all.equal(target = X,
current = (U %*% D %*% t(x = V)),
check.attributes = FALSE)
#> [1] TRUE
all.equal(target = U,
current = (X %*% V %*% solve(a = D)))
#> [1] TRUE
Created on 2019-04-01 by the reprex package (v0.2.1)
Hope this helps.
1 Like
Sorry, got it now. The matrix inverse is given by solve(d)
, not d^-1
.
# project onto u = xvd(-1)
head(u)
#> [,1] [,2] [,3] [,4]
#> [1,] -0.10823953 -0.04099580 0.027218646 0.013710648
#> [2,] -0.09945776 0.05757315 0.050003401 0.058435855
#> [3,] -0.11299630 0.02920003 -0.009420891 0.016098333
#> [4,] -0.10989710 0.05101939 -0.019457133 -0.037416661
#> [5,] -0.11422046 -0.05524180 -0.003354363 -0.020379051
#> [6,] -0.09920300 -0.12718049 -0.005747892 0.003748828
head(x %*% v %*% solve(d))
#> [,1] [,2] [,3] [,4]
#> [1,] -0.10823953 -0.04099580 0.027218646 0.013710648
#> [2,] -0.09945776 0.05757315 0.050003401 0.058435855
#> [3,] -0.11299630 0.02920003 -0.009420891 0.016098333
#> [4,] -0.10989710 0.05101939 -0.019457133 -0.037416661
#> [5,] -0.11422046 -0.05524180 -0.003354363 -0.020379051
#> [6,] -0.09920300 -0.12718049 -0.005747892 0.003748828
Created on 2019-04-01 by the reprex package (v0.2.1)
Yes thanks very much. Just posted that when your answer came in.
system
Closed
April 8, 2019, 3:28pm
5
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed. If you have a query related to it or one of the replies, start a new topic and refer back with a link.