Как построить линейную модель R lm () с помощью scatterplot3d с помощью функции $plane3d
Сообщество Stackru,
Я хочу построить результаты R
lm()
как плоскость на трехмерном графике, созданном с помощью
scatterplot3d()
из пакета R scatterplot3d. Я продолжаю получать несколько ошибок, в зависимости от моего метода построения графика с помощью
$plane3d()
функция.
Во-первых, некоторые воспроизводимые данные. Шаг 1. Создание фрейма данных.
elem <- data.frame(pH = c(8.12, 8.19, 6.09, 5.99, 5.18, 6.09, 5.40, 5.50, 4.93, 5.16, 7.57, 7.21, 5.13, 6.23, 5.72),
water_Loss = c(0.010, 0.005, 0.065, 0.120, 0.250, 0.305, 0.100, 0.020, 0.430, 0.060, 0.065, 0.050, 0.025, 0.050, 0.020),
elev = c(2397, 2393, 2593, 2599, 2741, 2774, 2979, 2787, 3173, 3370, 2147, 2130, 2374, 2359, 2643),
co2 = c(1.8410, 1.9810, 2.0110, 1.8960, 1.3060, 2.0160, 1.7360, 1.5860, 1.6360, 1.9665, 1.6360, 1.7660, 1.9760, 2.7510, 1.3310))
Шаг 2 - подгонка линейной модели
lms <- lm(elem$co2 ~ elem$pH + elem$water_Loss + elem$elev + I(elem$pH * elem$water_Loss * elem$elev))
summary(lms)
Примечание: в результатах этой линейной модели отсутствуют параметры lms$model$x и lms$model$y.
Шаг 3 - построение трехмерного графика
library(scatterplot3d)
s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55)
Чтобы построить график диаграммы рассеяния +
lm()
результат,
s3d$plane3d()
запускается сразу после построения графика.
Как это:
s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55)
s3d$plane3d()
Однако, двигаясь вперед, я укажу только
s3d$plane3d()
часть.
Вот где возникает проблема. Я выделю 3 различных способа, которыми я пытался отобразить линейную модель на этом графике.
Попытка 1: Построение результатов LMS напрямую
s3d$plane3d(lms, draw_polygon = TRUE, draw_lines = TRUE)
Это вызывает следующую ошибку:
Ошибка в xy.coords(x, y, setLab = FALSE): длины 'x' и 'y' различаются
Пытаясь исправить это, я пошел сюда: длины 'x' и 'y' различаются ОШИБКА при построении
Как и в сообщении, я использовал флаг
lm(x = TRUE, y = TRUE)
но у меня еще не было таких параметров в
lm()
результаты, чтобы иметь возможность проверить
length()
и это не сработало.
Попытка 2: указание координат x,y,z с точкой пересечения на диаграмме рассеяния
Я последовал этому предложению: R - Расширение линейной модели за пределы scatterplot3d
Для флага перехвата я использовал следующий код:
lms$coefficients
и взял значение под (Перехват).
s3d$plane3d(xyz.coords(x = as.numeric(lms$model$`elem$pH`), y = as.numeric(lms$model$`elem$water_Loss`), z = as.numeric(lms$model$`elem$elev`)), Intercept = 3.010033e+00 )
Это вызывает следующую ошибку:
Ошибка в x.coef * x.scal: нечисловой аргумент бинарного оператора
Попытка 3. Построение отдельных коэффициентов и попытка нарисовать многоугольники и линии.
Я попробовал это, прочитав документацию на R для
planes3d()
команда из {rgl}
Получение коэффициентов:
coefs <- coef(lms) ; coefs
s3d$plane3d(a = -5.901006e-02 , b = -1.546285e+01, c = -2.946729e-04, Intercept = 3.010033e+00)
Это вызывает следующую ошибку:
Ошибка в x.coef * x.scal: нечисловой аргумент бинарного оператора
Еще попробовал добавить флаги
draw_polygon = TRUE, draw_lines = TRUE
к приведенной выше команде, которая дала только еще одну ошибку - нижнюю строку - не сработала.
На данный момент я в полной растерянности (я пробовал много других методов - я не могу опубликовать их все). Я хотел бы попросить помощи в попытке точно определить, что именно мне не хватает для построения этой плоскости на этом графике. Мы будем очень благодарны за любую помощь.
Спасибо.
1 ответ
scatterplot3d()
не сможет строить модели с большей размерностью (чем 2 входных измерения и 1 выходное измерение) в 3D. Фактически, такой график не будет действительным, поскольку значения в дополнительных измерениях предположительно будут разными для разных наблюдений. Следовательно, они будут влиять на то, насколько точно подходит модель, и график, в котором они не учитываются, будет вводить в заблуждение.
Тем не менее,
s3d$plane3d
не очень хорошо обрабатывает искаженный ввод. Например, если размерность модели не соответствует ожидаемой, она вернет сбивающие с толку сообщения об ошибках (как вы уже видели). Для этой функции также нет справки, и фактически функция вложена в другую функцию пакета и не имеет комментариев. В результате все это будет довольно сложно понять, но если вы хотите углубиться, вы должны прочитать код пакета, который вы можете найти здесь.
Вы можете абсолютно точно, чтобы ваш график отображал поверхность частичной регрессии, но вы должны указать plot3d, какие измерения вы хотите. По сути, вы будете рисовать плоскость в трехмерном пространстве, где у вас должна быть гиперплоскость в пространстве более высоких измерений.
Ваша попытка 2 была на правильном пути. Но вы не приводите правильный аргумент. Функция хочет
x.coef
и
y.coef
и т. д. но не
xyz.coords
и поэтому он, по-видимому, пытается интерпретировать переданные вами векторы как коэффициент и терпит неудачу. Вместо этого вы можете сделать это:
s3d$plane3d(Intercept=lms$coefficients["(Intercept)"][[1]],
x.coef=lms$coefficients["elem$pH"][[1]],
y.coef=lms$coefficients["elem$water_Loss"][[1]],
draw_polygon = TRUE,
draw_lines = TRUE,
polygon_args = list(col = rgb(0.8, 0.8, 0.8, 0.8)))
Однако маловероятно, что вы даже увидите поверхность регрессии на своем графике, потому что влияние размеров, которые вы не наносите, сместит ее из видимой области вашей фигуры. Если вы хотите оттянуть его силой, вам нужно изменить свой перехват:
average_intercept <- lms$coefficients["(Intercept)"][[1]] + lms$coefficients["elem$elev"][[1]] * mean(elem$elev)
s3d$plane3d(Intercept=average_intercept,
x.coef=lms$coefficients["elem$pH"][[1]],
y.coef=lms$coefficients["elem$water_Loss"][[1]],
draw_polygon = TRUE,
draw_lines = TRUE,
polygon_args = list(col = rgb(0.8, 0.8, 0.8, 0.8)))
Но плоскость, которую вы видите, на самом деле представляет собой только двумерный срез трехмерной поверхности, которая является вашей регрессией и точно представляет только те наблюдения, которые вы видите, которые имеют точно среднее значение в этом третьем измерении (elev
в твоем случае).
Фактически, это именно то, что вы получили бы, если бы запустили регрессию без дополнительных измерений; так что вы можете сделать это и построить график.