Линейное программирование против Итеративно взвешенное время выполнения наименьших квадратов

#linear-regression #linear-programming #least-squares #nonlinear-optimization #cvxopt

#линейная регрессия #линейное программирование #наименьшие квадраты #нелинейная оптимизация #cvxopt

Вопрос:

Я пытался запустить регрессию наименьшего абсолютного отклонения (регрессия L1). Я сделал это, разработав линейную программу и решив с помощью CVXOPT (на Python). Количество функций (включая константу) составляло 13, а количество выборок составляло ~ 100 тыс. Для завершения работы потребовалось много часов. Затем я понял, что могу работать statsmodels' QuantReg с. q=0.5 это заняло несколько секунд. Я читал, что они используют итеративно взвешенные наименьшие квадраты (IRL). Является ли IRLS быстрее, чем линейное программирование для этой цели, или, может быть, другая формулировка задачи линейной оптимизации и использование лучшего решателя, такого как Gurobi, существенно сократит время выполнения линейной программы? Причина, по которой я спрашиваю, заключается в том, что я хочу попробовать функцию потерь, которая включает суммирование двух разных абсолютных функций с разными весами. Я считаю, что я могу использовать IRLS и для этой проблемы, но я не уверен, и мне больше нравится линейное программирование.

Формулировка, которую я использовал для линейной программы, была следующей:

введите описание изображения здесь

Результирующий код для CVXOPT выглядел следующим образом:

 def l1_fit(x,y):
'''

:param x: feature matrix
:param y: label vector
:return: LAD coefficients

The problem I construct is:
    min c'*(v|A)
    subject to:
        (-I|x)*(v|A)<=y
        (-I|-x)*(v|A)<=-y
'''
c = matrix(np.concatenate((np.ones(y.shape[0]),np.zeros(x.shape[1]))).astype(float).tolist(),
           (y.shape[0] x.shape[1],1),'d')
G = scipy_sparse_to_spmatrix(np.transpose(hstack((vstack((-identity(y.shape[0]),np.transpose(x))),
                          vstack((-identity(y.shape[0]),np.transpose(-x))))).astype(float)))
h = matrix(np.concatenate((y,-y)).astype(float).tolist(),(2*y.shape[0],1),'d')
sol = lp(c, G, h)
return sol[1][y.shape[0]:]
  

Комментарии:

1. Существуют разные формулировки LP для задачи регрессии L1. Для больших задач может быть полезно не дублировать матрицу X. См. Ссылку

2. Кенкер использовал алгоритм внутренней точки. Разработчики квантильной регрессии в Julia сообщили об ускорении по сравнению с версией IRLS, последняя изначально была переводом версии statsmodels. github.com/pkofod/QuantileRegressions.jl

3. Версия statsmodels, похоже, неплохо справляется с приближением к оптимальному, но иногда возникают проблемы с окончательным результатом.

4. 1 для statsmodels QuantReg. Да, время решения LP может сильно различаться, см. Эту Матрицу сравнения LP из двух десятков тестовых примеров на scicomp.stack.