Создать экспоненциальную функцию в R из 2 точек

#r #function #exponential

#r #функция #экспоненциальная

Вопрос:

Я хотел бы создать экспоненциальную функцию в R, когда заданы только 2 точки, через которые проходит линия. Я хотел бы использовать базовый формат f (x) = ab ^ x. Я понимаю, как сделать это вручную, создав два уравнения, а затем отдельно решая для b и a, но у меня возникают проблемы с кодированием этого в R. Например, когда я пытаюсь присвоить переменной другую переменную, я получаю «объект не найден ошибка» на первом шагеэтого процесса.

 x <- c(4, 3, 1.8, 1.1, .6, .3, .02) 
y <- c(2, 7, 16, 27, 40, 51, 66)  
df <- data.frame(x,y)
a <- df$y[1]/b^df$x[1]

Error: object 'b' not found
  

Я понимаю, почему я получаю эту ошибку, но я не знаю, как ее обойти.

Я мог бы создать экспоненциальную модель, используя только первые 2 точки, но коэффициенты не близки к фактическим значениям данных.

 expmod <- lm(log(df$y[1:2])~df$x[1:2])
exp(expmod$coefficients)

(Intercept)        df$x 
300.1250000   0.2857143
  

Перехват должен быть ближе к 66 на основе данных (y = 66, когда x = 0.02)

В конечном итоге я хочу иметь возможность использовать эту функцию для получения двух точек на линии, а затем как для построения линии, так и для получения значений на основе других входных данных x (т. Е. c (0,1,2,3,4)), но на ранней стадии у меня возникают проблемы.

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

Комментарии:

1.Модель, которую вы получаете, представляет собой экспоненциальную функцию, которая проходит через две точки. Вы получите те же коэффициенты, если решите ее, используя одновременные уравнения. b <- exp((log(y[1]) - log(y[2])) / (x[1] - x[2])) a <- y[1] / (b ^ x[1])

Ответ №1:

Причина, по которой вы не получаете желаемый перехват, заключается в том, что первые две точки в вашем фрейме данных не находятся на той же экспоненциальной кривой, что и другие точки. Мы можем увидеть это, построив график log(y) против x :

 plot(x, log(y))
  

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

Теперь давайте нарисуем регрессию, используя только ваши первые две точки (две крайние правые точки)

 abline(lm(log(y) ~ x, data = df[1:2, ]), col = "red")
  

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

и добавьте строку для остальных 5 точек:

 abline(lm(log(y) ~ x, data = df[-c(1:2), ]), col = "blue")
  

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

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

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

И наоборот, если мы используем все точки, мы получаем разумный прогноз для отношения в целом:

 plot(x, y)
lines(new_frame$x, new_frame$y, col = "red")
  

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

И численное предсказание для перехвата ближе к вашим ожиданиям:

 exp(lm(log(y) ~ x, data = df)$coef)
#> (Intercept)           x 
#>  68.2345853   0.4335491 
  

Редактировать

Чтобы вычислить уравнение «вручную» из двух точек, вам нужно взять логарифм значений y, затем вы можете вычислить градиент логарифмической линии между двумя точками, выполнив:

 gradient <- (log(y2) - log(y1)) / (x2 - x1)
  

и вы можете получить перехват, решив y = gradient * x intercept для перехвата, то есть:

 intercept <- log(y1) - gradient * x1
  

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

 exp_line <- function(x1, x2, y1, y2) {
  gradient  <- (log(y2) - log(y1)) / (x2 - x1)
  intercept <- log(y1) - gradient * x1
  cat("y = ", exp(gradient), "^x * ", exp(intercept), "n", sep = "")
}
  

Мы получаем

 exp_line(x[1], x[2], y[1], y[2])
#> y = 0.2857143^x * 300.125

exp_line(x[4], x[5], y[4], y[5])
#> y = 0.455625^x * 64.10553
  

И если мы хотим нарисовать экспоненциальную кривую между любыми двумя точками, мы можем сделать следующее:

 draw_exp_line <- function(x1, x2, y1, y2, col) {
  gradient  <- (log(y2) - log(y1)) / (x2 - x1)
  intercept <- log(y1) - gradient * x1
  x <- seq(0, 5, 0.1)
  lines(x, exp(gradient)^x * exp(intercept), col = col)
}

plot(x, y)
draw_exp_line(x[2], x[1], y[2], y[1], "red")
  

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

Комментарии:

1. Спасибо, Аллан, но это не то, о чем я прошу. Я полностью понимаю, что делать любую форму регрессии только с двумя точками — плохая идея. Я специально хочу найти экспоненциальную функцию, когда задано только две точки. Я привел пример экспоненциальной модели как способ определения функции по коэффициентам модели, но это, очевидно, не очень хорошая идея. Я хотел бы сделать это так же, как вы бы вручную в исчислении, но закодированный в R. Что-то похожее на это youtube.com/watch?v=1IE5jNudELQ