#python #python-3.x #numpy #scikit-learn #logistic-regression
#python #python-3.x #numpy #scikit-learn #логистическая регрессия
Вопрос:
По соображениям воспроизводимости я делюсь простым набором данных, над которым я работаю здесь.
Чтобы было понятно, что я делаю — из столбца 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)
Это дает следующие графики.
Как мы можем видеть из графиков
- 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)
Как мы можем вписать quotient
(определенное выше) в сигмовидную функцию, чтобы получить график примерно следующего вида?
Комментарии:
1. Я рекомендую вам пакет lmfit. Здесь у вас есть простой способ реализовать ваши собственные подогнанные функции. (Надеюсь, я правильно понял вашу проблему)
2.
lmfit
для сигмовидной функции? Я раньше с этим не работал, но можешь попробовать с набором данных, которым я поделился, Ричард? Спасибо.3. Разве подгонка набора данных в sigmoid не такая же, как использование классификатора sigmoid? Вам просто нужно извлечь параметры. В Scikit learn есть сигмовидный классификатор, который очень прост в использовании.
4. Я сделал что-то очень похожее в R, поможет ли это, если я поделюсь этим?
5. @MedImage, спасибо, но я хочу это на Python. Если бы вы могли поделиться своим ответом на Python с теми же данными, которыми поделился я, это было бы здорово, и я отмечу это как принятый ответ.
Ответ №1:
Вы хотите подогнать 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)
Это дает вам следующий график:
и следующее пространство параметров (для вышеупомянутой используемой функции):
[-1.82910694e 01 4.88870236e-01 6.15103201e-03 1.82895890e 01]
Если вы хотите подогнать переменные quotient_time
и quotient
, вы просто меняете переменные.
...
p, _ = curve_fit(sigmoid, quotient_times, quotient)
...
и отобразить ее:
Комментарии:
1. Я все еще не уверен, действительно ли это то, чего вы «хотите» (с научной точки зрения), но это то, о чем вы просили 😉
2. Да, это именно то, о чем я спрашивал, но не могли бы вы попробовать это с набором данных, которым я поделился?
3. @Brown, это твой набор данных! Это совокупная сумма бета-дистрибутива.
4. Действительно? Тогда куда вы передаете бета-версию данных? Может быть, мне принести кофе:-D
5. @Brown, это
pdf_beta.cumsum()
команда,pdf_beta
именно то, что вы указали в своем примере кода. Я дополнительно предоставил теперь подгонкуquotient
иquotient_times
(в качестве вашего первого графика). Надеюсь, это поможет. И когда данные распределены настолько неоднородно, то подгонка, скорее всего, будет не слишком хорошей.