Menu

Biểu đồ phân tán trong R: plot(), đường hồi quy và pairs()

Cách vẽ biểu đồ phân tán (scatter plot) trong R: vẽ hai biến bằng plot(), thêm đường hồi quy bằng abline(lm()), làm mượt bằng lowess() và tạo ma trận pairs().

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Biểu đồ phân tán cho thấy gì

Biểu đồ phân tán (scatter plot) thể hiện mối quan hệ giữa hai biến số: mỗi quan sát thành một điểm, đặt theo giá trị thứ nhất trên trục ngang và giá trị thứ hai trên trục dọc. Nếu hai biến biến đổi cùng nhau, các điểm tạo thành một khuôn mẫu; nếu không, bạn nhận được một đám mây không hình dạng. Đây là cái nhìn đầu tiên chuẩn mực trước khi khớp bất kỳ mô hình nào, và R vẽ nó bằng chính hàm plot() đã nói trong hướng dẫn plot().

Ta sẽ dùng mtcars, một bộ dữ liệu có sẵn gồm 32 chiếc xe, và đặt một câu hỏi vật lý: xe nặng hơn có động cơ mạnh hơn không?

Vẽ biểu đồ

wt là trọng lượng tính bằng nghìn pound, hp là mã lực:

plot(mtcars$wt, mtcars$hp,
     main = "Horsepower vs. weight",
     xlab = "Weight (1000 lbs)",
     ylab = "Horsepower",
     pch  = 19,
     col  = "steelblue")

Hình vẽ: ba mươi hai chấm đặc đi lên từ góc thấp của biểu đồ (xe nhẹ, khoảng 1,5 trên thang trọng lượng, khoảng từ 60 đến 90 mã lực) về phía các xe nặng trên 5, vượt quá 200 mã lực. Xu hướng đi lên rất rõ nhưng không gọn gàng: ở cùng một trọng lượng, các điểm trải trên một dải mã lực khá rộng.

Phần định dạng là bộ công cụ quen thuộc của biểu đồ base: pch = 19 cho hình tròn đặc (hình tròn rỗng mặc định dễ biến mất trong ảnh chụp màn hình), col cho màu, cex = 1.3 nếu điểm cần to hơn. Để tô màu điểm theo một biến phân loại thứ ba, hãy đánh chỉ số một vector màu bằng một factor: col = c("tomato", "steelblue", "darkgreen")[factor(mtcars$cyl)] cho mỗi số xi lanh một màu riêng.

Cách đọc: chiều, độ mạnh, hình dạng

Ba câu hỏi, theo thứ tự, mỗi lần bạn nhìn một biểu đồ phân tán:

  • Chiều. Các điểm đi lên (quan hệ dương) hay đi xuống (quan hệ âm) khi bạn nhìn dọc theo trục ngang? Ở đây chúng đi lên: nặng hơn nghĩa là mạnh hơn. Thử vẽ mpg theo wt thì đám mây đi xuống: nặng hơn nghĩa là tốn xăng hơn.
  • Độ mạnh. Các điểm bám sát một đường đi đến mức nào? Một dải mảnh như nét bút chì là quan hệ mạnh; một đám rải rác là quan hệ yếu. Đám mây này bám khá sát ở mức vừa phải.
  • Hình dạng và bất ngờ. Đường đi thẳng hay cong? Có cụm nào không, có điểm nào cách xa mọi điểm khác không? Trong mtcars, chiếc Maserati Bora nằm nổi bật phía trên cả nhóm: 335 mã lực ở mức trọng lượng trung bình. Một điểm như vậy có thể kéo lệch đường khớp đáng kể, đó chính là lý do bạn nhìn trước khi khớp.

Thêm đường xu hướng

Biểu đồ phân tán nêu ra một mối quan hệ; một đường đi qua nó tóm tắt nhận định đó. Khớp một mô hình tuyến tính rồi đưa thẳng cho abline():

plot(mtcars$wt, mtcars$hp,
     pch = 19, col = "steelblue",
     xlab = "Weight (1000 lbs)", ylab = "Horsepower")

abline(lm(hp ~ wt, data = mtcars), col = "tomato", lwd = 2)

lm(hp ~ wt) khớp đường bình phương nhỏ nhất (đọc công thức là "hp được giải thích bởi wt", biến của trục dọc đứng trước ~) và abline() vẽ nó ngang qua biểu đồ. Đường này tăng khoảng 46 mã lực trên mỗi nghìn pound. Mô hình đó có nghĩa là gì và cách đọc phần tóm tắt của nó là chủ đề của bài hồi quy tuyến tính.

Nếu không muốn giả định một đường thẳng, lowess() vẽ một đường cong mượt đi theo dữ liệu bất kể nó đi đâu:

lines(lowess(mtcars$wt, mtcars$hp), col = "darkgreen", lwd = 2, lty = 2)

Khi đường lowess và đường thẳng gần khớp nhau, tóm tắt tuyến tính là hợp lý. Khi đường cong uốn đi chỗ khác, mối quan hệ là phi tuyến và một đường thẳng sẽ mô tả sai nó.

