If you want to learn about SAS Optimization and how to get the most out of it, this blog is a great place to begin. Before I get into it, I want to note that the problem solved in our example is simple, but it is good for learning about optimization. My goal is for you to learn from this blog and provide feedback on what you want to see in future posts.
To my surprise, I was able to interact with SAS technology using open-source as easily as its native language. Throughout this process, I deployed open-source and SAS environments as containers and used SAS Optimization capabilities by interacting only with Python. The next section briefly explains the components that went into the process.
Initially, I wanted to use SAS Optimization on SAS Viya, but I was not proficient enough in SAS programming. Instead, I decided to use a more familiar language, Python, and use the sasoptpy package to access SAS optimization models. I was able to create an exercise in a Jupyter notebook that used SAS Optimization to optimize a marketing strategy that results in the maximum profit.
sasoptpy uses python-swat package to communicate with SAS Viya. While python-swat gives direct access to CAS action sets, sasoptpy adds methods that are specific to SAS Optimization.
In order to build and solve SAS optimization models, sasoptpy uses Python native commands to build sas syntax and runs them in CAS engine using runOptmodel actionset.
Step 1: Connecting to CAS and instantiating sasoptpy model
This section is usually the most time-consuming part because it requires understanding of how a project can be interpreted as equations that optimization algorithms will understand. Let's learn more about our problem before defining our model parameters. Optimization algorithms take information by defining it as sets of objectives, variables and constraints.
In short, objectives are final outcomes that are usually minimized or maximized. Objectives are represented as equations that consist of variables. Variables can be referred to as resources that are being manipulated to reach optimal solution(s) for the objectives. Usually, resources are limited, and such limitations can be represented as constraint functions.
The problem is pretty simple:
- Objective is to maximize profit from these campaigns.
- Resources/Variables are profits that are associated with specific campaign types.
- Resources are limited/constrained two ways:
- Each campaign type: Credit, Deposit and Insurance can each be used 3 times only.
- Each customer can only be assigned a single campaign type.
Step 3: Define variables, objectives and constraints
Now that we have this information, let's define variables.
27 binary variables were created, representing all possible matches of customers and campaign types. Each of these variables can be equal to either 0 or 1. You might be confused as to why we did this, but wait until you see the objective function.
As confusing as it looks, the objective function is simple. We are simply multiplying binary variables to their corresponding campaign profit.
objective = 100 * variable(Credit,0) + 50 * variable(Credit, 1) + ... + 60 * variable(Insurance,7) + 75 * variable(Insurance, 8)
We are specifying the objective to be maximized using so.MAX. If a campaign='Credit' is assigned to a customer=2 then variable(Credit, 1) will become 1, which will increase objective function by 50. If we had no constraints, then all the variables would become 1.
First constraint says that we can only select one campaign per customer, one variable per row. Second constraint says that we can have up to three variables assigned for each campaign type, three variables per column.
Step 4: Solve objective and retrieve solution
With a single line of Python command, the algorithm's complex computations are solved. Although I specified my algorithm, this was not necessary. The model is capable of finding best algorithm to solve objective functions. The best value turns out to be 745 and optimized binary variables can be mapped to our data.
Variables that were assigned 1 have been highlighted with green circles to show best solution.
To make my work more customizable, I containerized Jupyter and SAS environments separately, created a bridge network for them to talk through, and used Python language from the Jupyter container to connect to SAS Viya (CAS) from the SAS environment container. By using containers, I was able to create a ready-to-use environment that I could easily deploy from any machine at any scale.
This a simple example of how you can combine SAS and open-source technologies to solve real business issues. I hope that you enjoyed my first blog. I encourage you to give feedback on what real world problems would you want to see solved in future blogs.
For more information on how to build SAS containers and use SAS Optimization: