Многомерная (полиномиальная) наилучшая кривая в питоне?

Как рассчитать наиболее подходящую линию в python, а затем нанести ее на диаграмму рассеяния в matplotlib?

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

from sklearn import linear_model
clf = linear_model.LinearRegression()
x = [[t.x1,t.x2,t.x3,t.x4,t.x5] for t in self.trainingTexts]
y = [t.human_rating for t in self.trainingTexts]
clf.fit(x,y)
regress_coefs = clf.coef_
regress_intercept = clf.intercept_      

Это многомерно (для каждого случая есть много значений x). Итак, X — это список списков, а y — один список. Например:

x = [[1,2,3,4,5], [2,2,4,4,5], [2,2,4,4,1]] 
y = [1,2,3,4,5]

Но как мне это сделать с полиномиальными функциями более высокого порядка. Например, не просто линейный (x в степени M=1), а биномиальный (x в степени M=2), квадратичный (x в степени M=4) и так далее. Например, как получить наиболее подходящие кривые из следующих?

Выдержка из книги Кристофера Бишопса "Распознавание образов и машинное обучение", стр. 7:

Извлечено из статьи Кристофера Бишопса


person Zach    schedule 08.08.2012    source источник
comment
Регрессия по методу наименьших квадратов остается линейной, даже если вы подбираете полином. Пока уравнение представляет собой линейную комбинацию членов (например, полином), работает тот же алгоритм.   -  person Dietrich Epp    schedule 08.08.2012
comment
Связано: Многовариантная регрессия с использованием numpy   -  person John Lyon    schedule 08.08.2012
comment
Связано: Многомерная полиномиальная регрессия с numpy   -  person John Lyon    schedule 08.08.2012
comment
Вы хотите сгенерировать формулу для каждого набора X или сгенерировать формулу для всех?   -  person mattexx    schedule 08.08.2012


Ответы (2)


Принятый ответ на этот вопрос содержит небольшая библиотека мультиполигонки, которая будет делать именно то, что вам нужно, используя numpy, и вы можете вставить результат в график, как я изложил ниже.

Вы просто передадите свои массивы точек x и y и степень (порядок) подгонки, которую вы требуете, в multipolyfit. Это возвращает коэффициенты, которые вы затем можете использовать для построения графика с использованием поливала numpy.

Примечание. Приведенный ниже код был изменен для выполнения многомерной подгонки, но изображение графика было частью более раннего немногомерного ответа.

import numpy
import matplotlib.pyplot as plt
import multipolyfit as mpf

data = [[1,1],[4,3],[8,3],[11,4],[10,7],[15,11],[16,12]]
x, y = zip(*data)
plt.plot(x, y, 'kx')

stacked_x = numpy.array([x,x+1,x-1])
coeffs = mpf(stacked_x, y, deg) 
x2 = numpy.arange(min(x)-1, max(x)+1, .01) #use more points for a smoother plot
y2 = numpy.polyval(coeffs, x2) #Evaluates the polynomial for each x2 value
plt.plot(x2, y2, label="deg=3")

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


Примечание. Это было частью ответа ранее, но по-прежнему актуально, если у вас нет многомерных данных. Вместо coeffs = mpf(... используйте coeffs = numpy.polyfit(x,y,3)

Для немногомерных наборов данных проще всего это сделать с помощью polyfit:

numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)

Полиномиальная аппроксимация методом наименьших квадратов.

Подгоните многочлен p(x) = p[0] * x**deg + ... + p[deg] степени deg к точкам (x, y). Возвращает вектор коэффициентов p, минимизирующий квадрат ошибки.

person John Lyon    schedule 08.08.2012
comment
Как это применимо к многомерной регрессии? Поскольку у меня есть несколько переменных x (по 5 для каждого случая), у меня есть двумерный массив (список списков) для x. Мой x выглядит так: [[1,2,3,4,5],[2,3,4,5,6],..]. Вводя это в ваш ответ, я получаю TypeError: expected 1D vector for x. - person Zach; 08.08.2012
comment
Будут ли эти отдельные наборы данных анализироваться отдельно или вместе? Как выглядят значения y? - person John Lyon; 08.08.2012
comment
Я отредактировал свой исходный вопрос, чтобы ответить на ваш комментарий. Это единый набор данных. Я хочу регрессировать несколько значений (функции, независимые переменные), например [x1,x2,x3,x4], с одним значением y, ДЛЯ КАЖДОГО СЛУЧАЯ. Каждый список x соответствует соответствующему значению y. Это многомерная регрессия. - person Zach; 08.08.2012
comment
Ой. Тогда это совсем другой вопрос, чем исходная формулировка. - person John Lyon; 08.08.2012
comment
@Zach Попробуйте скрипт, указанный в принятом ответе здесь: stackoverflow.com/questions/2799491/ - person John Lyon; 08.08.2012
comment
@jozzas Откуда взялся модуль multipolyfit? Попытка импортировать его приводит к ошибке импорта: ImportError: No module named multipolyfit.multipolyfit ... - person Rolf Bartstra; 26.03.2013
comment
@RolfBartstra в связанном вопросе и ответе (первая ссылка в этом ответе) пользователь написал для этого небольшую служебную функцию: github.com/mrocklin/multipolyfit - person John Lyon; 27.03.2013
comment
Я только что заметил этот вопрос. Я обновил организацию репозитория, добавил разрешительную лицензию с открытым исходным кодом и опубликовал его на PyPi. Вы должны иметь возможность easy_install multipolyfit . - person MRocklin; 01.05.2013
comment
Я получаю TypeError: можно только объединить кортеж (не int) с ошибкой кортежа для строки stacked_x = numpy.array([x,x+1,x-1]). - person user200340; 08.09.2016

Немного вырвано из контекста, потому что результирующая функция не полиномиальная, но все же, возможно, интересная. Одной из основных проблем полиномиальной аппроксимации является феномен Рунге: чем выше степень, тем драматичнее будут возникать колебания. Это не просто построено, но оно вернется, чтобы укусить вас.

В качестве исправления я недавно создал smoothfit. Он решает соответствующую задачу наименьших квадратов и дает хорошие результаты, например:

import numpy as np
import matplotlib.pyplot as plt
import smoothfit

x = [1, 4, 8, 11, 10, 15, 16]
y = [1, 3, 3, 4, 7, 11, 12]
a = 0.0
b = 17.0
plt.plot(x, y, 'kx')

lmbda = 3.0  # controls the smoothness
n = 100
u =  smoothfit.fit1d(x, y, a, b, n, lmbda)

x = np.linspace(a, b, n)
vals = [u(xx) for xx in x]
plt.plot(x, vals, "-")
plt.show()

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

person Nico Schlömer    schedule 26.03.2021