Using PyStan for constrianed optimization?


#1

I am interested in potentially using PyStan for an optimization problem I am dealing with.

I have a large amount of historical sales data for six different categories of products. Each product has a size attribute. I want to optimize the size of each product, subject to the constraints that product 1 must be smaller than product 2, which must be smaller than product 3, etc.

I could use a Gaussian process for estimating the relationship between sales & size within each product category (or even just a simple regression), and then find the maximum of the resulting equation. However that wouldn’t leave my results subject to the constraints.

Is it possible to model the relationship between product category, size, and sales, subject to the constraints, and get the maximum for each in PyStan? Or am I barking up the wrong tree?


#2

In Stan, you are going to want to use the positive_ordered type in the parameters block to enforce those constraints. But you are going to have to figure out exactly how to incorporate that into your optimization problem.


#3

That’s super helpful, thank you.

Perhaps I can start with a basic model (assuming two product categories for keeping example small):

sales = B0 + B1ProductCategory1 + B2ProductCategory2 + B3Size + B4ProductCat1xSize + B5ProductCat2xSize

and then using the positive_ordered type to set a constraint that B4 < B5.


#4

So, something along these lines:

pooled_data = """
data {
  int<lower=0> N;
  vector[N] sales;
  vector[N] dummy_cat1;
  vector[N] dummy_cat2;
  vector[N] size;
  vector[N] cat1size;
  vector[N] cat2size;
}
"""

pooled_parameters = """
parameters {
  real beta1;
  real beta2;
  real beta3;
  real beta4;
  real beta5;
  real beta6;

  real<lower=0> sigma;
} 
"""

pooled_model = """
model {
  sales ~ normal(beta1 + beta2*dummy_cat1 + beta3*dummy_cat2 + beta4*size + beta5*cat1size + beta6*cat2size, sigma);
}
"""

I did some preliminary Google searching, and couldn’t find the proper method for specifying the lower and upper limit for positive_ordered. Do you know where I can find this?


#5

It just dawned on me that my model makes no sense whatsoever in answering my original question. How can I delete this thread and come back when I have it better mapped out?


#6

I think you can delete the text of your posts but not the thread. Anyway, deleting the posts or the thread is not so good because the answers would then not be helpful for other people.

A positive_ordered parameter cannot have an upper bound, although its lower bound is zero and you could then shift the whole thing. In general, an upper bound isn’t a logical requirement, so you can often get away with not having it. You could divide the positive_ordered vector by its sum and then multiply by a positive upper bound. However, it is then necessary that your prior on the elements of the original positive_ordered vector have a fixed scale.