Ограниченная линейная регрессия в Python

У меня есть классическая линейная задача регрессии в форме:

y = X b

где y — это вектор отклика, X — это матрица входных переменных, а b — вектор параметров соответствия, которые я ищу.

Python предоставляет b = numpy.linalg.lstsq( X , y ) для решения задач этой формы.

Однако, когда я использую это, я получаю либо очень большие, либо очень маленькие значения для компонентов b.

Я хотел бы выполнить ту же подгонку, но ограничить значения b между 0 и 255.

Похоже, что scipy.optimize.fmin_slsqp() - это вариант, но я нашел его чрезвычайно медленным для интересующего меня размера проблемы (X - это что-то вроде 3375 by 1500 и, надеюсь, даже больше).

  1. Существуют ли какие-либо другие варианты Python для выполнения ограниченных подгонок методом наименьших квадратов?
  2. Или существуют процедуры Python для выполнения регрессии Лассо или регрессии гребня или какого-либо другого метода регрессии, который штрафует большие значения коэффициента b?

person ulmangt    schedule 14.04.2012    source источник
comment
sklearn LASSO: google.com /   -  person anon01    schedule 04.09.2020


Ответы (5)


Последние версии scipy включают решатель:

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.lsq_linear.html#scipy.optimize.lsq_linear

person tillsten    schedule 14.04.2012
comment
Красиво, на первый взгляд звучит как то, что мне нужно. Возможность присваивать веса строкам матрицы входных переменных X на самом деле также может быть очень полезной для меня (у меня есть чувство надежности различных точек данных, что может позволить мне воспользоваться этим преимуществом). Обязательно попробую, спасибо! - person ulmangt; 14.04.2012
comment
Это не очень хорошо проверено, надеюсь, что это сработает для вас. Код — это чистый python, и его должно быть легко протестировать. - person tillsten; 14.04.2012
comment
scipy.opimize.nnls тоже хороший совет. Простого ограничения неотрицательными значениями может быть достаточно. Решения numpy.linalg.lstsq, казалось, уравновешивали огромные положительные значения b столь же огромными отрицательными значениями b. - person ulmangt; 14.04.2012

Вы упомянули, что считаете регрессию Лассо или регрессию гребня приемлемой. Эти и многие другие линейные модели с ограничениями доступны в пакете scikit-learn. Ознакомьтесь с разделом об обобщенных линейных моделях.

Обычно ограничение коэффициентов включает в себя какой-то параметр регуляризации (C или альфа) — некоторые модели (те, которые заканчиваются на CV) могут использовать перекрестную проверку для автоматической установки этих параметров. Вы также можете дополнительно ограничить модели, чтобы они использовали только положительные коэффициенты — например, для этого есть опция в модели Лассо.

person conradlee    schedule 30.05.2012

scipy-optimize-leastsq-with-bound-constraints на SO дает наименьшие квадраты, который является scipy наименьшим квадратом + связанные ограничения, такие как 0 ‹= x_i ‹= 255.
(Scipy наименьший квадрат оборачивает MINPACK, одну из нескольких реализаций широко используемого алгоритм Левенберга-Марквардта, также известный как демпфированный метод наименьших квадратов.
Существуют различные способы реализации границ; я думаю, что метод наименьших квадратов_границы является самым простым.)

person denis    schedule 15.04.2012

Как говорит @conradlee, вы можете найти реализации Lasso и Ridge Regression в пакете scikit-learn. Эти регрессоры служат вашей цели, если вы просто хотите, чтобы ваши параметры подгонки были небольшими или положительными.

Однако, если вы хотите наложить любой другой диапазон в качестве границы для подходящих параметров, вы можете создать свой собственный ограниченный регрессор с тем же пакетом. См. ответ Дэвида Дейла на этот вопрос для примера.

person Bremsstrahlung    schedule 20.08.2019

Недавно я подготовил несколько уроков по линейной регрессии в Python. Вот один из вариантов (Gekko), включающий ограничения на коэффициенты.

# Constrained Multiple Linear Regression
import numpy as np
nd = 100 # number of data sets
nc = 5   # number of inputs
x = np.random.rand(nd,nc)
y = np.random.rand(nd)

from gekko import GEKKO
m = GEKKO(remote=False); m.options.IMODE=2
c  = m.Array(m.FV,nc+1)
for ci in c:
    ci.STATUS=1
    ci.LOWER = -10
    ci.UPPER =  10
xd = m.Array(m.Param,nc)
for i in range(nc):
    xd[i].value = x[:,i]
yd = m.Param(y); yp = m.Var()
s =  m.sum([c[i]*xd[i] for i in range(nc)])
m.Equation(yp==s+c[-1])
m.Minimize((yd-yp)**2)
m.solve(disp=True)
a = [c[i].value[0] for i in range(nc+1)]
print('Solve time: ' + str(m.options.SOLVETIME))
print('Coefficients: ' + str(a))

Он использует нелинейный решатель IPOPT для решения задачи, которая лучше, чем решатель scipy.optimize.minimize. В Python существуют и другие методы оптимизации с ограничениями, которые обсуждаются в Есть ли высококачественный решатель нелинейного программирования для Python?.

person John Hedengren    schedule 04.09.2020