วิธีการลงจุด R linear model lm () โดยใช้ scatterplot3d ผ่านฟังก์ชัน $ plane3d

Nov 06 2020

ชุมชน 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ในคำสั่งด้านบนซึ่งให้ แต่ข้อผิดพลาดอื่น - บรรทัดล่าง - ไม่ทำงาน

ณ จุดนี้ฉันสูญเสียอย่างสิ้นเชิง (ฉันได้ลองใช้วิธีอื่น ๆ มากมาย - ซึ่งฉันไม่สามารถโพสต์ได้ทั้งหมด) ฉันอยากจะขอความช่วยเหลือในการพยายามปักหมุดสิ่งที่ฉันขาดหายไปในการพล็อตระนาบนี้บนกราฟนี้ ความช่วยเหลือใด ๆ และทั้งหมดจะได้รับการชื่นชมเป็นอย่างมาก

ขอขอบคุณ.

คำตอบ

1 0range Nov 19 2020 at 00:15

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ในกรณีของคุณ)

ในความเป็นจริงนี่คือสิ่งที่คุณจะได้รับหากคุณวิ่งถดถอยโดยไม่มีมิติเพิ่มเติม ดังนั้นคุณอาจจะทำและวางแผนเช่นนั้น