MWPCA Procedure

Example 24.1 Anomaly Detection of Parking Lot Floodlights

This example applies the MWPCA procedure to a data set that consists of energy consumption every five minutes for six floodlight circuits in a parking lot at SAS headquarters in Cary, North Carolina, over a span of about three months. Each of these light circuits has a sensor that measures the energy consumption of the lights.

The following code includes the DATA step that generates the data table mylib.ParkingLotLights.

        data mylib.parkinglotlights;
input time e49548 e49549 e49551 e49552 e49553 e49554;
datalines;

   ... more lines ...   

Output 24.1.1 displays the energy consumption of each of these light circuits in the first 16 days. The energy consumption throughout the day is zero because the lights are off during the day. In this figure, you can see that the orange lights (e49549) have a dip in energy consumption for a couple of hours on the sixth night, indicating that one of the lights controlled by the circuit was not functioning properly. Also, you can see that during day 15, all lights have a spike in energy consumption during the day. A storm occurred on that day, creating enough darkness to trigger the lights to come on briefly. There was no malfunction in the lights.

Output 24.1.1: Energy Consumption (Kilowatts) of Floodlights, First 16 Days

bulbsenergyconsumption


Output 24.1.2 displays the energy consumption of each light circuit in the last 13 days. In this figure, you can see that the green lights (e49552) start to have many dips in energy consumption in the last 11 nights; several of the lights on this circuit are starting to fail. Also, toward the end, the red lights (e49553) have dips in energy consumption, especially on the second-last night, indicating that problems are occurring in this circuit as well.

Output 24.1.2: Energy Consumption (Kilowatts) of Floodlights, Last 13 Days

bulbsenergyconsumption2


The following code uses PROC MWPCA to illustrate how moving-windows principal component analysis can help determine when the lights begin to fail:

proc MWPCA data=mylib.parkinglotlights windowsize = 240 stepsize = 1;
       id time;
       input e49548 e49549 e49551 e49552 e49553 e49554;
       output out=mylib.output standardpc pcangles;
run;

Output 24.1.3 displays the first principal component that is obtained from the output table that results from applying PROC MWPCA to the mylib.ParkingLotLights data table over the sliding windows of data. In this figure, you can observe that the first principal component that is associated with the orange lights starts deviating from the first principal components that are associated with the other lights around the same time that the dips were observed on the sixth night for these lights. Also, toward the end of the data, the first principal component that is associated with the green lights starts deviating from the first principal components that are associated with the other lights again around the same time that the dips for this light were observed toward the end. The same is true of the dips in the energy consumption of the red lights toward the end of the sample. Note that during the storm, when all lights came on unexpectedly (on day 15), the first principal components that are related to the lights do not deviate from each other, and thus there is no signal of failure in this instance. This result is correct: the unexpected behavior of the lights was not caused by a light malfunction. Output 24.1.3 shows how PROC MWPCA detects malfunctions in each light circuit by tracking the first principal components of their energy consumption.

proc sgplot data=mylib.output;
   series x=window_id y=e49554/legendlabel = "e49554"
    lineattrs=(color=blue thickness = 1) ;
   series x=window_id y=e49553/legendlabel = "e49553"
    lineattrs=(color=red thickness = 1) ;
   series x=window_id y=e49552/legendlabel = "e49552"
    lineattrs=(color=CX00CC00 thickness = 1) ;
   series x=window_id y=e49551/legendlabel = "e49551"
    lineattrs=(color=purple thickness = 1) ;
   series x=window_id y=e49549/legendlabel = "e49549"
    lineattrs=(color=orange thickness = 1) ;
   series x=window_id y=e49548/legendlabel = "e49548"
    lineattrs=(color=CX00DDAA thickness = 1) ;
   yaxis label="First Principal Component";
   xaxis label="Window ID";
run;

Output 24.1.3: First Principal Component over Sliding Windows

First Principal Component over Sliding Windows


Output 24.1.4 plots the angle change of the first principal component between consecutive windows. When the observation that enters a window contains the outliers, its value of angle change is relatively higher than that of previous windows. By checking the value of the angle change in Output 24.1.4, you can easily detect when a light circuit is not functioning properly.

proc sgplot data =mylib.output;
   series x= window_id y= angle_chg/legendlabel = "angle change"
    lineattrs = (thickness = 1);
   yaxis label="Angle";
   xaxis label="Window ID";
run;

Output 24.1.4: Angle Change of the First Principal Component over Sliding Windows

Angle Change of the First Principal Component over Sliding Windows


Last updated: August 06, 2026