-
Notifications
You must be signed in to change notification settings - Fork 5
/
pca.go
135 lines (111 loc) · 4.24 KB
/
pca.go
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
124
125
126
127
128
129
130
131
132
133
134
135
package mlpack
/*
#cgo CFLAGS: -I./capi -Wall
#cgo LDFLAGS: -L. -lmlpack_go_pca
#include <capi/pca.h>
#include <stdlib.h>
*/
import "C"
import "gonum.org/v1/gonum/mat"
type PcaOptionalParam struct {
DecompositionMethod string
NewDimensionality int
Scale bool
VarToRetain float64
Verbose bool
}
func PcaOptions() *PcaOptionalParam {
return &PcaOptionalParam{
DecompositionMethod: "exact",
NewDimensionality: 0,
Scale: false,
VarToRetain: 0,
Verbose: false,
}
}
/*
This program performs principal components analysis on the given dataset using
the exact, randomized, randomized block Krylov, or QUIC SVD method. It will
transform the data onto its principal components, optionally performing
dimensionality reduction by ignoring the principal components with the
smallest eigenvalues.
Use the "Input" parameter to specify the dataset to perform PCA on. A desired
new dimensionality can be specified with the "NewDimensionality" parameter, or
the desired variance to retain can be specified with the "VarToRetain"
parameter. If desired, the dataset can be scaled before running PCA with the
"Scale" parameter.
Multiple different decomposition techniques can be used. The method to use
can be specified with the "DecompositionMethod" parameter, and it may take the
values 'exact', 'randomized', or 'quic'.
For example, to reduce the dimensionality of the matrix data to 5 dimensions
using randomized SVD for the decomposition, storing the output matrix to
data_mod, the following command can be used:
// Initialize optional parameters for Pca().
param := mlpack.PcaOptions()
param.NewDimensionality = 5
param.DecompositionMethod = "randomized"
data_mod := mlpack.Pca(data, param)
Input parameters:
- input (mat.Dense): Input dataset to perform PCA on.
- DecompositionMethod (string): Method used for the principal
components analysis: 'exact', 'randomized', 'randomized-block-krylov',
'quic'. Default value 'exact'.
- NewDimensionality (int): Desired dimensionality of output dataset. If
0, no dimensionality reduction is performed. Default value 0.
- Scale (bool): If set, the data will be scaled before running PCA,
such that the variance of each feature is 1.
- VarToRetain (float64): Amount of variance to retain; should be
between 0 and 1. If 1, all variance is retained. Overrides -d.
Default value 0.
- Verbose (bool): Display informational messages and the full list of
parameters and timers at the end of execution.
Output parameters:
- output (mat.Dense): Matrix to save modified dataset to.
*/
func Pca(input *mat.Dense, param *PcaOptionalParam) (*mat.Dense) {
params := getParams("pca")
timers := getTimers()
disableBacktrace()
disableVerbose()
// Detect if the parameter was passed; set if so.
gonumToArmaMat(params, "input", input, false)
setPassed(params, "input")
// Detect if the parameter was passed; set if so.
if param.DecompositionMethod != "exact" {
setParamString(params, "decomposition_method", param.DecompositionMethod)
setPassed(params, "decomposition_method")
}
// Detect if the parameter was passed; set if so.
if param.NewDimensionality != 0 {
setParamInt(params, "new_dimensionality", param.NewDimensionality)
setPassed(params, "new_dimensionality")
}
// Detect if the parameter was passed; set if so.
if param.Scale != false {
setParamBool(params, "scale", param.Scale)
setPassed(params, "scale")
}
// Detect if the parameter was passed; set if so.
if param.VarToRetain != 0 {
setParamDouble(params, "var_to_retain", param.VarToRetain)
setPassed(params, "var_to_retain")
}
// Detect if the parameter was passed; set if so.
if param.Verbose != false {
setParamBool(params, "verbose", param.Verbose)
setPassed(params, "verbose")
enableVerbose()
}
// Mark all output options as passed.
setPassed(params, "output")
// Call the mlpack program.
C.mlpackPca(params.mem, timers.mem)
// Initialize result variable and get output.
var outputPtr mlpackArma
output := outputPtr.armaToGonumMat(params, "output")
// Clean memory.
cleanParams(params)
cleanTimers(timers)
// Return output(s).
return output
}