Kiểm tra con số bằng cor()

Biểu đồ cho bạn hình dạng; cor() cho bạn độ mạnh bằng một con số. Bước này chỉ in ra văn bản, nên hãy chạy nó ở đây:

Trọng lượng và mã lực tương quan khoảng 0,66: đám mây đi lên bám vừa phải, được thể hiện bằng một con số. Ma trận còn cho thấy mpg tương quan âm mạnh với cả hai (khoảng −0,87 với trọng lượng). Nhưng hãy giữ thứ tự: biểu đồ trước, hệ số sau. Một giá trị r duy nhất có thể che giấu một đường cong hoặc bị một điểm ngoại lai thổi phồng: xem bài tương quan để biết những cách nó gây hiểu lầm kinh điển.

Ma trận biểu đồ phân tán: pairs()

Khi có nhiều cột số, vẽ tay từng cặp sẽ nhanh chán. pairs() làm việc đó trong một lệnh:

pairs(mtcars[, c("mpg", "wt", "hp")],
      pch = 19, col = "steelblue")

Kết quả là một lưới 3 × 3: tên biến nằm trên đường chéo, và mỗi ô ngoài đường chéo là biểu đồ phân tán của một cặp: mpg theo wt, mpg theo hp, wt theo hp, mỗi cặp xuất hiện hai lần với hai trục đổi chỗ. Đây là cách nhanh nhất để sàng lọc một bộ dữ liệu mới: một cái nhìn cho thấy cặp nào có liên quan, quan hệ nào cong, và điểm ngoại lai nằm ở đâu. Hãy chọn bớt cột trước, như ở đây: quá sáu bảy biến thì các ô co lại đến mức không đọc được.

Phiên bản ggplot2

Trong ggplot2, biểu đồ phân tán cộng một đường khớp là hai lớp:

library(ggplot2)

ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point(color = "steelblue", size = 2) +
    geom_smooth(method = "lm", color = "tomato") +
    labs(title = "Horsepower vs. weight",
         x = "Weight (1000 lbs)", y = "Horsepower")

geom_smooth(method = "lm") chính là abline(lm(...)) kèm thêm một phần thưởng: dải tin cậy tô bóng quanh đường. Bỏ trống method thì nó khớp một đường loess, phiên bản ggplot2 của lowess(). Base R thắng về tốc độ gõ khi cần xem nhanh; ggplot2 thắng ngay khi bạn muốn tô màu điểm theo nhóm kèm chú giải tự động.

Điều cần nhớ

  • plot(x, y) với hai vector số là một biểu đồ phân tán; pch = 19 và trục có nhãn giúp nó trông chỉn chu.
  • Đọc chiều, độ mạnh, hình dạng và tìm điểm ngoại lai trước khi tính bất cứ thứ gì.
  • abline(lm(y ~ x, data = df)) thêm đường hồi quy; lines(lowess(x, y)) thêm một đường cong không giả định là thẳng.
  • cor() định lượng điều biểu đồ cho thấy; biểu đồ giữ cho con số trung thực.
  • pairs(df[, cols]) vẽ mọi biểu đồ phân tán theo cặp cùng lúc, cách sàng lọc nhanh nhất cho một bộ dữ liệu mới.

Tiếp theo: biểu đồ cột, rời các cặp biến số để so sánh số lượng giữa các nhóm.

Câu hỏi thường gặp

Làm sao để vẽ biểu đồ phân tán trong R?

Gọi plot(x, y) với hai vector số, ví dụ plot(mtcars$wt, mtcars$hp). Mỗi quan sát thành một điểm. Thêm pch = 19 để có chấm đặc và main, xlab, ylab để gắn nhãn.

Làm sao để thêm đường hồi quy vào biểu đồ phân tán trong R?

Khớp mô hình rồi đưa nó cho abline(): abline(lm(hp ~ wt, data = mtcars)) vẽ đường bình phương nhỏ nhất lên biểu đồ đang có. Chú ý thứ tự trong công thức: biến của trục dọc đứng trước dấu ~.

Làm sao để vẽ nhiều cặp biến cùng lúc trong R?

pairs(df) vẽ một ma trận biểu đồ phân tán: mỗi cặp cột một ô nhỏ. Hãy chọn bớt cột trước, như pairs(mtcars[, c("mpg", "wt", "hp")]), vì quá sáu bảy cột thì các ô sẽ nhỏ đến mức không đọc được.

Biểu đồ phân tán cho biết điều gì mà hệ số tương quan không cho biết?

Hình dạng. Hệ số tương quan chỉ là một con số và có thể giống hệt nhau cho một đường thẳng gọn gàng, một đường cong, hay một đám mây có một điểm ngoại lai cực đoan. Biểu đồ phân tán cho thấy trực tiếp độ cong, các cụm và điểm ngoại lai, đó là lý do bạn vẽ trước rồi mới tính cor().

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu