-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmlapiDecomposition.Rd
123 lines (108 loc) · 3.97 KB
/
mlapiDecomposition.Rd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/decomposition.R
\docType{data}
\name{mlapiDecomposition}
\alias{mlapiDecomposition}
\alias{mlapiDecomposition}
\alias{mlapiDecompositionOnline}
\title{Base abstract class for all decompositions}
\format{\code{R6Class} object.}
\usage{
mlapiDecomposition
mlapiDecompositionOnline
}
\description{
Base class for all \bold{decompositions} which are methods which can decompose matrix into
2 low-dimensional matrices \code{x = f(A, B)}.
(Think of this Latent Dirichlet Allocation, Non-negative Matrix Factorization, etc).
It iherits from \link{mlapiTransformation} and additionally requires to implement \code{components} member.
Base class for all \bold{decompositions} which are methods which can decompose matrix into
2 low-dimensional matrices \code{x = f(A, B)} \bold{incrementally}.
It iherits from \link{mlapiDecomposition} and additionally requires
to implement \code{partial_fit} method which can learn \code{components} incrementally.
}
\section{Fields}{
\describe{
\item{\code{components}}{features embeddings. So if matrix is decomposed in a form \code{x = f(A, B)} where
X = n\*m, A = n\*k, B = k\*m them \code{B = components}}
\item{\code{components}}{features embeddings. So if matrix is decomposed in a form \code{x = f(A, B)} where
X = n\*m, A = n\*k, B = k\*m them \code{B = components}}
}}
\section{Methods}{
\describe{
\item{\code{$fit_transform(x, y = NULL, ...)}}{}
\item{\code{$transform(x, ...)}}{Performs transformation of the new data (after model was trained)}
}
\describe{
\item{\code{$fit_transform(x, y = NULL, ...)}}{}
\item{\code{$partial_fit(x, y = NULL, ...)}}{}
\item{\code{$transform(x, ...)}}{Performs transformation of the new data (after model was trained)}
}
}
\section{Arguments}{
\describe{
\item{x}{A matrix like object, should \bold{inherit from \code{Matrix} or \code{matrix}}.
Allowed classes should be defined in child classes.}
\item{y}{\code{NULL}. Optional taget variable. Usually this should be \code{NULL}.
There few cases when it could be used.}
\item{...}{additional parameters \bold{with default values}}
}
\describe{
\item{x}{A matrix like object, should \bold{inherit from \code{Matrix} or \code{matrix}}.
Allowed classes should be defined in child classes.}
\item{y}{\code{NULL}. Optional taget variable. Usually this should be \code{NULL}.
There few cases when it could be used.}
\item{...}{additional parameters \bold{with default values}}
}
}
\examples{
TruncatedSVD = R6::R6Class(
classname = "TruncatedSVD",
inherit = mlapi::mlapiDecomposition,
public = list(
initialize = function(rank = 10) {
private$rank = rank
super$set_internal_matrix_formats(dense = "matrix", sparse = NULL)
},
fit_transform = function(x, ...) {
x = super$check_convert_input(x)
private$n_features = ncol(x)
svd_fit = svd(x, nu = private$rank, nv = private$rank, ...)
sing_values = svd_fit$d[seq_len(private$rank)]
result = svd_fit$u \%*\% diag(x = sqrt(sing_values))
private$components_ = t(svd_fit$v \%*\% diag(x = sqrt(sing_values)))
rm(svd_fit)
rownames(result) = rownames(x)
colnames(private$components_) = colnames(x)
private$fitted = TRUE
invisible(result)
},
transform = function(x, ...) {
if (private$fitted) {
stopifnot(ncol(x) == ncol(private$components_))
lhs = tcrossprod(private$components_)
rhs = as.matrix(tcrossprod(private$components_, x))
t(solve(lhs, rhs))
}
else
stop("Fit the model first woth model$fit_transform()!")
}
),
private = list(
rank = NULL,
n_features = NULL,
fitted = NULL
)
)
set.seed(1)
model = TruncatedSVD$new(2)
x = matrix(sample(100 * 10, replace = TRUE), ncol = 10)
x_trunc = model$fit_transform(x)
dim(x_trunc)
x_trunc_2 = model$transform(x)
sum(x_trunc_2 - x_trunc)
#' check pipe-compatible S3 interface
x_trunc_2_s3 = transform(x, model)
identical(x_trunc_2, x_trunc_2_s3)
}
\keyword{datasets}