Cây Quyết định là gì?
Cây Quyết định là thuật toán Học máy linh hoạt có thể thực hiện cả nhiệm vụ phân loại và hồi quy. Chúng là các thuật toán rất mạnh, có khả năng phù hợp với các bộ dữ liệu phức tạp. Bên cạnh đó, cây quyết định là thành phần cơ bản của rừng ngẫu nhiên, là một trong những thuật toán Machine Learning mạnh nhất hiện nay.
Đào tạo và Hình dung cây quyết định
Để xây dựng cây quyết định đầu tiên của bạn trong ví dụ R, chúng tôi sẽ tiến hành như sau trong hướng dẫn Cây quyết định này:
- Bước 1: Nhập dữ liệu
- Bước 2: Làm sạch tập dữ liệu
- Bước 3: Tạo tập huấn luyện / thử nghiệm
- Bước 4: Xây dựng mô hình
- Bước 5: Đưa ra dự đoán
- Bước 6: Đo lường hiệu suất
- Bước 7: Điều chỉnh các siêu tham số
Bước 1) Nhập dữ liệu
Nếu bạn tò mò về số phận của Titanic, bạn có thể xem video này trên Youtube. Mục đích của tập dữ liệu này là dự đoán những người nào có nhiều khả năng sống sót hơn sau vụ va chạm với tảng băng trôi. Tập dữ liệu chứa 13 biến và 1309 quan sát. Tập dữ liệu được sắp xếp theo thứ tự của biến X.
set.seed(678)path <- 'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/titanic_data.csv'titanic <-read.csv(path)head(titanic)
Đầu ra:
## X pclass survived name sex## 1 1 1 1 Allen, Miss. Elisabeth Walton female## 2 2 1 1 Allison, Master. Hudson Trevor male## 3 3 1 0 Allison, Miss. Helen Loraine female## 4 4 1 0 Allison, Mr. Hudson Joshua Creighton male## 5 5 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female## 6 6 1 1 Anderson, Mr. Harry male## age sibsp parch ticket fare cabin embarked## 1 29.0000 0 0 24160 211.3375 B5 S## 2 0.9167 1 2 113781 151.5500 C22 C26 S## 3 2.0000 1 2 113781 151.5500 C22 C26 S## 4 30.0000 1 2 113781 151.5500 C22 C26 S## 5 25.0000 1 2 113781 151.5500 C22 C26 S## 6 48.0000 0 0 19952 26.5500 E12 S## home.dest## 1 St Louis, MO## 2 Montreal, PQ / Chesterville, ON## 3 Montreal, PQ / Chesterville, ON## 4 Montreal, PQ / Chesterville, ON## 5 Montreal, PQ / Chesterville, ON## 6 New York, NY
tail(titanic)
Đầu ra:
## X pclass survived name sex age sibsp## 1304 1304 3 0 Yousseff, Mr. Gerious male NA 0## 1305 1305 3 0 Zabour, Miss. Hileni female 14.5 1## 1306 1306 3 0 Zabour, Miss. Thamine female NA 1## 1307 1307 3 0 Zakarian, Mr. Mapriededer male 26.5 0## 1308 1308 3 0 Zakarian, Mr. Ortin male 27.0 0## 1309 1309 3 0 Zimmerman, Mr. Leo male 29.0 0## parch ticket fare cabin embarked home.dest## 1304 0 2627 14.4583 C## 1305 0 2665 14.4542 C## 1306 0 2665 14.4542 C## 1307 0 2656 7.2250 C## 1308 0 2670 7.2250 C## 1309 0 315082 7.8750 S
Từ đầu ra đầu và đuôi, bạn có thể nhận thấy dữ liệu không bị xáo trộn. Đây là một vấn đề lớn! Khi bạn phân chia dữ liệu của mình giữa nhóm tàu và nhóm thử nghiệm, bạn sẽ chỉ chọn hành khách từ hạng 1 và 2 (Không có hành khách nào từ hạng 3 nằm trong 80 phần trăm quan sát hàng đầu), có nghĩa là thuật toán sẽ không bao giờ thấy tính năng của hành khách hạng 3. Sai lầm này sẽ dẫn đến dự đoán kém.
Để khắc phục vấn đề này, bạn có thể sử dụng hàm sample ().
shuffle_index <- sample(1:nrow(titanic))head(shuffle_index)
Cây quyết định Mã R Giải thích
- sample (1: nrow (titanic)): Tạo danh sách ngẫu nhiên chỉ số từ 1 đến 1309 (tức là số hàng tối đa).
Đầu ra:
## [1] 288 874 1078 633 887 992
Bạn sẽ sử dụng chỉ mục này để xáo trộn tập dữ liệu titanic.
titanic <- titanic[shuffle_index, ]head(titanic)
Đầu ra:
## X pclass survived## 288 288 1 0## 874 874 3 0## 1078 1078 3 1## 633 633 3 0## 887 887 3 1## 992 992 3 1## name sex age## 288 Sutton, Mr. Frederick male 61## 874 Humblen, Mr. Adolf Mathias Nicolai Olsen male 42## 1078 O'Driscoll, Miss. Bridget female NA## 633 Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren) female 39## 887 Jermyn, Miss. Annie female NA## 992 Mamee, Mr. Hanna male NA## sibsp parch ticket fare cabin embarked home.dest## 288 0 0 36963 32.3208 D50 S Haddenfield, NJ## 874 0 0 348121 7.6500 F G63 S## 1078 0 0 14311 7.7500 Q## 633 1 5 347082 31.2750 S Sweden Winnipeg, MN## 887 0 0 14313 7.7500 Q## 992 0 0 2677 7.2292 C
Bước 2) Làm sạch tập dữ liệu
Cấu trúc của dữ liệu cho thấy một số biến có NA. Việc dọn dẹp dữ liệu sẽ được thực hiện như sau
- Thả các biến home.dest, cabin, name, X và ticket
- Tạo các biến nhân tố cho lớp và tồn tại
- Thả NA
library(dplyr)# Drop variablesclean_titanic <- titanic % > %select(-c(home.dest, cabin, name, X, ticket)) % > %#Convert to factor levelmutate(pclass = factor(pclass, levels = c(1, 2, 3), labels = c('Upper', 'Middle', 'Lower')),survived = factor(survived, levels = c(0, 1), labels = c('No', 'Yes'))) % > %na.omit()glimpse(clean_titanic)
Giải thích mã
- select (-c (home.dest, cabin, name, X, ticket)): Bỏ các biến không cần thiết
- pclass = factor (pclass, levels = c (1,2,3), label = c ('Upper', 'Middle', 'Lower')): Thêm nhãn vào lớp biến. 1 trở thành Thượng, 2 trở thành MIddle và 3 trở thành thấp hơn
- factor (còn tồn tại, cấp = c (0,1), nhãn = c ('Không', 'Có')): Thêm nhãn cho biến còn tồn tại. 1 trở thành Không và 2 trở thành Có
- na.omit (): Loại bỏ các quan sát NA
Đầu ra:
## Observations: 1,045## Variables: 8## $ pclassUpper, Lower, Lower, Upper, Middle, Upper, Middle, U… ## $ survived No, No, No, Yes, No, Yes, Yes, No, No, No, No, No, Y… ## $ sex male, male, female, female, male, male, female, male… ## $ age 61.0, 42.0, 39.0, 49.0, 29.0, 37.0, 20.0, 54.0, 2.0,… ## $ sibsp 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 1, 1, 0, 0, 0, 1, 1,… ## $ parch 0, 0, 5, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 4, 0,… ## $ fare 32.3208, 7.6500, 31.2750, 25.9292, 10.5000, 52.5542,… ## $ embarked S, S, S, S, S, S, S, S, S, C, S, S, S, Q, C, S, S, C…
Bước 3) Tạo tập huấn luyện / thử nghiệm
Trước khi đào tạo mô hình của mình, bạn cần thực hiện hai bước:
- Tạo một đoàn tàu và tập thử nghiệm: Bạn huấn luyện mô hình trên tập đoàn tàu và kiểm tra dự đoán trên tập thử nghiệm (tức là dữ liệu không nhìn thấy)
- Cài đặt rpart.plot từ bảng điều khiển
Thực tế phổ biến là chia nhỏ dữ liệu 80/20, 80% dữ liệu dùng để đào tạo mô hình và 20% để đưa ra dự đoán. Bạn cần tạo hai khung dữ liệu riêng biệt. Bạn không muốn chạm vào bộ thử nghiệm cho đến khi hoàn thành việc xây dựng mô hình của mình. Bạn có thể tạo một tên hàm create_train_test () có ba đối số.
create_train_test(df, size = 0.8, train = TRUE)arguments:-df: Dataset used to train the model.-size: Size of the split. By default, 0.8. Numerical value-train: If set to `TRUE`, the function creates the train set, otherwise the test set. Default value sets to `TRUE`. Boolean value.You need to add a Boolean parameter because R does not allow to return two data frames simultaneously.
create_train_test <- function(data, size = 0.8, train = TRUE) {n_row = nrow(data)total_row = size * n_rowtrain_sample < - 1: total_rowif (train == TRUE) {return (data[train_sample, ])} else {return (data[-train_sample, ])}}
Giải thích mã
- function (data, size = 0.8, train = TRUE): Thêm các đối số trong hàm
- n_row = nrow (data): Đếm số hàng trong tập dữ liệu
- total_row = size * n_row: Trả lại hàng thứ n để xây dựng nhóm tàu
- train_sample <- 1: total_row: Chọn hàng đầu tiên đến hàng thứ n
- if (train == TRUE) {} else {}: Nếu điều kiện đặt thành true, trả về tập hợp huấn luyện, trả về tập hợp thử nghiệm khác.
Bạn có thể kiểm tra chức năng của mình và kiểm tra kích thước.
data_train <- create_train_test(clean_titanic, 0.8, train = TRUE)data_test <- create_train_test(clean_titanic, 0.8, train = FALSE)dim(data_train)
Đầu ra:
## [1] 836 8
dim(data_test)
Đầu ra:
## [1] 209 8
Tập dữ liệu tàu có 1046 hàng trong khi tập dữ liệu thử nghiệm có 262 hàng.
Bạn sử dụng hàm prop.table () kết hợp với table () để xác minh xem quá trình ngẫu nhiên hóa có đúng hay không.
prop.table(table(data_train$survived))
Đầu ra:
#### No Yes## 0.5944976 0.4055024
prop.table(table(data_test$survived))
Đầu ra:
#### No Yes## 0.5789474 0.4210526
Trong cả hai tập dữ liệu, số lượng người sống sót là như nhau, khoảng 40%.
Cài đặt rpart.plot
rpart.plot không có sẵn từ các thư viện conda. Bạn có thể cài đặt nó từ bảng điều khiển:
install.packages("rpart.plot")
Bước 4) Xây dựng mô hình
Bạn đã sẵn sàng để xây dựng mô hình. Cú pháp cho hàm cây quyết định Rpart là:
rpart(formula, data=, method='')arguments:- formula: The function to predict- data: Specifies the data frame- method:- "class" for a classification tree- "anova" for a regression tree
Bạn sử dụng phương thức lớp vì bạn dự đoán một lớp.
library(rpart)library(rpart.plot)fit <- rpart(survived~., data = data_train, method = 'class')rpart.plot(fit, extra = 106
Giải thích mã
- rpart (): Hàm để phù hợp với mô hình. Các đối số là:
- còn tồn tại ~: Công thức của Cây Quyết định
- data = data_train: Tập dữ liệu
- method = 'class': Phù hợp với mô hình nhị phân
- rpart.plot (fit, extra = 106): Vẽ cái cây. Các tính năng bổ sung được đặt thành 101 để hiển thị xác suất của lớp thứ 2 (hữu ích cho các phản hồi nhị phân). Bạn có thể tham khảo họa tiết để biết thêm thông tin về những sự lựa chọn khác.
Đầu ra:
Bạn bắt đầu ở nút gốc (độ sâu 0 trên 3, đỉnh của biểu đồ):
- Ở trên cùng, đó là xác suất sống sót tổng thể. Nó cho thấy tỷ lệ hành khách sống sót sau vụ tai nạn. 41% hành khách sống sót.
- Nút này hỏi liệu giới tính của hành khách có phải là nam hay không. Nếu có, thì bạn đi xuống nút con bên trái của thư mục gốc (độ sâu 2). 63 phần trăm là nam giới với xác suất sống sót là 21 phần trăm.
- Ở nút thứ hai, bạn hỏi liệu hành khách nam trên 3,5 tuổi. Nếu có, thì cơ hội sống sót là 19 phần trăm.
- Bạn cứ tiếp tục như vậy để hiểu những tính năng nào ảnh hưởng đến khả năng sống sót.
Lưu ý rằng, một trong nhiều phẩm chất của Cây quyết định là chúng yêu cầu rất ít chuẩn bị dữ liệu. Đặc biệt, chúng không yêu cầu tính năng mở rộng hoặc căn giữa.
Theo mặc định, hàm rpart () sử dụng thước đo tạp chất Gini để tách nốt. Hệ số Gini càng cao, càng có nhiều cá thể khác nhau trong nút.
Bước 5) Đưa ra dự đoán
Bạn có thể dự đoán tập dữ liệu thử nghiệm của mình. Để đưa ra dự đoán, bạn có thể sử dụng hàm dự đoán (). Cú pháp cơ bản của dự đoán cho cây quyết định R là:
predict(fitted_model, df, type = 'class')arguments:- fitted_model: This is the object stored after model estimation.- df: Data frame used to make the prediction- type: Type of prediction- 'class': for classification- 'prob': to compute the probability of each class- 'vector': Predict the mean response at the node level
Bạn muốn dự đoán hành khách nào có nhiều khả năng sống sót sau vụ va chạm từ bộ thử nghiệm. Nó có nghĩa là, bạn sẽ biết trong số 209 hành khách đó, ai sẽ sống sót hay không.
predict_unseen <-predict(fit, data_test, type = 'class')
Giải thích mã
- dự đoán (fit, data_test, type = 'class'): Dự đoán lớp (0/1) của tập kiểm tra
Kiểm tra hành khách không vượt qua được và những người đã làm.
table_mat <- table(data_test$survived, predict_unseen)table_mat
Giải thích mã
- table (data_test $ survival, dự đoán_unseen): Tạo một bảng để đếm số lượng hành khách được phân loại là người sống sót và đã qua đời so với phân loại cây quyết định chính xác trong R
Đầu ra:
## predict_unseen## No Yes## No 106 15## Yes 30 58
Mô hình đã dự đoán chính xác 106 hành khách thiệt mạng nhưng phân loại 15 người sống sót là đã chết. Bằng cách tương tự, mô hình đã phân loại nhầm 30 hành khách là những người sống sót trong khi hóa ra họ đã chết.
Bước 6) Đo lường hiệu suất
Bạn có thể tính toán thước đo độ chính xác cho nhiệm vụ phân loại với ma trận nhầm lẫn :
Các ma trận nhầm lẫn là một lựa chọn tốt hơn để đánh giá việc thực hiện phân loại. Ý tưởng chung là đếm số lần các trường hợp Đúng được phân loại là Sai.
Mỗi hàng trong ma trận nhầm lẫn đại diện cho một mục tiêu thực tế, trong khi mỗi cột đại diện cho một mục tiêu dự đoán. Hàng đầu tiên của ma trận này coi hành khách đã chết (hạng Sai): 106 người được phân loại chính xác là đã chết ( Đúng âm ), trong khi người còn lại được phân loại sai là người sống sót ( Sai dương tính ). Hàng thứ hai xem xét những người sống sót, lớp tích cực là 58 ( True positive ), trong khi True âm là 30.
Bạn có thể tính toán kiểm tra độ chính xác từ ma trận nhầm lẫn:
Nó là tỷ lệ của đúng dương và âm thực trên tổng của ma trận. Với R, bạn có thể viết mã như sau:
accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
Giải thích mã
- sum (Diag (table_mat)): Tổng của đường chéo
- sum (table_mat): Tổng của ma trận.
Bạn có thể in độ chính xác của bộ thử nghiệm:
print(paste('Accuracy for test', accuracy_Test))
Đầu ra:
## [1] "Accuracy for test 0.784688995215311"
Bạn có 78 phần trăm điểm cho bộ kiểm tra. Bạn có thể sao chép cùng một bài tập với tập dữ liệu đào tạo.
Bước 7) Điều chỉnh các siêu tham số
Cây quyết định trong R có các tham số khác nhau kiểm soát các khía cạnh của sự phù hợp. Trong thư viện cây quyết định rpart, bạn có thể kiểm soát các tham số bằng cách sử dụng hàm rpart.control (). Trong đoạn mã sau, bạn giới thiệu các thông số bạn sẽ điều chỉnh. Bạn có thể tham khảo họa tiết để biết các thông số khác.
rpart.control(minsplit = 20, minbucket = round(minsplit/3), maxdepth = 30)Arguments:-minsplit: Set the minimum number of observations in the node before the algorithm perform a split-minbucket: Set the minimum number of observations in the final note i.e. the leaf-maxdepth: Set the maximum depth of any node of the final tree. The root node is treated a depth 0
Chúng tôi sẽ tiến hành như sau:
- Xây dựng hàm để trả về độ chính xác
- Điều chỉnh độ sâu tối đa
- Điều chỉnh số lượng mẫu tối thiểu mà một nút phải có trước khi nó có thể tách
- Điều chỉnh số lượng mẫu tối thiểu mà một nút lá phải có
Bạn có thể viết một hàm để hiển thị độ chính xác. Bạn chỉ cần bọc mã bạn đã sử dụng trước đây:
- dự đoán: dự đoán_unseen <- dự đoán (phù hợp, data_test, type = 'class')
- Sản xuất bảng: table_mat <- table (data_test $ còn sót lại, dự đoán_unseen)
- Tính chính xác: precision_Test <- sum (Diag (table_mat)) / sum (table_mat)
accuracy_tune <- function(fit) {predict_unseen <- predict(fit, data_test, type = 'class')table_mat <- table(data_test$survived, predict_unseen)accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)accuracy_Test}
Bạn có thể thử điều chỉnh các thông số và xem liệu bạn có thể cải thiện mô hình so với giá trị mặc định hay không. Xin nhắc lại, bạn cần có độ chính xác cao hơn 0,78
control <- rpart.control(minsplit = 4,minbucket = round(5 / 3),maxdepth = 3,cp = 0)tune_fit <- rpart(survived~., data = data_train, method = 'class', control = control)accuracy_tune(tune_fit)
Đầu ra:
## [1] 0.7990431
Với thông số sau:
minsplit = 4minbucket= round(5/3)maxdepth = 3cp=0
Bạn nhận được hiệu suất cao hơn so với mô hình trước đó. Xin chúc mừng!
Tóm lược
Chúng ta có thể tóm tắt các hàm để huấn luyện thuật toán cây quyết định trong R
Thư viện |
Mục tiêu |
chức năng |
lớp học |
thông số |
chi tiết |
---|---|---|---|---|---|
rpart |
Đào tạo cây phân loại trong R |
rpart () |
lớp học |
công thức, df, phương pháp | |
rpart |
Đào tạo cây hồi quy |
rpart () |
anova |
công thức, df, phương pháp | |
rpart |
Vẽ cây |
rpart.plot () |
mô hình vừa vặn | ||
căn cứ |
dự đoán |
dự đoán () |
lớp học |
mô hình phù hợp, loại | |
căn cứ |
dự đoán |
dự đoán () |
thăm dò |
mô hình phù hợp, loại | |
căn cứ |
dự đoán |
dự đoán () |
vectơ |
mô hình phù hợp, loại | |
rpart |
thông số điều khiển |
rpart.control () |
minsplit |
Đặt số lượng quan sát tối thiểu trong nút trước khi thuật toán thực hiện tách |
|
minbucket |
Đặt số lượng quan sát tối thiểu trong nốt cuối cùng, tức là lá |
||||
maxdepth |
Đặt độ sâu tối đa của bất kỳ nút nào của cây cuối cùng. Nút gốc được coi là độ sâu 0 |
||||
rpart |
Mô hình đào tạo với tham số điều khiển |
rpart () |
công thức, df, phương pháp, điều khiển |
Lưu ý: Huấn luyện mô hình trên dữ liệu huấn luyện và kiểm tra hiệu suất trên tập dữ liệu không nhìn thấy, tức là tập thử nghiệm.