วิธีการลงจุด R linear model lm () โดยใช้ scatterplot3d ผ่านฟังก์ชัน $ plane3d
ชุมชน Stackoverflow
ฉันต้องการพล็อตผลลัพธ์ของ R lm()เป็นระนาบในกราฟ 3 มิติที่สร้างด้วย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 - สร้างกราฟ 3 มิติ
library(scatterplot3d)
s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55)
ในการสร้างกราฟกราฟ scatterplot กราฟ + 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 กับการสกัดกั้นใน scatterplot
ฉันทำตามคำแนะนำนี้: R - การขยาย Linear Model เกิน 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ในคำสั่งด้านบนซึ่งให้ แต่ข้อผิดพลาดอื่น - บรรทัดล่าง - ไม่ทำงาน
ณ จุดนี้ฉันสูญเสียอย่างสิ้นเชิง (ฉันได้ลองใช้วิธีอื่น ๆ มากมาย - ซึ่งฉันไม่สามารถโพสต์ได้ทั้งหมด) ฉันอยากจะขอความช่วยเหลือในการพยายามปักหมุดสิ่งที่ฉันขาดหายไปในการพล็อตระนาบนี้บนกราฟนี้ ความช่วยเหลือใด ๆ และทั้งหมดจะได้รับการชื่นชมเป็นอย่างมาก
ขอขอบคุณ.
คำตอบ
scatterplot3d()จะไม่สามารถพล็อตโมเดลที่มีขนาดใหญ่กว่า (มากกว่า 2 มิติอินพุตและ 1 มิติเอาต์พุต) ในแบบ 3 มิติ ในความเป็นจริงพล็อตดังกล่าวจะไม่ถูกต้องเนื่องจากค่าในมิติข้อมูลเพิ่มเติมน่าจะแตกต่างกันสำหรับการสังเกตที่แตกต่างกัน ดังนั้นพวกเขาจะมีอิทธิพลต่อความใกล้ชิดของแบบจำลองและพล็อตที่ละเลยสิ่งเหล่านี้จะทำให้เข้าใจผิด
ที่กล่าวว่าs3d$plane3dไม่สามารถจัดการอินพุตที่ผิดรูปแบบได้เป็นอย่างดี ตัวอย่างเช่นหากมิติข้อมูลของโมเดลไม่เป็นไปตามที่คาดไว้โมเดลจะส่งคืนข้อความแสดงข้อผิดพลาดที่ทำให้สับสน (ดังที่คุณเห็น) นอกจากนี้ยังไม่มีความช่วยเหลือสำหรับฟังก์ชันนี้และในความเป็นจริงฟังก์ชันนั้นซ้อนอยู่ในฟังก์ชันอื่นในแพ็คเกจและไม่มีความคิดเห็น เป็นผลให้ทั้งหมดนี้จะค่อนข้างยากที่จะเข้าใจ แต่ถ้าคุณต้องการที่จะไปลึกคุณต้องอ่านรหัสของแพคเกจที่คุณสามารถหาที่นี่
คุณสามารถให้พล็อตของคุณแสดงพื้นผิวการถดถอยบางส่วนได้ แต่คุณต้องบอก plot3d ว่าต้องการมิติใด โดยพื้นฐานแล้วคุณจะต้องวางแผนเครื่องบินในพื้นที่ 3 มิติซึ่งคุณควรมีไฮเปอร์เพลนในพื้นที่มิติที่สูงขึ้น
ความพยายามครั้งที่ 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)))
แต่ระนาบที่คุณเห็นนั้นเป็นเพียงชิ้นส่วน 2 มิติผ่านพื้นผิว 3 มิตินั่นคือการถดถอยของคุณและแสดงเฉพาะการสังเกตที่คุณมีค่าเฉลี่ยในมิติที่สามเท่านั้น ( elevในกรณีของคุณ)
ในความเป็นจริงนี่คือสิ่งที่คุณจะได้รับหากคุณวิ่งถดถอยโดยไม่มีมิติเพิ่มเติม ดังนั้นคุณอาจจะทำและวางแผนเช่นนั้น