#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