In this post, you'll learn how to use arrays to store information and use it in rules.
Let's review how user variables work. User variables allow storing information from successive transactions for use in complex rules that track behavior.
For example, you might create a single user variable that tracks total incorrect PIN entry attempts. Each declined attempt could iterate the variable for each particular account. You could then create a rule that blocks an account if the number of incorrect PIN entries exceeds 5.
As another example, let's say you would like to compare the ZIP code from a customer's previous transaction to the ZIP code of an incoming transaction. You could store the most recent transaction ZIP code in a user variable, and compare it against the ZIP code for incoming transactions. User variables can store other information about transactions, like the IP address, amount, and more.
But what if you want to track a pattern of behavior using several related fields? For example, what if you wanted to store the ZIP code for the most recent 5 transactions, not just the most recent one. As another example, what if you wanted to track some information about an account, like the average daily balance, for each day in the last week.
In SAS Fraud Management, you can track this information and use it in rules with arrays.
In SAS Fraud Management, arrays are created just like user variables. In fact - arrays are simply a group of user variables that SAS Fraud Management treats as an array.
In our previous ZIP code example, we might create a user variable called transaction zip to store the most recent transaction ZIP code.
The SAS Fraud Management user interface shows creating a user variable with one replication.
Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.
If I wanted to instead create a 5 item array to store information about my 5 most recent transactions, I can select to create duplicates of the transaction zip variable.
The SAS Fraud Management user interface shows creating a user variable with 5 replications.
This creates 5 of the txn_zip variable that I can use later in my rule code. We'll also create several other variables, each with duplications, to track information about the most recent 5 transactions of this type. I add two more variables to store the transaction amount and date time.
Next, we will create the rule that will populate, update, and use this array.
How you update and reference user variables depends on your environment and preference. You might have a variable rule that updates a user variable array, while another rule that runs subsequently references the value. Or, you might use one authorization rule to simultaneously populate and update an array, and use it to make a decision.
In this example, we will create a variable rule to populate the arrays, then an authorization rule to make a decision using the array.
First, my variable rule will declare the array. This tells SAS Fraud Management to treat each set of user variables as an array in the rule code.
/*Declare arrays storing txn information */
%DeclareArray(&rule.txn_amt , _A_TXN_AMT_1 - _A_TXN_AMT_5);
%DeclareArray(&rule.txn_zips , _A_TXN_ZIP_1 - _A_TXN_ZIP_5);
%DeclareArray(&rule.txn_dttm , _A_TXN_DTTM_1 - _A_TXN_DTTM_5);
In this example, the 5 positions of each array will represent the 5 most recent transactions and what their corresponding value is. These are examples of event-based arrays, because the rule will add data to this array and shift its contents each time a relevant event occurs. Therefore, the rule code should shift the arrays, and then store the corresponding information from the incoming transaction in the first position:
%ShiftHistoryArray(&rule.txn_amt &rule.txn_zips &rule.dttm);
/*if the transaction amount is not 0, add the transaction's information to the first position in the array */
if TCA_CLIENT_AMT > 0
then do;
%set( _A_TXN_DTTM_1 ) = dhms( rqo_tran_date,0,0,rqo_tran_time );
%set( _A_TXN_AMT_1 ) = TCA_CLIENT_AMT;
%set( _A_TXN_DTTM_1 ) = HCT_TERM_POST_CODE;
end
Next, we can create an authorization rule to utilize the historical transaction data stored in these arrays. You could use this information in a number of different ways depending on the complexity of the rule you want to create. For instance, you might create a rule that uses a current transaction's ZIP code, amount, and date time with this historical data so that a particular combination will trigger an alert. For now, let's start with a basic example that will only utilize the transaction amount data.
I create an authorization rule that calculates the mean of the last 5 transaction amounts. Then, if the most recent transaction amount is more than two times that mean, the rule will decline the transaction.
if 2* mean( _A_TXN_AMT_1,_A_TXN_AMT_2, _A_TXN_AMT_3,
_A_TXN_AMT_4, _A_TXN_AMT_5 ) < TCA_CLIENT_AMT
then do;
%Action_Decline();
end;
Let's go through an example of how this table could be populated and used as a result of these rules. First, let's discuss what happens the first time this rule runs. On the first transaction that comes in for a particular customer, the array is empty. This means that the initial value of the transaction is stored in the first position of the array, and the remaining positions are empty.
The current values in this array are:
user variable | value |
_A_TXN_AMT_1 | $50.81 |
_A_TXN_AMT_2 | . |
_A_TXN_AMT_3 | . |
_A_TXN_AMT_4 | . |
_A_TXN_AMT_5 | . |
Note that if the initial values are zero rather than missing, then the logic of this rule may not work as expected, since the mean of any number and four zeroes will always be significantly lower than the initial transaction amount. This emphasizes the important of priming variables, or ensuring that the rule logic checks whether the variables have been primed or are otherwise functioning as intended.
In this case, the mean of all the transactions in the array is 50.81 - equal to the first and only value in the array. This rule will not fire, because 50.81 is not greater than 2(50.81) or 101.61.
The next transaction that comes in for a particular account has a value of $74.25. This is stored in the first position, and the remaining items in the array are shifted out.
user variable | value |
_A_TXN_AMT_1 | $74.25 |
_A_TXN_AMT_2 | $50.81 |
_A_TXN_AMT_3 | . |
_A_TXN_AMT_4 | . |
_A_TXN_AMT_5 | . |
This time, the authorization rule will check whether 2 times the mean of 74.25 and 50.81 is less than 74.25. Double the mean is greater than the current transaction amount, so once again, the rule will not fire.
The next event has a significantly higher transaction amount, resulting in the following table and expression:
user variable | value |
_A_TXN_AMT_1 | $825.75 |
_A_TXN_AMT_2 | $74.25 |
_A_TXN_AMT_3 | $50.81 |
_A_TXN_AMT_4 | . |
_A_TXN_AMT_5 | . |
The rule code calculates the expression, and since 633.87 < 825.75, the rule will fire, and the transaction will be declined.
This has been a simple introduction into event-based arrays in SAS Fraud Management. The second type of array is a date-based array. In this case, the positions in the array do not represent distinct events, but rather distinct time buckets for tracking activity. We'll explore an example using this type of array in a subsequent post.
For more information on SAS Fraud Management, see the user guides and other articles from the SAS Community.
Find more articles from SAS Global Enablement and Learning here.
The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.