Как мы подгоняем сигмоидную функцию в Python? - PullRequest
0 голосов
/ 11 марта 2019

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

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

import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import beta

protocols = {}

types = {"data_v": "data_v.csv"}

for protname, fname in types.items():
    col_time,col_window = np.loadtxt(fname,delimiter=',').T
    trailing_window = col_window[:-1] # "past" values at a given index
    leading_window  = col_window[1:]  # "current values at a given index
    decreasing_inds = np.where(leading_window < trailing_window)[0]
    quotient = leading_window[decreasing_inds]/trailing_window[decreasing_inds]
    quotient_times = col_time[decreasing_inds]

    protocols[protname] = {
        "col_time": col_time,
        "col_window": col_window,
        "quotient_times": quotient_times,
        "quotient": quotient,
    }
    plt.figure(); plt.clf()
    plt.plot(quotient_times, quotient, ".", label=protname, color="blue")
    plt.ylim(0, 1.0001)
    plt.title(protname)
    plt.xlabel("quotient_times")
    plt.ylabel("quotient")
    plt.legend()
    plt.show()
    sns.distplot(quotient, hist=False, label=protname)

Это дает следующие графики.

enter image description here

enter image description here

Как видно из графиков

  • Data-V имеет коэффициент 0,8, если quotient_times меньше 3, а коэффициент остается 0,5, если quotient_times больше 3.

Я также установил его в бета-версию, используя следующий код

xt = plt.xticks()[0]  
xmin, xmax = min(xt), max(xt)  
lnspc = np.linspace(xmin, xmax, len(quotient))

alpha,beta,loc,scale = stats.beta.fit(quotient)  
pdf_beta = stats.beta.pdf(lnspc, alpha, beta,loc, scale)  
plt.plot(lnspc, pdf_beta, label="Data-V", color="darkblue", alpha=0.9)
plt.xlabel('$quotient$')
#plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
plt.legend(loc="best", frameon=False)

enter image description here

Как мы можем вписать quotient (определенный выше) в сигмовидную функцию, чтобы получить график, подобный следующему?

enter image description here

1 Ответ

1 голос
/ 11 марта 2019

Вы хотите соответствовать sigmoid или фактически логистической функции .Это может варьироваться несколькими способами, например, наклоном, средней точкой, величиной и смещением.

Вот код, который определяет эту функцию sigmoid и использует функцию scipy.optimize.curve_fit, чтобы минимизировать ошибку путем настройки параметров.

from scipy.optimize import curve_fit

def sigmoid (x, A, h, slope, C):
    return 1 / (1 + np.exp ((x - h) / slope)) *  A + C

# Fits the function sigmoid with the x and y data
#   Note, we are using the cumulative sum of your beta distribution!
p, _ = curve_fit(sigmoid, lnspc, pdf_beta.cumsum())

# Plots the data
plt.plot(lnspc, pdf_beta.cumsum(), label='original')
plt.plot(lnspc, sigmoid(lnspc, *p), label='sigmoid fit')
plt.legend()

# Show parameters for the fit
print(p)

Это дает вам следующий график:

comparison original data and sigmoid fit

и следующее пространство параметров (для указанной выше функции):

[-1.82910694e+01  4.88870236e-01  6.15103201e-03  1.82895890e+01]

Если вы хотите подогнать переменные quotient_time и quotient, просто измените переменные.

...
p, _ = curve_fit(sigmoid, quotient_times, quotient)
...

и нанесите на график:

quotient and sigmoid fit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...