Constrained regression in Python with multiple constraints
I am still not sure which model you are running (posting a Minimal, Complete, and Verifiable example would certainly help), but the following should work for GLMs. From the docs, we have,
constraints (formula expression or tuple) – If it is a tuple, then the constraint needs to be given by two arrays (constraint_matrix, constraint_value), i.e. (R, q). Otherwise, the constraints can be given as strings or list of strings. see t_test for details.
This implies the function call should be along the following lines,
R = [[0, 0, 0, a, b, 0, 0],
[0, c, d, 0, 0, 0, 0]]
q = [0, 0]
results = model.fit_constrained((R, q))
This should work, but since we do not have your model I do not know for sure if R * params = q
, which must hold according to the documentation.
R: Force regression coefficients to add up to 1
1) CVXR We can compute the coefficients using CVXR directly by specifying the objective and constraint. We assume that D is the response, the coefficients of A and B must sum to 1, b[1] is the intercept and b[2], b[3] and b[4] are the coefficients of A, B and C respectively.
library(CVXR)
b <- Variable(4)
X <- cbind(1, as.matrix(data[-4]))
obj <- Minimize(sum((data$D - X %*% b)^2))
constraints <- list(b[2] + b[3] == 1)
problem <- Problem(obj, constraints)
soln <- solve(problem)
bval <- soln$getValue(b)
bval
## [,1]
## [1,] 1.6428605
## [2,] -0.3571428
## [3,] 1.3571428
## [4,] -0.1428588
The objective is the residual sum of squares and it equals:
soln$value
## [1] 0.07142857
2) pracma We can also use the pracma package to compute the coefficients. We specify the X matrix, response vector, the constraint matrix (in this case the vector given as the third argument is regarded as a one row matrix) and the right hand side of the constraint.
library(pracma)
lsqlincon(X, data$D, Aeq = c(0, 1, 1, 0), beq = 1) # X is from above
## [1] 1.6428571 -0.3571429 1.3571429 -0.1428571
3) limSolve This package can also solve for the coefficients of regression problems with constraints. The arguments are the same as in (2).
library(limSolve)
lsei(X, data$D, c(0, 1, 1, 0), 1)
giving:
$X
A B C
1.6428571 -0.3571429 1.3571429 -0.1428571
$residualNorm
[1] 0
$solutionNorm
[1] 0.07142857
$IsError
[1] FALSE
$type
[1] "lsei"
Check
We can double check the above by using the lm
approach in the other answer:
lm(D ~ I(A-B) + C + offset(B), data)
giving:
Call:
lm(formula = D ~ I(A - B) + C + offset(B), data = data)
Coefficients:
(Intercept) I(A - B) C
1.6429 -0.3571 -0.1429
The I(A-B)
coefficient equals the coefficient of A
in the original formulation and one minus it is the coefficient of C
. We see that all approaches do lead to the same coefficients.
Related Topics
Database Does Not Update Automatically with MySQL and Python
What Are Some Good Python Orm Solutions
Does Python Have a Module to Convert CSS Styles to Inline Styles for Emails
R Foverlaps Equivalent in Python
List Comprehension in Haskell, Python and Ruby
Programmatically Extract Data from an Excel Spreadsheet
How Does Python Manage Int and Long
Which Is the Recommended Way to Plot: Matplotlib or Pylab
Pandas Extract Number from String
Control the Size Textarea Widget Look in Django Admin
Combine a Folder of Text Files into a CSV with Each Content in a Cell
Pyobjc VS Rubycocoa for MAC Development: Which Is More Mature
In Python Can One Implement Mixin Behavior Without Using Inheritance