Линия регрессии чертежа, доверительный интервал и интервал прогнозирования в Python

Я новичок в регрессионной игре и надеюсь построить функционально произвольную линию нелинейной регрессии (плюс доверительные интервалы) для подмножества данных, которое удовлетворяет определенному условию (т.е. со средним репликационным значением, превышающим порог, см. ниже).

создается для независимой переменной x для 20 различных значений: x=(20-np.arange(20))**2, при этом rep_num=10 реплицируется для каждого условия. Данные показывают сильную нелинейность в x и выглядят следующим образом:

import numpy as np

mu = [.40, .38, .39, .35, .37, .33, .34, .28, .11, .24,
      .03, .07, .01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]     

data = np.zeros((20, rep_num))
for i in range(13):
    data[i] = np.clip(np.random.normal(loc=mu[i], scale=0.1, size=rep_num), 0., 1.)

Я могу сделать график рассеяния данных; репликационные средства показаны красными точками:

import matplotlib.pyplot as plt

plt.scatter(np.log10(np.tile(x[:,None], rep_num)), data, 
            facecolors='none', edgecolors='k', alpha=0.25)
plt.plot(np.log10(x), data.mean(1), 'ro', alpha=0.8)
plt.plot(np.log10(x), np.repeat(0., 20), 'k--')
plt.xlim(-0.02, np.max(np.log10(x)) + 0.02)
plt.ylim(-0.01, 0.7)

график рассеяния

Моя цель - построить линию регрессии только для тех данных, которые имеют репликацию в среднем > 0,02. Кроме того, я хотел бы добавить 95% -ный доверительный интервал (черные пунктирные линии) вокруг регрессии, а также интервал предсказания 95% (синие пунктирные линии) - в идеале интервал прогнозирования также может быть окрашен в прозрачный синий фон.

Заключительный сюжет (без синего фона внутри интервала предсказания) будет выглядеть примерно так:

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

Как мне это сделать? Мой онлайн-поиск дал очень разные частичные подходы, используя морские, скудные и статистические модели. Приложения некоторых из этих функций шаблонов, похоже, не работали вместе с существующим графиком рассеяния matplotlib.

Ответы

Ответ 1

ОК, вот выстрел в это (с полосой предсказания). Прежде всего, вы хотите выбрать применимые данные:

threshold = 0.02
reg_x = np.log10(x)[data.mean(1)>threshold]
reg_y = data.mean(1)[data.mean(1)>threshold]

Затем вы выбираете модель и выполняете подгонку. Заметьте, здесь я выбрал полином второго порядка, но в принципе вы могли бы сделать что угодно. Для подстановок я использую kapteyn, у этого есть встроенный метод доверительных запретов, хотя его было бы легко реализовать (см., Например, Delta method)

from kapteyn import kmpfit

# Set model to fit.
def model(p, x):
    a, b, c = p
    return a + b*x + c*x**2

# Perform fit.
f = kmpfit.simplefit(model, [.1, .1, .1], reg_x, reg_y)

f содержит все оценочные параметры и т.д., вы можете использовать это для построения и т.д.

x = np.linspace(0, 3, 100)
plt.plot(x, model(f.params, x), linestyle='-', color='black', marker='')

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

# Partial derivatives:
dfdp = [1., reg_x, reg_x**2]
_, ci_upper, ci_lower = f.confidence_band(reg_x, dfdp, 0.95, model)

# Plot.
plt.plot(reg_x, ci_upper, linestyle='--', color='black', marker='')
plt.plot(reg_x, ci_lower, linestyle='--', color='black', marker='')

К сожалению, в пакете нет prediction_bands() процедуры, по крайней мере, не того, о чем я знаю. Предположим, вы нашли какой-то метод для полосы прогноза, построение и подготовка выглядели бы одинаково, хотя..

p_upper, p_lower = prediction_band(*args, **kwargs)
plt.fill_between(reg_x, p_upper, p_lower, facecolor='blue', alpha=0.2, linestyle='')

Надеюсь, это поможет, L.