Robust PCA Action Set
Detecting Anomalies
This section contains PROC CAS code.
Note: Input data must be accessible in your CAS session, either as a CAS table or as a transient-scope table. A CAS table has a two-level name: the first level is your CAS engine libref, and the second level is the table name. You refer to this table in the CAS procedure by specifying only the second level. For more information about two-level names, see Chapter 2, Shared Concepts (SAS Visual Data Mining and Machine Learning: Procedures). A transient-scope table is called directly from the action and exists in memory for the duration of the action. For more information about accessing data, see SAS Viya: System Programming Guide. For more information about PROC CAS and programming in CASL, see SAS Cloud Analytic Services: CASL Programmer’s Guide and SAS Cloud Analytic Services: CASL Reference.
This example shows how you can use the robustPca action to detect anomalies. The input data table mycas.rpcaData2 has 50 observations and three variables: Index, X, and Y. Index is simply an observation number, X is a randomly generated number between 0 and 1, and Y is X plus a random term between -1 and 1. This data table also has three outliers for variable Y in observations 7, 20, and 33.
The following DATA step creates the rpcaData2 data set:
data rpcaData2;
input index X Y;
datalines;
1 0.522 0.510
2 0.642 0.583
3 0.628 0.543
4 0.826 0.875
5 0.101 0.031
6 0.310 0.311
7 0.447 4.421
8 0.419 0.481
9 0.861 0.874
10 0.418 0.334
11 0.929 1.020
12 0.946 0.946
13 0.548 0.567
14 0.626 0.643
15 0.616 0.581
16 0.684 0.622
17 0.438 0.450
18 0.264 0.174
19 0.705 0.607
20 0.932 3.024
21 0.866 0.836
22 0.145 0.138
23 0.225 0.133
24 0.577 0.515
25 0.815 0.832
26 0.678 0.706
27 0.844 0.892
28 0.996 1.033
29 0.695 0.676
30 0.988 0.930
31 0.684 0.614
32 0.582 0.660
33 0.048 2.004
34 0.230 0.276
35 0.928 0.885
36 0.509 0.539
37 0.187 0.224
38 0.339 0.405
39 0.726 0.782
40 0.459 0.463
41 0.938 1.038
42 0.435 0.451
43 0.520 0.535
44 0.051 0.146
45 0.951 1.017
46 0.173 0.199
47 0.164 0.119
48 0.773 0.834
49 0.428 0.336
50 0.864 0.918
;
run;
You can load rpcaData into your CAS session by naming your CAS engine libref in the first statement of the following DATA step:
data mycas.rpcaData2;
set rpcaData2;
run;
This statement assumes your CAS engine libref is named mycas, but you can substitute any appropriately defined CAS engine libref.
The following statements run the robustPca action.
proc cas;
ods trace on;
loadactionset "robustPca";
action robustPca /
table={name="rpcaData2"}
id={"index"}
lambdaWeight=3.5
outmat={sparseMat={name="sparsemat2" replace=True}}
;
run;
If you look at the output data table mycas.sparsemat2 in the CAS engine library, you can see that the only nonzero values in the sparse matrix are related to the outlier values that were introduced for variable Y (in observations 7, 20, and 33).
Alternatively, you can set the anomalyDetection parameter to True in the robustPca action and then use the astore action to detect the outliers, as in the following statements:
proc cas;
ods trace on;
loadactionset "robustPca";
action robustPca /
table={name="rpcaData2"}
id={"index"}
scale=True
center=True
saveState={name="store" replace=True}
anomalyDetection=True
;
run;
proc cas;
loadactionset "astore";
action score /
table={name="rpcaData2"}
options={{name="RPCA_PROJECTION_TYPE",value=2}}
rstore={name="store"}
casout={name="scored",replace=True}
;
run;
If you look at the mycas.scored data table in the CAS engine library, you can see that the same outliers (observations 7, 20, and 33) are detected. The two methods that are described in this section are not exactly the same, but with proper settings they both detect outliers.
Detecting Anomalies
This section contains Lua code for the analysis in the CASL version of this example, which contains details about the results.
Note: In order to run this code, the data that are described in the CASL version need to be accessible to the CAS server. One way to do this is to convert the rpcaData2 data to the comma-separated-value (CSV) file rpcaData2.csv and then use the following code to load the CSV file into CAS:
s:loadtable{casLib="casuser", path="rpcaData2.csv"}
For more information about coding in Lua, see Getting Started with SAS Viya for Lua and SAS Viya: System Programming Guide.
s:loadactionset{actionset="robustPca"}
s:robustPca{
table={name="rpcaData2"},
id={"index"},
lambdaWeight=3.5,
outmat={sparseMat={name="sparsemat2", replace=True}}
}
s:robustPca{
table={name="rpcaData2"},
id={"index"},
scale=True,
center=True,
saveState={name="store", replace=True},
anomalyDetection=True
}
s:loadactionset{actionset="astore"}
s:score{
table={name="rpcaData2"},
options={{name="RPCA_PROJECTION_TYPE",value=2}},
rstore={name="store"},
out={name="scored",replace=True}
}
s:fetch{table={name="scored"}, to=50}
Detecting Anomalies
This section contains Python code for the analysis in the CASL version of this example, which contains details about the results.
Note: In order to run this code, the data that are described in the CASL version need to be accessible to the CAS server. One way to do this is to convert the rpcaData2 data to the comma-separated-value (CSV) file rpcaData2.csv and then use the following code to load the CSV file into CAS:
s.upload_file('rpcaData2.csv')
For more information about coding in Python, see Getting Started with SAS Viya for Python and SAS Viya: System Programming Guide.
s.loadactionset(actionset="robustPca")
s.robustPca(
table={"name" : "rpcaData2"},
id={"index"},
lambdaWeight=3.5,
outmat={"sparseMat":{"name":"sparsemat2", "replace":True}}
)
s.fetch(table={"name":"sparsemat2"}, to=50)
s.robustPca(
table={"name" : "rpcaData2"},
id={"index"},
scale=True,
center=True,
saveState={"name":"store", "replace":True},
anomalyDetection=True
)
s.loadactionset(actionset="astore")
s.score(
table={"name" : "rpcaData2"},
options=[{"name":"RPCA_PROJECTION_TYPE","value":2}],
rstore={"name":"store"},
out={"name":"scored","replace":True}
)
s.fetch(table={"name":"scored"}, to=50)
Detecting Anomalies
This section contains R code for the analysis in the CASL version of these examples, which contains details about the results.
Note: In order to run this code, the data that are described in the CASL version need to be loaded into CAS. One way to do this is to convert the rpcaData2 data set to the comma-separated-value (CSV) file rpcaData2.csv then use the following code to load the CSV file into CAS:
data <- cas.read.csv(s,
"rpcaData2.csv",
header= TRUE,
casOut=list(name="rpcaData2",replace=TRUE))
loadActionSet(s,'robustPca')
rs <- cas.robustPca.robustpca(s,
table =list(name="rpcaData2"),
id=list("index"),
lambdaweight=3.5,
outmat=list(sparseMat =list(name="sparsemat2",replace=TRUE)))
cas.table.fetch(s, table = list(name = 'sparsemat2'), to = 50)
rs <- cas.robustPca.robustpca(s,
table =list(name="rpcaData2"),
id=list("index"),
scale=TRUE,
center=TRUE,
saveState=list(name="store",replace=TRUE),
anomalyDetection=TRUE)
loadActionSet(s,'astore')
rs <- cas.astore.score(s,
table =list(name="rpcaData2"),
options=list(list(name="RPCA_PROJECTION_TYPE",value=2)),
rstore=list(name="store"),
out=list(name="scored",replace=TRUE))
cas.table.fetch(s, table = list(name = 'scored'), to = 50)