# Load thư viện tree
library(tree)
# Load thư viện ISLR
library(ISLR)
Attaching package: 㤼㸱ISLR㤼㸲
The following object is masked _by_ 㤼㸱.GlobalEnv㤼㸲:
Carseats
# Đính kèm tập dữ liệu Carseats có 400 dòng và 11 cột
Carseats= ISLR::Carseats
# Tìm hiểu tập dữ liệu Carseats
?Carseats
# attach dùng để khiến cho tập dữ liệu Carseats Rstudio theo tên
attach(Carseats)
# Tạo ra biến high nhận giá trị = 'Yes' nếu Sales > 8, = 'No' nếu Sales <=8
High=ifelse(Sales<=8,"No","Yes")
# CHèn biến High vào tập dữ liệu Carseats
Carseats = data.frame(Carseats , High)
# Hàm tree dùng để tạo ra cây phân loại giúp dự đoán giá trị đầu ra là biến High và sử dụng tất cả các biến còn lại trừ biến Sales làm giá trị đầu vào trong dữ liệu Carseats
tree.carseats=tree(High~.-Sales,Carseats )
# Phân tích dữ liệu cây phân loại vừa được tạo
summary(tree.carseats)
Classification tree:
tree(formula = High ~ . - Sales, data = Carseats)
Variables actually used in tree construction:
[1] "ShelveLoc" "Price" "Income" "CompPrice" "Population" "Advertising" "Age" "US"
Number of terminal nodes: 27
Residual mean deviance: 0.4575 = 170.7 / 373
Misclassification error rate: 0.09 = 36 / 400
Hàm summary liệt kê các biến internal nodes trong cây bao gồm các biến : “ShelveLoc” “Price” “Income” “CompPrice” “Population” “Advertising” “Age” “US”, cho biết số lượng terminal nodes = 27, độ lệch chuẩn trung bình = 0.4575, tỉ lệ sai số huấn luyện = 0.09
# Chuyển thuộc tính biến high thành dạng factor
Carseats$High = as.factor(Carseats$High)
# Hiển thị thuộc tính của biến High
class(Carseats$High)
[1] "factor"
# Hiển thị tập dữ liệu Carseats dưới dạng bảng tính
fix(Carseats)
# Chuyển thuộc tính biến Urban thành dạng factor
Carseats$Urban = as.factor(Carseats$Urban)
# Hiển thị cấu trúc cây
plot(tree.carseats)
# Hiển thị nhãn tên các node của cây, biến pretty = 0 là để bao gồm tên loại cho bất cứ giá trị định tính nào so với việc chỉ hiển thị các kí tự chữ cái cho mỗi loại
text(tree.carseats,pretty=0)
# Hiển thị kết quả output tương ứng với mỗi nhánh của cây
tree.carseats
node), split, n, deviance, yval, (yprob)
* denotes terminal node
1) root 400 541.500 No ( 0.59000 0.41000 )
2) ShelveLoc: Bad,Medium 315 390.600 No ( 0.68889 0.31111 )
4) Price < 92.5 46 56.530 Yes ( 0.30435 0.69565 )
8) Income < 57 10 12.220 No ( 0.70000 0.30000 )
16) CompPrice < 110.5 5 0.000 No ( 1.00000 0.00000 ) *
17) CompPrice > 110.5 5 6.730 Yes ( 0.40000 0.60000 ) *
9) Income > 57 36 35.470 Yes ( 0.19444 0.80556 )
18) Population < 207.5 16 21.170 Yes ( 0.37500 0.62500 ) *
19) Population > 207.5 20 7.941 Yes ( 0.05000 0.95000 ) *
5) Price > 92.5 269 299.800 No ( 0.75465 0.24535 )
10) Advertising < 13.5 224 213.200 No ( 0.81696 0.18304 )
20) CompPrice < 124.5 96 44.890 No ( 0.93750 0.06250 )
40) Price < 106.5 38 33.150 No ( 0.84211 0.15789 )
80) Population < 177 12 16.300 No ( 0.58333 0.41667 )
160) Income < 60.5 6 0.000 No ( 1.00000 0.00000 ) *
161) Income > 60.5 6 5.407 Yes ( 0.16667 0.83333 ) *
81) Population > 177 26 8.477 No ( 0.96154 0.03846 ) *
41) Price > 106.5 58 0.000 No ( 1.00000 0.00000 ) *
21) CompPrice > 124.5 128 150.200 No ( 0.72656 0.27344 )
42) Price < 122.5 51 70.680 Yes ( 0.49020 0.50980 )
84) ShelveLoc: Bad 11 6.702 No ( 0.90909 0.09091 ) *
85) ShelveLoc: Medium 40 52.930 Yes ( 0.37500 0.62500 )
170) Price < 109.5 16 7.481 Yes ( 0.06250 0.93750 ) *
171) Price > 109.5 24 32.600 No ( 0.58333 0.41667 )
342) Age < 49.5 13 16.050 Yes ( 0.30769 0.69231 ) *
343) Age > 49.5 11 6.702 No ( 0.90909 0.09091 ) *
43) Price > 122.5 77 55.540 No ( 0.88312 0.11688 )
86) CompPrice < 147.5 58 17.400 No ( 0.96552 0.03448 ) *
87) CompPrice > 147.5 19 25.010 No ( 0.63158 0.36842 )
174) Price < 147 12 16.300 Yes ( 0.41667 0.58333 )
348) CompPrice < 152.5 7 5.742 Yes ( 0.14286 0.85714 ) *
349) CompPrice > 152.5 5 5.004 No ( 0.80000 0.20000 ) *
175) Price > 147 7 0.000 No ( 1.00000 0.00000 ) *
11) Advertising > 13.5 45 61.830 Yes ( 0.44444 0.55556 )
22) Age < 54.5 25 25.020 Yes ( 0.20000 0.80000 )
44) CompPrice < 130.5 14 18.250 Yes ( 0.35714 0.64286 )
88) Income < 100 9 12.370 No ( 0.55556 0.44444 ) *
89) Income > 100 5 0.000 Yes ( 0.00000 1.00000 ) *
45) CompPrice > 130.5 11 0.000 Yes ( 0.00000 1.00000 ) *
23) Age > 54.5 20 22.490 No ( 0.75000 0.25000 )
46) CompPrice < 122.5 10 0.000 No ( 1.00000 0.00000 ) *
47) CompPrice > 122.5 10 13.860 No ( 0.50000 0.50000 )
94) Price < 125 5 0.000 Yes ( 0.00000 1.00000 ) *
95) Price > 125 5 0.000 No ( 1.00000 0.00000 ) *
3) ShelveLoc: Good 85 90.330 Yes ( 0.22353 0.77647 )
6) Price < 135 68 49.260 Yes ( 0.11765 0.88235 )
12) US: No 17 22.070 Yes ( 0.35294 0.64706 )
24) Price < 109 8 0.000 Yes ( 0.00000 1.00000 ) *
25) Price > 109 9 11.460 No ( 0.66667 0.33333 ) *
13) US: Yes 51 16.880 Yes ( 0.03922 0.96078 ) *
7) Price > 135 17 22.070 No ( 0.64706 0.35294 )
14) Income < 46 6 0.000 No ( 1.00000 0.00000 ) *
15) Income > 46 11 15.160 Yes ( 0.45455 0.54545 ) *
R hiển thị những tiêu chuẩn chia các nhánh cây (ví dụ như Price < 92.5), số lượng quan sát trong nhánh (ở nhánh Price là = 46), tiếp theo là độ lệch chuẩn, kết quả dự đoán của các nhánh (Yes hoặc No), tỉ lệ số quan sát trong các nhánh mang giá trị là Yes và No (ở nhánh Price có 0.30435 % quan sát mang giá trị Yes, 0.69565 % quan sát mang giá trị No), các nhánh mà dẫn đến terminal nodes được đánh dấu ’*’
# set.seed dùng để tái tạo những vector random giống nhau theo tương ứng với giá trị được đưa vào hàm seed
set.seed(2)
# Sử dụng 200 dòng ngẫu nhiên của dữ liệu Carseats làm tập train, biến train là một vector chứa 200 giá trị tương ứng với số dòng được lấy ngẫu nhiên trong dữ liệu ban đầu
train=sample(1:nrow(Carseats), 200)
# Sử dụng 200 dòng còn lại để làm tập Test
Carseats.test=Carseats[-train,]
# Trích xuất kết quả giá trị label thật của tập test
High.test=High[-train]
# Hàm tree dùng để tạo ra cây phân loại giúp dự đoán giá trị đầu ra là biến High và sử dụng tất cả các biến còn lại trừ biến Sales làm giá trị đầu vào trong dữ liệu tập train
tree.carseats=tree(High~.-Sales,Carseats,subset=train)
# Hàm predict được sử dụng để đưa ra dự đoán trên tập test, type = "class" dùng để trả về lớp dự đoán thật
tree.pred=predict(tree.carseats,Carseats.test,type="class")
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(tree.pred,High.test)
High.test
tree.pred No Yes
No 104 33
Yes 13 50
Tỉ lệ số lượng quan sát được phân loại đúng trong tập test là : (104+50)/200 = 0.77
# Thực hiện cắt tỉa cây để cải tiến kết quả
# set.seed dùng để tái tạo những vector random giống nhau theo tương ứng với giá trị được đưa vào hàm seed
set.seed(3)
# # Hàm cv.tree thực hiện cross-validation để quyết định độ phức tạp tối ưu cho cây.
cv.carseats=cv.tree (tree.carseats,FUN=prune.misclass)
names(cv.carseats)
[1] "size" "dev" "k" "method"
FUN=prune.misclass dùng để xác định rõ là muốn sai số phân loại sai làm được áp dụng cho cross-validation và quá trình cắt tỉa, so với giá trị mặc định của hàm là dùng độ lệch chuẩn (deviance).
#Hàm cv.tree() cho biết số lượng terminal nodes của mỗi cây, cũng như là tỉ lệ phân loại lỗi và giá trị của tham số chi phí phức (k) được sử dụng
cv.carseats
$size
[1] 21 19 14 9 8 5 3 2 1
$dev
[1] 74 76 81 81 75 77 78 85 81
$k
[1] -Inf 0.0 1.0 1.4 2.0 3.0 4.0 9.0 18.0
$method
[1] "misclass"
attr(,"class")
[1] "prune" "tree.sequence"
Chúng ta thấy rằng với 9 terminal nodes thì sai số lỗi cross-validation ra được là thấp nhất
#Biểu đồ phân tán của các biến dữ liệu với các dữ liệu cột được chia thành cửa sổ 1x2 bằng cách sử dụng hàm mfrow=c(1,2)
par(mfrow=c(1,2))
# Hiển thị đồ thị phân tán với x là số lượng terminal nodes và y là sai số lỗi cross validation
plot(cv.carseats$size ,cv.carseats$dev,type = "b")
# Hiển thị đồ thị phân tán với x là tham số chi phí phức tạp và y là sai số lỗi cross validation
plot(cv.carseats$k,cv.carseats$dev,type = "b")
# Sử dụng hàm prune.misclass() để tỉa cây cho cây còn lại 9 nodes
prune.carseats = prune.misclass(tree.carseats, best=9)
# Hiển thị cấu trúc cây đã được tỉa
plot(prune.carseats)
# Hiển thị nhãn tên các node của cây, biến pretty = 0 là để bao gồm tên loại cho bất cứ giá trị định tính nào so với việc chỉ hiển thị các kí tự chữ cái cho mỗi loại
text(prune.carseats, pretty=0)
# Đưa ra dự đoán trên cây đã được tỉa
tree.pred=predict(prune.carseats,Carseats.test,type="class")
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(tree.pred,High.test)
High.test
tree.pred No Yes
No 97 25
Yes 20 58
Tỉ lệ số lượng quan sát được phân loại đúng trong tập test là : (97+58)/200 = 0.775
# Tiếp tục thực hiện cắt tỉa cây để tăng số node lên 15
prune.carseats = prune.misclass (tree.carseats ,best = 15)
# Hiển thị cấu trúc cây đã được tỉa lên số node = 15
plot(prune.carseats)
# Hiển thị nhãn tên các node của cây, biến pretty = 0 là để bao gồm tên loại cho bất cứ giá trị định tính nào so với việc chỉ hiển thị các kí tự chữ cái cho mỗi loại
text(prune.carseats,pretty=0)
# Đưa ra dự đoán trên cây đã được tỉa lên node = 15
tree.pred=predict(prune.carseats,Carseats.test,type="class")
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(tree.pred,High.test)
High.test
tree.pred No Yes
No 102 30
Yes 15 53
Tỉ lệ số lượng quan sát được phân loại đúng trong tập test là : (102+53)/200 = 0.775
# Load thư viện Mass
library(MASS)
# set.seed dùng để tái tạo những vector random giống nhau theo tương ứng với giá trị được đưa vào hàm seed
set.seed (1)
# CHia random tập train với số lượng quan sát được chia đôi trong dữ liệu Boston
train = sample(1:nrow(Boston), nrow(Boston)/2)
# Hàm tree dùng để tạo ra cây phân loại giúp dự đoán giá trị đầu ra là biến medv và sử dụng tất cả các biến còn lại giá trị đầu vào trong dữ liệu Boston
tree.boston=tree(medv~.,Boston,subset=train)
# Phân tích dữ liệu cây phân loại vừa được tạo
summary(tree.boston)
Regression tree:
tree(formula = medv ~ ., data = Boston, subset = train)
Variables actually used in tree construction:
[1] "rm" "lstat" "crim" "age"
Number of terminal nodes: 7
Residual mean deviance: 10.38 = 2555 / 246
Distribution of residuals:
Min. 1st Qu. Median Mean 3rd Qu. Max.
-10.1800 -1.7770 -0.1775 0.0000 1.9230 16.5800
Hàm summary liệt kê các biến internal nodes trong cây bao gồm các biến : “rm” “lstat” “crim” “age”, cho biết số lượng terminal nodes = 7, độ lệch chuẩn trung bình = 10.38 được tính thông qua tổng bình phương các lỗi của cây
Ngoài còn cho biết giá trị min, max , trung vị, tỉ lệ 25%, 75 % của sai số lỗi cho các nhánh
# Hiển thị cấu trúc cây đã được tạo
plot(tree.boston)
# Hiển thị nhãn tên các node của cây, biến pretty = 0 là để bao gồm tên loại cho bất cứ giá trị định tính nào so với việc chỉ hiển thị các kí tự chữ cái cho mỗi loại
text(tree.boston,pretty=0)
# Hàm cv.tree thực hiện cross-validation để quyết định độ phức tạp tối ưu cho cây.
cv.boston=cv.tree(tree.boston)
# Hiển thị đồ thị phân tán với x là số lượng terminal nodes và y là sai số lỗi cross validation
plot(cv.boston$size,cv.boston$dev,type="b")
# Cắt tỉa cây còn 5 nodes
prune.boston=prune.tree(tree.boston ,best=5)
# Hiển thị cấu trúc cây đã được tỉa còn 5 nodes
plot(prune.boston)
# Hiển thị nhãn tên các node của cây, biến pretty = 0 là để bao gồm tên loại cho bất cứ giá trị định tính nào so với việc chỉ hiển thị các kí tự chữ cái cho mỗi loại
text(prune.boston,pretty=0)
# Dự đoán trên tập test bao gồm các quan sát còn lại khác với tập train của cây còn 5 nodes
yhat=predict (tree.boston ,newdata=Boston[-train ,])
# Trích xuất kết quả giá trị output medv thật của tập test
boston.test = Boston[-train , "medv"]
# Hiển thị biểu đồ phân tán với cột x là giá trị được dự đoán và cột y là giá trị thật của tập test
plot(yhat,boston.test)
# Thêm 1 đường thẳng nối qua các điểm phân tán
abline(0 , 1)
# Tính Mean Squared Error (MSE) của cây hồi quy
mean((yhat -boston.test)^2)
[1] 35.28688
MSE của tập test = 35.28688, nên Root Mean Squared Error(RMSE) là khoảng 5.94