Один пример кривой показан ниже. Точка локтя может быть x = 3 или 4. Как вычислить локоть для кривой автоматически и математически?
Один пример кривой показан ниже. Точка локтя может быть x = 3 или 4. Как вычислить локоть для кривой автоматически и математически?
Вы можете захотеть найти точку с максимальной абсолютной второй производной, которая для набора дискретных точек x[i]
, как вы там, может быть аппроксимирована с центральной разницей:
secondDerivative[i] = x[i+1] + x[i-1] - 2 * x[i]
Как отмечалось выше, то, что вы действительно хотите, это точка с максимальной кривизной, но вторая производная будет делать, и это центральное различие является хорошим прокси для второй производной.
Я создал пакет Python , который пытается реализовать алгоритм Kneedle.
Чтобы воссоздать вышеуказанную функцию и определить точку максимальной кривизны:
x = range(1,21)
y = [0.065, 0.039, 0.030, 0.024, 0.023, 0.022, 0.019, 0.0185, 0.0187,
0.016, 0.015, 0.016, 0.0135, 0.0130, 0.0125, 0.0120, 0.0117, 0.0115, 0.0112, 0.013]
kn = KneeLocator(
x,
y,
curve='convex',
direction='decreasing',
interp_method='interp1d',
)
print(kn.knee)
7
import matplotlib.pyplot as plt
plt.xlabel('x')
plt.ylabel('f(x)')
plt.xticks(range(1,21))
plt.plot(x, y, 'bx-')
plt.vlines(kn.knee, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')
Обновить
Kneed имеет улучшенный метод подбора сплайнов для обработки локальных минимумов, используйте interp_method='polynomial'
.
kn = KneeLocator(
x,
y,
curve='convex',
direction='decreasing',
interp_method='polynomial',
)
print(kn.knee)
4
И новый сюжет:
plt.xlabel('x')
plt.ylabel('f(x)')
plt.xticks(range(1,21))
plt.plot(x, y, 'bx-')
plt.vlines(kn.knee, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')
Такие функции, как этот, обычно называются L-curve для их фигур. Они появляются при решении некорректных проблем посредством регуляризации.
"Локоть" - точка на кривой с максимальной абсолютной второй производной.
То, что вы действительно хотите, это точка с максимальным curvature. Когда наклон много меньше 1, это может быть аппроксимировано второй производной (как указывает @ebo), но это не всегда так.