Как найти точки перегиба на графике плотности ядра в R? - PullRequest
0 голосов
/ 09 июля 2020

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

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

Как найти все точки поворота на кривой плотности ядра при изменении ширины окна .

Так что, я думаю, должен быть способ найти x-значения точек перегиба тоже. Было бы здорово, если бы у кого-нибудь есть чаевые.

1 Ответ

0 голосов
/ 09 июля 2020

По определению, точка перегиба - это точка, в которой вторая производная функции равна нулю. На практике это означает, что точкой перегиба будет точка, в которой наклон переходит от увеличения к уменьшению, или vv. Используя это определение, я пришел с этим приблизительным и неавтоматическим подходом c: предположим, что у вас есть фрейм данных , который я назову all, который содержит значения x в первом столбце и результат вычисления плотности во втором столбце. Из этого фрейма данных мы можем вычислить наклон двух последовательных точек следующим образом:

slopes <- vector()
for(i in (2:nrow(all))){
  x1 <- all[i-1, 1]
  x2 <- all[i, 1]
  y1 <- all[i-1, 2]
  y2 <- all[i, 2]
  slope_i <- (y2-y1)/(x2-x1)
  slopes <- append(slopes, slope_i)
}

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

increment <- vector()
for(j in 2:length(slopes)){
  increment_j <- slopes[j] - slopes[j-1]
  increment <- append(increment, increment_j)
}

Точками перегиба будут те точки, где это приращение перешло от положительного к отрицательному, или vv

Теперь давайте разделим эти приращения на положительные и отрицательные:

pos <- which(increment>0)
neg <- which(increment<0

Теперь, когда есть скачок в этих pos или neg векторах, это означает, что у нас есть точка перегиба. Итак, еще раз:

steps_p <- vector()
for(k in 2:length(pos)){
  steps_k <- pos[k] - pos[k-1]
  steps_p <- append(steps_p, steps_k)
}
steps_n <- vector()
for(k in 2:length(neg)){
  steps_k <- neg[k] - neg[k-1]
  steps_n <- append(steps_n, steps_k)
}

Теперь просто спросите R:

which(steps_p>1)
which(steps_n>1)

Это индексы ваших точек перегиба, теперь просто go к исходному фрейму данных и попросите значение x:

all[pos[which(steps_p>1)],1]
all[neg[which(steps_n>1)],1]

Имейте в виду, что значение x будет близко к точному, но не совсем, так как в течение каждого l oop мы теряем один индекс, но он все равно будет очень близким раствор.

...