Giới thiệu

Trong thế giới tự nhiên, nấm là một sinh vật vừa quen thuộc vừa bí ẩn, vừa là nguồn thực phẩm dinh dưỡng, vừa là cạm bẫy chết người. Ranh giới giữa một bữa ăn ngon và một ca ngộ độc đôi khi rất mong manh, phụ thuộc vào kinh nghiệm và kiến thức nhận dạng. Trong thời đại số, khoa học dữ liệu mở ra một cách tiếp cận mới: sử dụng các thuật toán và thống kê để “giải mã” những quy luật ẩn sau các đặc điểm hình thái, từ đó xây dựng những phương pháp phân loại đáng tin cậy.

Báo cáo này sẽ thực hiện một cuộc “điều tra” chuyên sâu trên bộ dữ liệu “Mushroom Classification” nổi tiếng. Chúng ta sẽ theo đuổi hai mục tiêu chính:

  1. Dự báo độc tính: Đâu là những “dấu hiệu vàng” giúp cảnh báo một cây nấm là độc?

  2. Dự báo Môi trường sống: Liệu hình dáng, màu sắc, mùi hương có thể tiết lộ nơi một cây nấm ưa thích sinh sống?

1 Đọc và tổng quan về bộ dữ liệu

1.1 Đọc file dữ liệu Mushroom

data <- read.csv("D:/PTDLDT/Mushroom.csv", header = T)
datatable(data)

1.2 Tổng quan về bộ dữ liệu

Bộ dữ liệu Mushroom bao gồm 8124 quan sát và 23 biến, trong đó biến class là biến mục tiêu (‘p’ cho poisonous - độc, ‘e’ cho edible - ăn được) và 22 biến còn lại mô tả các đặc điểm vật lý của nấm. Đáng chú ý, tất cả các biến này đều là biến định tính.

1.2.1 Danh sách các biến và ý nghĩa

Dưới đây là bảng mô tả ý nghĩa của một số biến chính trong bộ dữ liệu.

Bảng mô tả chi tiết tất cả các biến trong bộ dữ liệu Mushroom
STT Tên biến Mô tả Các giá trị và ý nghĩa
1 class Loại nấm (Biến mục tiêu) e=edible (ăn được), p=poisonous (độc)
2 cap.shape Hình dạng mũ nấm b=bell (hình chuông), c=conical (hình nón), x=convex (lồi), f=flat (phẳng), k=knobbed (có núm), s=sunken (lõm)
3 cap.surface Bề mặt mũ nấm f=fibrous (dạng sợi), g=grooves (có rãnh), y=scaly (có vảy), s=smooth (mịn)
4 cap.color Màu sắc mũ nấm n=brown (nâu), b=buff (da bò), c=cinnamon (quế), g=gray (xám), r=green (xanh lá), p=pink (hồng), u=purple (tím), e=red (đỏ), w=white (trắng), y=yellow (vàng)
5 bruises Có bị thâm khi va chạm? t=bruises (có), f=no (không)
6 odor Mùi của nấm a=almond (hạnh nhân), l=anise (hồi), c=creosote (dầu creosote), y=fishy (tanh), f=foul (hôi), m=musty (mốc), n=none (không mùi), p=pungent (hăng), s=spicy (cay)
7 gill.attachment Cách phiến nấm gắn vào thân a=attached (gắn liền), d=descending (chạy xuống), f=free (tự do), n=notched (có khía)
8 gill.spacing Khoảng cách giữa các phiến nấm c=close (gần nhau), w=crowded (chật chội), d=distant (thưa)
9 gill.size Kích thước phiến nấm b=broad (rộng), n=narrow (hẹp)
10 gill.color Màu sắc phiến nấm k=black (đen), n=brown (nâu), b=buff (da bò), h=chocolate (sô-cô-la), g=gray (xám), o=orange (cam), p=pink (hồng), r=green (xanh lá), u=purple (tím), e=red (đỏ), w=white (trắng), y=yellow (vàng)
11 stalk.shape Hình dạng thân nấm e=enlarging (phình ra),t=tapering (thon lại)
12 stalk.root Gốc thân nấm b=bulbous (hình củ), c=club (hình dùi cui), u=cup (hình chén), e=equal (đều), z=rhizomorphs (dạng rễ giả), r=rooted (có rễ)
13 stalk.surface.above.ring Bề mặt thân nấm (phía trên vành) f=fibrous (dạng sợi), y=scaly (có vảy), k=silky (mượt như lụa), s=smooth (mịn)
14 stalk.surface.below.ring Bề mặt thân nấm (phía dưới vành) f=fibrous (dạng sợi), y=scaly (có vảy), k=silky (mượt như lụa), s=smooth (mịn)
15 stalk.color.above.ring Màu sắc thân nấm (phía trên vành) n=brown (nâu), b=buff (da bò), c=cinnamon (quế), g=gray (xám), o=orange (cam), p=pink (hồng), e=red (đỏ), w=white (trắng), y=yellow (vàng)
16 stalk.color.below.ring Màu sắc thân nấm (phía dưới vành) n=brown (nâu), b=buff (da bò), c=cinnamon (quế), g=gray (xám), o=orange (cam), p=pink (hồng), e=red (đỏ), w=white (trắng), y=yellow (vàng)
17 veil.type Loại màng che (Veil) p=partial (một phần), u=universal (toàn phần)
18 veil.color Màu sắc màng che n=brown (nâu), o=orange (cam), w=white (trắng), y=yellow (vàng)
19 ring.number Số lượng vành nấm n=none (không có), o=one (một), t=two (hai)
20 ring.type Loại vành nấm c=cobwebby (dạng mạng nhện), e=evanescent (dễ rụng), f=flaring (loe ra), l=large (lớn), n=none (không có), p=pendant (treo lủng lẳng), s=sheathing (dạng bao), z=zone (vân)
21 spore.print.color Màu sắc của bào tử k=black (đen), n=brown (nâu), b=buff (da bò), h=chocolate (sô-cô-la), r=green (xanh lá), o=orange (cam), u=purple (tím), w=white (trắng), y=yellow (vàng)
22 population Sự phân bố, quần thể a=abundant (dồi dào), c=clustered (mọc cụm), n=numerous (số lượng lớn), s=scattered (rải rác), v=several (vài cây), y=solitary (mọc đơn)
23 habitat Môi trường sống g=grasses (trên cỏ), l=leaves (trên lá), m=meadows (đồng cỏ), p=paths (lối đi), u=urban (đô thị), w=waste (bãi rác), d=woods (trong rừng)

1.2.2 Cấu trúc bộ dữ liệu

Để có được cái nhìn tổng quan và bước đầu đánh giá tính phù hợp của tập dữ liệu với mục tiêu nghiên cứu, ta tiến hành kiểm tra cấu trúc của bộ dữ liệu bằng cách sử dụng hai hàm cơ bản trong R là dim()str().

  • Hàm dim() cho biết kích thước của bảng dữ liệu, cụ thể là số hàng (quan sát) và số cột (biến).
dim(data)
## [1] 8124   23

Bộ dữ liệu có 8124 quan sát (mẫu nấm) và 23 biến (đặc điểm). Đây là một bộ dữ liệu có kích thước đủ lớn để thực hiện các phân tích thống kê có ý nghĩa.

  • Hàm str() cung cấp thông tin về cấu trúc dữ liệu, bao gồm tên các biến, kiểu dữ liệu của từng biến (ví dụ: số, chuỗi ký tự, biến phân loại), cũng như một số giá trị minh họa cho mỗi biến.
str(data)
## 'data.frame':    8124 obs. of  23 variables:
##  $ class                   : chr  "p" "e" "e" "p" ...
##  $ cap.shape               : chr  "x" "x" "b" "x" ...
##  $ cap.surface             : chr  "s" "s" "s" "y" ...
##  $ cap.color               : chr  "n" "y" "w" "w" ...
##  $ bruises                 : chr  "t" "t" "t" "t" ...
##  $ odor                    : chr  "p" "a" "l" "p" ...
##  $ gill.attachment         : chr  "f" "f" "f" "f" ...
##  $ gill.spacing            : chr  "c" "c" "c" "c" ...
##  $ gill.size               : chr  "n" "b" "b" "n" ...
##  $ gill.color              : chr  "k" "k" "n" "n" ...
##  $ stalk.shape             : chr  "e" "e" "e" "e" ...
##  $ stalk.root              : chr  "e" "c" "c" "e" ...
##  $ stalk.surface.above.ring: chr  "s" "s" "s" "s" ...
##  $ stalk.surface.below.ring: chr  "s" "s" "s" "s" ...
##  $ stalk.color.above.ring  : chr  "w" "w" "w" "w" ...
##  $ stalk.color.below.ring  : chr  "w" "w" "w" "w" ...
##  $ veil.type               : chr  "p" "p" "p" "p" ...
##  $ veil.color              : chr  "w" "w" "w" "w" ...
##  $ ring.number             : chr  "o" "o" "o" "o" ...
##  $ ring.type               : chr  "p" "p" "p" "p" ...
##  $ spore.print.color       : chr  "k" "n" "n" "k" ...
##  $ population              : chr  "s" "n" "n" "s" ...
##  $ habitat                 : chr  "u" "g" "m" "u" ...

Tất cả các biến hiện đang ở dạng ký tự (chr). Để R có thể phân tích chúng dưới dạng biến định tính, chúng ta cần chuyển đổi chúng sang kiểu factor.

1.3 Kiểm tra và xử lý dữ liệu thiếu (NA)

Dữ liệu trong thực tế thường không hoàn hảo. Một số nguồn tài liệu cho biết giá trị bị thiếu trong bộ dữ liệu này được ký hiệu là ‘?’. Chúng ta cần kiểm tra và xử lý chúng.

# Sử dụng hàm na_if() kết hợp với across() để thay thế '?' một cách an toàn.
mushroom_df_processed <- data %>%
  dplyr::mutate(dplyr::across(everything(), ~na_if(., "?")))

# Đếm số lượng giá trị NA trong mỗi cột
na_counts <- colSums(is.na(mushroom_df_processed))

# Lấy ra những cột có chứa giá trị NA (số lượng NA > 0)
cols_with_na <- na_counts[na_counts > 0]

# In ra kết quả kiểm tra
if (length(cols_with_na) > 0) {
  cat("\nPhát hiện các giá trị NA trong các cột sau:\n")
  print(cols_with_na)
} else {
  cat("\nKhông tìm thấy giá trị NA nào trong bộ dữ liệu.\n")
}
## 
## Phát hiện các giá trị NA trong các cột sau:
## stalk.root 
##       2480
# XỬ LÝ NA BẰNG PHƯƠNG PHÁP THAY THẾ BẰNG MODE

# Hàm để tìm mode (giá trị phổ biến nhất) của một vector
get_mode <- function(v) {
  # Loại bỏ NA trước khi tìm mode để không bị lỗi
  v_without_na <- na.omit(v)
  # Tìm giá trị duy nhất và đếm tần suất của chúng
  uniqv <- unique(v_without_na)
  # Trả về giá trị có tần suất cao nhất
  uniqv[which.max(tabulate(match(v_without_na, uniqv)))]
}

# Áp dụng thay thế NA bằng mode cho cột 'stalk.root'
# (Dựa vào kết quả ở trên, chúng ta biết chỉ cột này có NA)
cat("\nThực hiện thay thế giá trị NA trong cột 'stalk.root' bằng mode...\n")
## 
## Thực hiện thay thế giá trị NA trong cột 'stalk.root' bằng mode...
mode_stalk_root <- get_mode(mushroom_df_processed$stalk.root)
cat("Giá trị mode của cột 'stalk.root' là:", mode_stalk_root, "\n")
## Giá trị mode của cột 'stalk.root' là: b
# Thực hiện việc thay thế
mushroom_df_processed$stalk.root[is.na(mushroom_df_processed$stalk.root)] <- mode_stalk_root

# Đếm lại tổng số NA trong toàn bộ data frame để xác nhận
final_na_count <- sum(is.na(mushroom_df_processed))

cat("\nKiểm tra lại sau khi xử lý...\n")
## 
## Kiểm tra lại sau khi xử lý...
cat("Tổng số giá trị NA còn lại trong bộ dữ liệu:", final_na_count, "\n")
## Tổng số giá trị NA còn lại trong bộ dữ liệu: 0
if (final_na_count == 0) {
  cat("=> Xử lý dữ liệu thiếu thành công!\n")
} else {
  cat("=> CẢNH BÁO: Vẫn còn giá trị NA trong dữ liệu!\n")
}
## => Xử lý dữ liệu thiếu thành công!

Nhận xét:

  • Chỉ có một cột duy nhất chứa giá trị thiếu là stalk.root với 2480 giá trị bị thiếu, chiếm khoảng 30.5% tổng số quan sát.

  • Việc loại bỏ các hàng này sẽ làm mất một lượng lớn dữ liệu. Thay vào đó, một chiến lược hợp lý là thay thế các giá trị thiếu bằng mode (giá trị xuất hiện nhiều nhất) của cột đó. Điều này giúp bảo toàn kích thước mẫu.

Kết quả: Dữ liệu đã được làm sạch, không còn giá trị thiếu.

1.4 Chuyển đổi dữ liệu sang factor

Để R hiểu đúng các biến là biến định tính, chúng ta chuyển đổi tất cả các cột sang kiểu factor.

# Chuyển đổi tất cả các cột sang factor
df <- mushroom_df_processed %>% mutate(across(everything(), as.factor))

# Kiểm tra lại cấu trúc sau khi chuyển đổi
str(df)
## 'data.frame':    8124 obs. of  23 variables:
##  $ class                   : Factor w/ 2 levels "e","p": 2 1 1 2 1 1 1 1 2 1 ...
##  $ cap.shape               : Factor w/ 6 levels "b","c","f","k",..: 6 6 1 6 6 6 1 1 6 1 ...
##  $ cap.surface             : Factor w/ 4 levels "f","g","s","y": 3 3 3 4 3 4 3 4 4 3 ...
##  $ cap.color               : Factor w/ 10 levels "b","c","e","g",..: 5 10 9 9 4 10 9 9 9 10 ...
##  $ bruises                 : Factor w/ 2 levels "f","t": 2 2 2 2 1 2 2 2 2 2 ...
##  $ odor                    : Factor w/ 9 levels "a","c","f","l",..: 7 1 4 7 6 1 1 4 7 1 ...
##  $ gill.attachment         : Factor w/ 2 levels "a","f": 2 2 2 2 2 2 2 2 2 2 ...
##  $ gill.spacing            : Factor w/ 2 levels "c","w": 1 1 1 1 2 1 1 1 1 1 ...
##  $ gill.size               : Factor w/ 2 levels "b","n": 2 1 1 2 1 1 1 1 2 1 ...
##  $ gill.color              : Factor w/ 12 levels "b","e","g","h",..: 5 5 6 6 5 6 3 6 8 3 ...
##  $ stalk.shape             : Factor w/ 2 levels "e","t": 1 1 1 1 2 1 1 1 1 1 ...
##  $ stalk.root              : Factor w/ 4 levels "b","c","e","r": 3 2 2 3 3 2 2 2 3 2 ...
##  $ stalk.surface.above.ring: Factor w/ 4 levels "f","k","s","y": 3 3 3 3 3 3 3 3 3 3 ...
##  $ stalk.surface.below.ring: Factor w/ 4 levels "f","k","s","y": 3 3 3 3 3 3 3 3 3 3 ...
##  $ stalk.color.above.ring  : Factor w/ 9 levels "b","c","e","g",..: 8 8 8 8 8 8 8 8 8 8 ...
##  $ stalk.color.below.ring  : Factor w/ 9 levels "b","c","e","g",..: 8 8 8 8 8 8 8 8 8 8 ...
##  $ veil.type               : Factor w/ 1 level "p": 1 1 1 1 1 1 1 1 1 1 ...
##  $ veil.color              : Factor w/ 4 levels "n","o","w","y": 3 3 3 3 3 3 3 3 3 3 ...
##  $ ring.number             : Factor w/ 3 levels "n","o","t": 2 2 2 2 2 2 2 2 2 2 ...
##  $ ring.type               : Factor w/ 5 levels "e","f","l","n",..: 5 5 5 5 1 5 5 5 5 5 ...
##  $ spore.print.color       : Factor w/ 9 levels "b","h","k","n",..: 3 4 4 3 4 3 3 4 3 3 ...
##  $ population              : Factor w/ 6 levels "a","c","n","s",..: 4 3 3 4 1 3 3 4 5 4 ...
##  $ habitat                 : Factor w/ 7 levels "d","g","l","m",..: 6 2 4 6 2 2 4 4 2 4 ...

Nhận xét: Tất cả các biến giờ đã có kiểu factor với các cấp độ (levels) tương ứng, sẵn sàng cho việc phân tích.

2 Phân tích mô tả một biến (Univariate Analysis)

Phần này tập trung vào việc hiểu phân phối của một vài đặc điểm nấm một cách riêng lẻ.

2.1 Biến class (Loại nấm)

Trước khi đi sâu vào các mối quan hệ phức tạp, chúng ta cần hiểu rõ sự phân bổ của biến quan trọng nhất: độc tính. Tỷ lệ nấm độc và nấm ăn được trong bộ dữ liệu này như thế nào?

df <- df %>%
  mutate(class_full = recode(class, "e" = "Ăn được","p" = "Độc"))

class_summary <- df %>%
  count(class_full) %>%
  mutate(Percentage = n / sum(n))

colnames(class_summary) <- c("Loại nấm", "Tần số", "Tần suất")

kable(class_summary, align = "c", booktabs = TRUE, digits = 2, caption = "Thống kê tần suất của các loại nấm") %>%
  kable_styling(full_width = FALSE, position = "center")
Thống kê tần suất của các loại nấm
Loại nấm Tần số Tần suất
Ăn được 4208 0.52
Độc 3916 0.48

Trực quan hoá

bar_plot <- ggplot(df, aes(x = class_full, fill = class_full)) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = 0, size = 3) +
  labs(title = "Phân bố loại nấm",
       x = "Loại",
       y = "Số lượng", fill = "Loại nấm") + 
  theme_minimal(base_size = 14) +
  scale_fill_manual(values = c("Ăn được" = "skyblue", "Độc" = "pink"))

class_p <- as.data.frame(table(df$class_full))
colnames(class_p) <- c("Category", "Count")

pie_plot <- ggplot(class_p, aes(x = "", y = Count, fill = Category)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start=0) +
labs(title = "Tỷ lệ nấm", fill = "Loại nấm") +
theme_void(base_size = 14) +
geom_text(aes(label = scales::percent(Count/sum(Count), accuracy = 0.0001)), position = position_stack(vjust = 0.5), size = 2.5)+scale_fill_manual(values = c("Ăn được" = "salmon", "Độc" = "#00BFC4"))

bar_plot + pie_plot

Nhận xét:

  • Bộ dữ liệu khá cân bằng. Nấm ăn được (edible - e) chiếm 51.8% (4208 mẫu), trong khi nấm độc (poisonous - p) chiếm 48.2% (3916 mẫu).

  • Sự cân bằng này là một lợi thế lớn, giúp các phân tích và mô hình sau này không bị thiên vị về một trong hai loại, đảm bảo rằng các quy luật chúng ta tìm thấy sẽ có giá trị cho cả hai nhóm.

2.2 Biến habitat (Môi trường sống)

Môi trường sống (habitat) là nơi nấm sinh trưởng và phát triển, tiết lộ nhiều thông tin về hệ sinh thái và nhu cầu dinh dưỡng của chúng. Một số loài nấm có mối quan hệ cộng sinh với các loài cây cụ thể, trong khi những loài khác phát triển trên gỗ mục, lá cây, hoặc trong đồng cỏ. Việc xác định môi trường sống là một bước quan trọng trong quy trình định danh nấm ngoài tự nhiên. Bộ dữ liệu phân loại môi trường sống thành: grasses (đồng cỏ), leaves (lá cây), meadows (bãi cỏ), paths (lối đi), urban (đô thị), waste (chất thải), và woods (rừng). Chúng ta hãy xem xét các môi trường sống phổ biến nhất trong bộ dữ liệu này.

# Tạo nhãn Tiếng Việt
habitat_labels <- c( "d" = "Trong rừng", "g" = "Trên cỏ", "l" = "Trên lá", "m" = "Đồng cỏ", "p" = "Lối đi", "u" = "Đô thị", "w" = "Bãi rác")
df$habitat_full <- factor(habitat_labels[df$habitat])

# Thống kê tần suất
habitat_summary <- df %>%
  count(habitat_full) %>%
  mutate(Percentage = (n / sum(n)))

kable(habitat_summary,
      col.names = c("Môi trường sống", "Tần số", "Tần suất"),
      align = "c", booktabs = TRUE,
      caption = "Thống kê tần suất môi trường sống của các loại nấm") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = T)
Thống kê tần suất môi trường sống của các loại nấm
Môi trường sống Tần số Tần suất
Bãi rác 192 0.0236337
Đô thị 368 0.0452979
Đồng cỏ 292 0.0359429
Lối đi 1144 0.1408173
Trên cỏ 2148 0.2644018
Trên lá 832 0.1024126
Trong rừng 3148 0.3874938

Trực quan hoá

ggplot(df, aes(x = fct_infreq(habitat_full), fill = fct_infreq(habitat_full))) +
  geom_bar() +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 3.5) +
  labs(title = "Phân bố môi trường sống của nấm", x = "Môi trường sống", y = "Số lượng", fill = "Môi trường sống") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét:

  • Biểu đồ cho thấy môi trường sống phổ biến nhất của các loài nấm trong bộ dữ liệu là trong rừng (woods - d), với 3148 mẫu. Điều này phản ánh thực tế rằng rừng là hệ sinh thái đa dạng và lý tưởng cho sự phát triển của nấm.

  • Đồng cỏ (grasses - g) cũng là một môi trường sống quan trọng, đứng thứ hai với 2148 mẫu.

  • Các môi trường như lối đi (paths - p), trên lá (leaves - l) và đô thị (urban - u) có tần suất thấp hơn nhưng vẫn đáng kể.

  • Môi trường sống trên chất thải (waste - w) và trên bãi cỏ (meadows - m) là hiếm gặp nhất. Việc một cây nấm mọc ở đâu có thể là một gợi ý mạnh mẽ về danh tính của nó, và có khả năng liên quan đến việc nó có độc hay không.

3 Ước lượng khoảng và kiểm định giả thuyết cho tỷ lệ

Phần này sử dụng các phương pháp thống kê suy luận để đưa ra kết luận về tổng thể từ dữ liệu mẫu. Đối với mỗi biến, chúng ta sẽ chọn một hạng mục quan tâm (thường là hạng mục phổ biến nhất) để thực hiện:

  1. Ước lượng khoảng tin cậy 95% cho tỷ lệ của hạng mục đó trong tổng thể.

  2. Kiểm định giả thuyết để xem liệu tỷ lệ thực tế của hạng mục đó có khác biệt so với một giá trị giả định hay không.

Phương pháp này giúp chúng ta hiểu rõ hơn về mức độ phổ biến của từng đặc điểm cụ thể.

3.1 Phân tích cho biến class và hạng mục quan tâm: p (Poisonous - Độc)

Chúng ta sẽ ước lượng khoảng tin cậy và kiểm định giả thuyết cho tỷ lệ nấm độc trong tổng thể.

# Lấy số lượng cho từng hạng mục
class_counts <- table(df$class)
total_mushrooms <- sum(class_counts)
cat("Tổng số lượng nấm:", total_mushrooms, "\n")
## Tổng số lượng nấm: 8124
poisonous_count <- class_counts["p"]
cat("Số lượng nấm độc:", poisonous_count, "\n")
## Số lượng nấm độc: 3916

Ước lượng khoảng tin cậy 95% cho tỷ lệ nấm độc

prop_test_poisonous <- prop.test(x = poisonous_count, n = total_mushrooms, conf.level = 0.95)
prop_test_poisonous$conf.int
## [1] 0.4711126 0.4929616
## attr(,"conf.level")
## [1] 0.95

Diễn giải: Với độ tin cậy 95%, chúng ta có thể kết luận rằng tỷ lệ thực sự của nấm độc trong tổng thể (mà mẫu này đại diện) nằm trong khoảng từ 47.1% đến 49.3%.

3.2 Phân tích Biến habitat (Môi trường sống) và hạng mục quan tâm: d (Woods - Trong rừng)

Chúng ta sẽ phân tích tỷ lệ nấm sinh sống trong rừng, môi trường phổ biến nhất.

habitat_counts <- table(df$habitat)
woods_habitat_count <- habitat_counts["g"]

cat("Tổng số lượng nấm:", total_mushrooms, "\n")
## Tổng số lượng nấm: 8124
cat("Số lượng nấm sống trong rừng:", woods_habitat_count, "\n")
## Số lượng nấm sống trong rừng: 2148

Ước lượng khoảng tin cậy 95% cho tỷ lệ nấm sống “Trong rừng”

prop_test_habitat <- prop.test(x = woods_habitat_count, n = total_mushrooms, conf.level = 0.95)
prop_test_habitat$conf.int
## [1] 0.2548640 0.2741637
## attr(,"conf.level")
## [1] 0.95

Diễn giải: Với độ tin cậy 95%, tỷ lệ thực sự của nấm sống trong rừng trong tổng thể được ước tính nằm trong khoảng từ 25.486% đến 27.41637%.

Kiểm định giả thuyết

Bài toán kiểm định: \[ \begin{cases} H_0 : p = 0.26 \quad (\text{Tỷ lệ nấm sống trong rừng trong tổng thể bằng 26%}) \\ H_1: p \neq 0.26 \quad (\text{Tỷ lệ nấm sống trong rừng trong tổng thể khác 26%}) \end{cases} \]

prop_test_habitat_H0 <- prop.test(x = woods_habitat_count, n = total_mushrooms, p = 0.26, alternative = "two.sided")
print(prop_test_habitat_H0)
## 
##  1-sample proportions test with continuity correction
## 
## data:  woods_habitat_count out of total_mushrooms, null probability 0.26
## X-squared = 0.79541, df = 1, p-value = 0.3725
## alternative hypothesis: true p is not equal to 0.26
## 95 percent confidence interval:
##  0.2548640 0.2741637
## sample estimates:
##         p 
## 0.2644018

Kết luận: Giá trị p-value = 0.37254, lớn hơn mức ý nghĩa α = 0.05. Do đó, chúng ta không đủ bằng chứng để bác bỏ giả thuyết \(H_0\). Tỷ lệ nấm sống trong rừng trong tổng thể bằng 26%.

4 Phân tích mối quan hệ giữa hai biến định tính (Bivariate Analysis)

Phần này là trọng tâm của báo cáo, tập trung vào việc phân tích mối quan hệ giữa các biến để trả lời hai câu hỏi nghiên cứu chính:

Câu hỏi 1 (Về độc tính): Những đặc điểm vật lý nào có mối liên hệ mạnh mẽ nhất với việc một cây nấm là độc hay ăn được?

Câu hỏi 2 (Về môi trường sống): Liệu các đặc điểm như mùi, màu sắc, hình dạng có thay đổi một cách có hệ thống theo từng môi trường sống khác nhau không?

Để trả lời các câu hỏi trên, chúng ta sẽ đi sâu vào phân tích từng cặp biến quan trọng, áp dụng một chuỗi các phương pháp từ mô tả (bảng tần số, biểu đồ) đến suy luận (kiểm định Chi-bình phương) để hiểu rõ bản chất của mỗi mối quan hệ.

Trước tiên, chúng ta sẽ tập trung vào Câu hỏi 1: Tìm kiếm các yếu tố dự báo độc tính. Chúng ta sẽ lần lượt kiểm tra các đặc điểm đáng ngờ nhất, bắt đầu bằng một trong những kinh nghiệm dân gian phổ biến nhất liên quan đến vết bầm của nấm.

4.1 Mối quan hệ giữa class và bruises

Câu hỏi nghiên cứu: Việc một cây nấm có vết bầm ảnh hưởng như thế nào đến khả năng nó là nấm độc?

Bảng tần số chéo và trực quan hóa

# Tạo bảng tần số
class_bruises_table <- table(df$bruises, df$class)

# Gán tên hàng
rownames(class_bruises_table) <- c("Không có vết bầm", "Có vết bầm")

# Hiển thị bảng với kable
kable(class_bruises_table,
      col.names = c("Ăn được", "Độc"),
      caption = "Bảng tần số giữa vết bầm và độc tính") %>%
  kable_styling(bootstrap_options = "striped", full_width = F)
Bảng tần số giữa vết bầm và độc tính
Ăn được Độc
Không có vết bầm 1456 3292
Có vết bầm 2752 624
# Trực quan hóa bằng biểu đồ cột nhóm
ggplot(df, aes(x = bruises, fill = class_full)) +
  geom_bar(position = "dodge") +
  geom_text(stat = "count", aes(label = after_stat(count)),
            position = position_dodge(width = 0.9), vjust = -0.2, size = 3) +
  labs(title = "Mối quan hệ giữa vết bầm và độc tính",
       x = "Có vết bầm (f: không, t: có)", y = "Số lượng", fill = "Loại nấm") +
  theme_minimal(base_size = 12)

Nhận xét:

  • Bảng và biểu đồ cho thấy một sự tương phản rõ rệt. Trong tổng số 4748 cây nấm không có vết bầm (f), có tới 3292 cây là nấm độc (chiếm một tỷ lệ áp đảo ~ 69%). Ngược lại, trong 3376 cây nấm có vết bầm (t), chỉ có 624 cây là nấm độc (chiếm ~ 18.5%).

  • Điều này gợi ý mạnh mẽ rằng việc có vết bầm là một đặc điểm liên quan đến nấm ăn được.

Kiểm định Chi-bình phương (Chi-squared Test)

Bài toán kiểm định: \[ \begin{cases} H_0: \text{Việc có vết bầm và độc tính của nấm là hai biến độc lập.}\\ H_1: \text{Việc có vết bầm và độc tính của nấm có sự liên quan.} \end{cases} \]

chisq.test(class_bruises_table)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  class_bruises_table
## X-squared = 2041.4, df = 1, p-value < 2.2e-16

Trong đó

  • X-squared = 2041.4: Đây là giá trị thống kê kiểm định Chi-bình phương. Nó đo lường sự khác biệt giữa tần suất quan sát được (số liệu thực tế trong bảng của bạn) và tần suất kỳ vọng (số liệu mà chúng ta mong đợi nếu hai biến hoàn toàn độc lập với nhau).

  • df = 1: Bậc tự do (degrees of freedom). Đối với kiểm định Chi-bình phương, bậc tự do được tính bằng công thức (số hàng - 1) * (số cột - 1). Vì bảng của bạn là 2x2, nên df = (2 - 1) * (2 - 1) = 1.

  • p-value < 2.2e-16: Đây là kết quả quyết định. Nếu việc có vết bầm và độc tính của nấm thực sự không liên quan gì đến nhau (H₀ đúng), thì xác suất để chúng ta quan sát được một mối liên hệ mạnh mẽ như vậy trong mẫu là gần như bằng không.

Kết luận: Với p-value < 2.2e-16, chúng ta bác bỏ giả thuyết \(H_0\). Có bằng chứng thống kê không thể chối cãi về một mối liên hệ mạnh mẽ giữa vết bầm và độc tính. Việc có vết bầm là một chỉ báo rất mạnh cho thấy nấm có khả năng cao là ăn được, trong khi không có vết bầm là một dấu hiệu cảnh báo nguy hiểm mà người thu hái nấm phải hết sức lưu ý.

Rủi ro tương đối (Relative Risk - RR)

Định nghĩa: RR so sánh xác suất (nguy cơ) một cây nấm là độc giữa nhóm “phơi nhiễm” (có vết bầm) và nhóm “không phơi nhiễm” (không có vết bầm).

# Bảng cần có dạng: cột là kết quả, hàng là phơi nhiễm
# Chúng ta định nghĩa "kết quả" là Độc (p) và "phơi nhiễm" là Có vết bầm (t)
rr_table_bruises <- table(df$bruises, df$class)[, c("p", "e")] 

# Tính toán RR
rr_result_bruises <- riskratio.wald(rr_table_bruises, rev="rows") # rev="rows" vì nhóm phơi nhiễm (t) ở hàng 2
rr_result_bruises
## $data
##        
##            p    e Total
##   t      624 2752  3376
##   f     3292 1456  4748
##   Total 3916 4208  8124
## 
## $measure
##    risk ratio with 95% C.I.
##      estimate     lower     upper
##   t 1.0000000        NA        NA
##   f 0.3761878 0.3593876 0.3937733
## 
## $p.value
##    two-sided
##     midp.exact fisher.exact chi.square
##   t         NA           NA         NA
##   f          0            0          0
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Trong đó

t là nhóm tham chiếu (reference group) với Risk Ratio = 1.000.

f có risk ratio = 0.37621878, nghĩa là:

  • Nguy cơ một cây nấm là độc khi nó không có vết bầm (f) chỉ bằng 0.376 lần (tức 37.6%) so với nguy cơ của một cây nấm có vết bầm (t)“. Hay, nguy cơ một cây nấm là độc khi nó có vết bầm (t) cao gấp 1 / 0.376 = 2.66 lần so với khi không có vết bầm.

  • Khoảng tin cậy 95%: [0.3594; 0.3938] cho thấy kết quả chính xác và có ý nghĩa thống kê cao (vì không chứa 1).

Diễn giải kết quả Relative Risk:

  • Relative Risk (RR) ≈ 0.3761878. Điều này có nghĩa là: Nguy cơ một cây nấm là độc ở nhóm có vết bầm chỉ bằng 0.3761878 lần so với nguy cơ ở nhóm không có vết bầm.

  • Nói cách khác, việc có vết bầm làm giảm 62.38% (1 - 0.3762) nguy cơ một cây nấm là độc.

  • Khoảng tin cậy 95% cho RR là [0.3594; 0.3938]. Vì khoảng này không chứa 1, nó khẳng định mối liên hệ có ý nghĩa thống kê.

Tỷ số chênh (Odds Ratio - OR)

Định nghĩa: OR so sánh “odds” của việc một cây nấm là độc giữa hai nhóm.

or_result_bruises <- oddsratio.wald(rr_table_bruises, rev="rows")
or_result_bruises$measure
##    odds ratio with 95% C.I.
##      estimate      lower     upper
##   t 1.0000000         NA        NA
##   f 0.1002854 0.09014769 0.1115632

Trong đó

  • t 1.0000000: Nhóm t (có vết bầm) vẫn là nhóm tham chiếu. OR của nó so với chính nó là 1.

  • f 0.1002854: Đây là Tỷ số Chênh (OR) của nhóm f (không có vết bầm) so với nhóm t.

  • Diễn giải: “Tỷ số chênh (odds) một cây nấm là độc khi nó không có vết bầm chỉ bằng 0.10 lần (tức 10%) so với tỷ số chênh khi nó có vết bầm”. Hay, tỷ số chênh một cây nấm là độc khi nó có vết bầm cao gấp 1 / 0.10 = 10 lần so với khi không có vết bầm.

  • lower 0.09014769 upper 0.1115632: Khoảng tin cậy 95% cho OR là từ 0.09 đến 0.11. Khoảng này cũng không chứa 1.0, cho thấy một mối liên hệ rất mạnh và có ý nghĩa thống kê.

Diễn giải kết quả Odds Ratio:

  • Odds Ratio (OR) ≈ 0.1003. Điều này có nghĩa là: Odds của việc một cây nấm là độc khi nó có vết bầm chỉ bằng 0.1003 lần (tức 10.03%) so với odds của việc nó là độc khi không có vết bầm.

  • Khoảng tin cậy 95% cho OR là [0.0901; 0.1116], không chứa 1, khẳng định mối liên hệ có ý nghĩa thống kê rất cao.

4.2 Mối quan hệ giữa class và odor (Mùi)

Câu hỏi nghiên cứu: Mùi hương của nấm có phải là một yếu tố dự báo mạnh về độc tính hay không?

Bảng tần số chéo và trực quan hóa

# Tạo một "từ điển" để ánh xạ các ký tự sang tên đầy đủ
odor_labels <- c(
  "a" = "Hạnh nhân", "l" = "Hồi", "c" = "Creosote",
  "y" = "Tanh", "f" = "Hôi", "m" = "Mốc",
  "n" = "Không mùi", "p" = "Hăng", "s" = "Cay")

df <- df %>%
  mutate(odor_full = recode(odor, !!!odor_labels))

class_odor_table <- table(Mùi = df$odor_full, Độc_tính = df$class_full)

kable(class_odor_table, caption = "Bảng tần số giữa mùi hương và loại nấm") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "center") %>%
  # Điều chỉnh độ rộng cột để bảng trông đẹp hơn
  column_spec(1, width = "10em", bold = TRUE) %>%
  column_spec(2:3, width = "8em")
Bảng tần số giữa mùi hương và loại nấm
Ăn được Độc
Hạnh nhân 400 0
Creosote 0 192
Hôi 0 2160
Hồi 400 0
Mốc 0 36
Không mùi 3408 120
Hăng 0 256
Cay 0 576
Tanh 0 576
# Trực quan hóa
ggplot(df, aes(x = fct_infreq(odor_full), fill = class_full)) +
  geom_bar(position = "dodge") +  # <-- Xếp cạnh nhau
  labs(title = "Mối quan hệ giữa mùi hương và độc tính của nấm",
       x = "Mùi của nấm", y = "Tần suất", fill = "Loại nấm") +
  theme_minimal(base_size = 12) +
  scale_fill_brewer(palette = "Set1", labels = c("Ăn được", "Độc"))+theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét:

  • Sự tách biệt gần như hoàn hảo giữa hai nhóm. Các loại nấm có mùi dễ chịu như Hạnh nhân, Hồi, hoặc Không mùi chiếm phần lớn trong nhóm ăn được. Ngược lại, tất cả các loại nấm có mùi khó chịu như Hôi, Tanh, Cay, Hăng đều 100% là nấm độc, không có ngoại lệ.

  • Trong tất cả các đặc điểm được khảo sát, mùi hương (odor) nổi lên như một yếu tố dự báo độc tính mạnh mẽ và đáng tin cậy nhất. Biểu đồ cho thấy không có sự chồng chéo giữa nhóm mùi an toàn và nhóm mùi nguy hiểm, giúp việc phân loại trở nên gần như tuyệt đối chỉ dựa vào đặc điểm này.

  • Từ mối quan hệ này, có thể rút ra một quy tắc vàng đơn giản và an toàn cho thực tế: “Nếu nấm có bất kỳ mùi lạ hoặc khó chịu nào, hãy mặc định nó là độc và tuyệt đối không sử dụng”. Điều này nhấn mạnh tầm quan trọng của việc kiểm tra cảm quan (mùi) khi nhận dạng nấm.

Kiểm định Chi-bình phương (Chi-squared Test) \[ \begin{cases} H_0: \text{Mùi và độc tính là hai biến độc lập.}\\ H_1: \text{Mùi và độc tính có sự liên quan.} \end{cases} \]

chisq.test(class_odor_table)
## 
##  Pearson's Chi-squared test
## 
## data:  class_odor_table
## X-squared = 7659.7, df = 8, p-value < 2.2e-16

Kết luận: Với p-value < 2.2e-16, chúng ta bác bỏ \(H_0\) và kết luận có một mối liên hệ thống kê cực kỳ mạnh mẽ. Mùi là yếu tố dự báo độc tính mạnh nhất. Có thể nói, chỉ cần dựa vào mùi, chúng ta đã có thể phân loại chính xác gần như toàn bộ nấm trong bộ dữ liệu này.

Vì biến odor có nhiều hơn 2 hạng mục (9 loại mùi) nên không thể tính một giá trị RR hoặc OR duy nhất cho toàn bộ bảng.

4.3 Mối quan hệ giữa class và spore.print.color (Màu sắc bào tử)

Câu hỏi nghiên cứu: Màu sắc bào tử có liên quan đến việc một cây nấm là độc hay ăn được không?

Bảng tần số chéo và trực quan hóa

spore_labels <- c(
  "k" = "Đen", "n" = "Nâu", "b" = "Da bò", 
  "h" = "Sô-cô-la", "r" = "Xanh lá", "o" = "Cam",
  "u" = "Tím", "w" = "Trắng", "y" = "Vàng"
)
df <- df %>%
  mutate(spore_color_full = recode(spore.print.color, !!!spore_labels))

class_spore_table <- table(df$spore_color_full, df$class_full)
kable(class_spore_table, caption = "Bảng tần số chéo giữa màu sắc bào tử và đọc tính của nấm") %>%
  kable_styling(bootstrap_options = "striped", position = "center", full_width = F)%>%
  column_spec(1, width = "5em") %>%
  column_spec(2:ncol(class_odor_table)+1, width = "12em")
Bảng tần số chéo giữa màu sắc bào tử và đọc tính của nấm
Ăn được Độc
Da bò 48 0
Sô-cô-la 48 1584
Đen 1648 224
Nâu 1744 224
Cam 48 0
Xanh lá 0 72
Tím 48 0
Trắng 576 1812
Vàng 48 0
ggplot(df, aes(x = fct_infreq(spore_color_full), fill = class_full)) +
  geom_bar(position = "dodge") +
  labs(
    title = "Mối quan hệ giữa màu sắc bào tử và độc tính của nấm",
    x = "Màu sắc bào tử",
    y = "Tần suất",
    fill = "Loại nấm"
  ) +
  theme_minimal(base_size = 12) +
  scale_fill_brewer(palette = "Set1", labels = c("Ăn được", "Độc"))+theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét: Mối quan hệ cũng rất rõ ràng. Màu bào tử r (xanh lá) 100% là độc. Các màu h (sô-cô-la) và w (trắng) có tỷ lệ độc rất cao, trong khi k (đen) và n (nâu) gần như hoàn toàn là ăn được.

Kiểm định Chi-bình phương (Chi-squared Test) \[ \begin{cases} H_0: \text{Màu sắc bào tử và độc tính là hai biến độc lập.}\\ H_1: \text{Màu sắc bào tử và độc tính có sự liên quan.} \end{cases} \]

chisq.test(class_spore_table)
## 
##  Pearson's Chi-squared test
## 
## data:  class_spore_table
## X-squared = 4602, df = 8, p-value < 2.2e-16

Kết luận: Với p-value < 2.2e-16, chúng ta bác bỏ \(H_0\) và kết luận có một mối liên hệ thống kê rất mạnh mẽ.

Tương tự như biến odor, biến spore.print.color cũng có nhiều hơn 2 hạng mục. Do đó, việc tính toán một RR/OR duy nhất là không phù hợp. Do vậy, chúng ta sẽ xây dựng bảng 2x2 với “Màu sắc bào tử”: k - Đen, w - Trắng và “Loại nấm”: e - Ăn được, p - Độc.

Rủi ro tương đối (RR)

Tiến hành so sánh xác suất (tỷ lệ) một cây nấm là độc (class = ‘p’) giữa nhóm “phơi nhiễm” (có màu sắc bào tử đen: spore.print.color = ‘k’) và nhóm “không phơi nhiễm” (có màu sắc bào tử trắng: spore.print.color = ‘w’).

  • Nhóm phơi nhiễm: Là những cây nấm có màu sắc bào tử đen (spore.print.color = ‘k’), xem liệu việc có màu sắc bào tử đen có liên quan đến việc nấm là độc hay không.

  • Nhóm không phơi nhiễm: Là những cây nấm có Màu sắc bào tử trắng (spore.print.color = ‘w’), đóng vai trò là nhóm đối chiếu để so sánh nguy cơ hoặc tỷ lệ chênh lệch nấm độc so với nhóm có màu sắc bào tử đen.

# Lọc dữ liệu và đảm bảo thứ tự levels
df_spore_class <- df %>%
  filter(spore.print.color %in% c("w", "k"), class %in% c("p", "e")) %>%
  mutate(
    spore.print.color = factor(spore.print.color, levels = c("w", "k")),
    class = factor(class, levels = c("p", "e"))
  )

# Tạo bảng tần số 2x2
contingency_table_spore_class <- table(df_spore_class$spore.print.color, df_spore_class$class)


riskratio.wald(contingency_table_spore_class)
## $data
##        
##            p    e Total
##   w     1812  576  2388
##   k      224 1648  1872
##   Total 2036 2224  4260
## 
## $measure
##    risk ratio with 95% C.I.
##     estimate    lower   upper
##   w 1.000000       NA      NA
##   k 3.649751 3.392568 3.92643
## 
## $p.value
##    two-sided
##     midp.exact fisher.exact chi.square
##   w         NA           NA         NA
##   k          0            0          0
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Về bảng tần số chéo:

  • Trong 1872 cây nấm có bào tử đen, có 224 cây là độc. Xác suất (nguy cơ) một cây nấm là độc nếu bào tử có màu đen là: P(Độc | Đen) = 224 / 1872 ≈ 12.0%.

  • Trong 2388 cây nấm có bào tử trắng, có 1812 cây là độc. Xác suất (nguy cơ) một cây nấm là độc nếu bào tử có màu trắng là: P(Độc | Trắng) = 1812 / 2388 ≈ 75.9%.

Diễn giải kết quả Relative Risk:

  • Theo cách tính của hàm riskratio.wald, nó đã lấy nhóm k (đen) làm nhóm tham chiếu (reference group) và tính RR cho nhóm w (trắng) so với nhóm k. Tuy nhiên, cách diễn giải của tác giả chọn w làm nhóm tham chiếu.

  • w là nhóm tham chiếu, RR = 1

  • k có RR = 3.649751. Con số này nói lên rằng: “Khả năng một cây nấm là độc ở nhóm có bào tử màu trắng cao gấp 3.65 lần so với nhóm có bào tử màu đen”.

  • Khoảng tin cậy 95% (95% C.I.): [3.392568, 3.92643]. Vì khoảng tin cậy này hoàn toàn nằm trên 1 và không chứa số 1, chúng ta có thể kết luận rằng nguy cơ ở nhóm bào tử trắng thực sự cao hơn nhóm bào tử đen một cách có ý nghĩa thống kê.

Tính Odds Ratio (OR)

So sánh “tỷ số chênh” (odds) của việc một cây nấm là độc giữa hai nhóm:

  • Nhóm phơi nhiễm: Nấm có bào tử màu đen (k).

  • Nhóm không phơi chiếu: Nấm có bào tử màu trắng (w).

or_spone_class <- oddsratio.wald(contingency_table_spore_class)
or_spone_class$measure
##    odds ratio with 95% C.I.
##     estimate    lower  upper
##   w  1.00000       NA     NA
##   k 23.14435 19.56251 27.382

Diễn giải kết quả Odd Ratio:

  • OR = 23.14435. Có ý nghĩa rằng một cây nấm là độc cao hơn gấp 23 lần nếu nó có bào tử màu trắng so với khi nó có bào tử màu đen.

  • Khoảng tin cậy 95% [19.56251,27382]: Vì toàn bộ khoảng này đều lớn hơn 1 rất nhiều, nó khẳng định rằng mối liên hệ này không phải là ngẫu nhiên mà cực kỳ mạnh và có ý nghĩa thống kê.

Kết luận: Phân tích Odds Ratio cho thấy bào tử màu trắng là một yếu tố làm tăng mạnh khả năng một cây nấm là độc. Cụ thể, odds của việc một cây nấm là độc cao hơn khoảng 23 lần khi nó có bào tử màu trắng so với khi nó có bào tử màu đen. Đây là một mối liên hệ rất mạnh và có ý nghĩa thống kê, là một cảnh báo quan trọng trong việc nhận dạng nấm.

Bây giờ, chúng ta sẽ chuyển hướng cuộc điều tra. Mục tiêu của phần này là trả lời câu hỏi 2: Liệu có thể nhìn vào một cây nấm và đoán xem nó đến từ khu rừng rậm, đồng cỏ hay ven đường không? Chúng ta sẽ kiểm tra xem liệu các đặc điểm như mùi, màu sắc và hình dạng có phải là “dấu ấn” của một môi trường sống cụ thể hay không.

4.4 Mối quan hệ giữa môi trường sống (habitat) và mùi (odor)

Câu hỏi nghiên cứu: Chúng ta sẽ kiểm tra xem sự phân bổ của các loại mùi có khác nhau đáng kể giữa các môi trường sống hay không.

Bảng tần số chéo và trực quan hoá

# Tạo bảng tần số chéo
habitat_odor_table <- table(df$habitat_full, df$odor_full)
kable(habitat_odor_table, caption = "Bảng tần số giữa môi trường sống và mùi hương của nấm") %>%
  kable_styling(bootstrap_options = "striped", full_width = T)
Bảng tần số giữa môi trường sống và mùi hương của nấm
Hạnh nhân Creosote Hôi Hồi Mốc Không mùi Hăng Cay Tanh
Bãi rác 0 0 0 0 0 192 0 0 0
Đô thị 0 0 144 0 0 96 128 0 0
Đồng cỏ 128 0 0 128 0 36 0 0 0
Lối đi 48 0 624 48 0 40 0 192 192
Trên cỏ 176 0 576 176 0 1092 128 0 0
Trên lá 0 0 192 0 0 256 0 192 192
Trong rừng 48 192 624 48 36 1816 0 192 192

Trực quan hoá

ggplot(df, aes(x = habitat_full, fill = odor_full)) +
  geom_bar(position = "dodge") +
  labs(title = "Số lượng các loại mùi theo môi trường sống",
       x = "Môi trường sống", y = "Số lượng", fill = "Mùi của nấm") +
  theme_minimal(base_size = 14) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét:

  • Dữ liệu cho thấy sự phân bổ mùi của nấm không hề ngẫu nhiên mà có quy luật rõ ràng theo từng môi trường. Môi trường Trong rừng bị thống trị bởi nấm Không mùi (1816 mẫu). Ngược lại, môi trường Trên cỏ và Lối đi lại là nơi tập trung của nấm có mùi Hồi (lần lượt 576 và 624 mẫu) và các mùi khó chịu khác. Điều này cho thấy mùi hương có thể là một chỉ báo mạnh mẽ để dự đoán môi trường sống của nấm.

  • Phân tích bảng tần số cho thấy nhiều loại mùi hoàn toàn không xuất hiện ở một số môi trường. Ví dụ, nấm có mùi Creosote chỉ được tìm thấy duy nhất ở Trong rừng. Tương tự, nấm mùi Tanh và Cay chỉ xuất hiện ở 3 môi trường: Trong rừng, Trên lá và Lối đi, nhưng lại vắng mặt hoàn toàn ở các môi trường khác. Sự vắng mặt này là một thông tin quan trọng, giúp thu hẹp phạm vi tìm kiếm hoặc nhận dạng loài.

  • Mặc dù bị thống trị bởi nấm không mùi, trong rừng là nơi duy nhất có sự hiện diện của tất cả các loại mùi được ghi nhận trong bộ dữ liệu (trừ mùi Hồi). Điều này phản ánh sự đa dạng sinh học cao của hệ sinh thái rừng, tạo điều kiện cho nhiều loài nấm khác nhau cùng phát triển, từ đó tạo ra một “bản giao hưởng” mùi hương phong phú nhất so với các môi trường sống khác.

Kiểm định Chi-bình phương (Chi-squared Test)

Bài toán kiểm định:

\[ \begin{cases} H_0: \text{Môi trường sống và mùi hương của nấm là hai biến độc lập.}\\ H_1: \text{Môi trường sống và mùi hương của nấm có sự liên quan.} \end{cases} \]

chisq.test(habitat_odor_table)
## 
##  Pearson's Chi-squared test
## 
## data:  habitat_odor_table
## X-squared = 6675.1, df = 48, p-value < 2.2e-16

Kết luận: Với p-value < 2.2e-16, chúng ta bác bỏ giả thuyết \(H_0\). Có bằng chứng thống kê không thể chối cãi về một mối liên hệ mạnh mẽ giữa mùi và môi trường sống của nấm. Các loài nấm có mùi hôi (thường là nấm độc) phát triển mạnh ở những khu vực quang đãng như đồng cỏ, lối đi. Ngược lại, các loài không mùi (thường là nấm ăn được) lại ưa thích môi trường rừng. Mùi là một yếu tố dự báo tốt cho môi trường sống.

Rủi ro tương đối (Relative Risk)

So sánh xác suất (tỷ lệ) một cây nấm có mùi hôi (odor = ‘f’) giữa nhóm “phơi nhiễm” (sống trong rừng: habitat = ‘d’) và nhóm “không phơi nhiễm” (sống trên cỏ: habitat = ‘g’).

  • Nhóm phơi nhiễm: Là những cây nấm sống trong rừng (habitat = ‘d’), xem liệu việc sống trong rừng có liên quan đến việc nấm có mùi hôi hay không.

  • Nhóm không phơi nhiễm: Là những cây nấm sống trên cỏ (habitat = ‘g’), đóng vai trò là nhóm đối chiếu để so sánh nguy cơ hoặc tỷ lệ chênh lệch nấm có mùi hôi so với nhóm sống trong rừng.

# Lọc dữ liệu và đảm bảo thứ tự levels
df_habitat_odor <- df %>%
  filter(habitat %in% c("d", "g"), odor %in% c("f", "n")) %>%
  mutate(
    habitat = factor(habitat, levels = c("d", "g")),
    odor = factor(odor, levels = c("f", "n"))
  )

# Tạo bảng tần số 2x2
contingency_table_habitat_odor <- table(df_habitat_odor$habitat, df_habitat_odor$odor)

riskratio.wald(contingency_table_habitat_odor)
## $data
##        
##            f    n Total
##   d      624 1816  2440
##   g      576 1092  1668
##   Total 1200 2908  4108
## 
## $measure
##    risk ratio with 95% C.I.
##      estimate     lower     upper
##   d 1.0000000        NA        NA
##   g 0.8796311 0.8435345 0.9172723
## 
## $p.value
##    two-sided
##       midp.exact fisher.exact   chi.square
##   d           NA           NA           NA
##   g 6.717302e-10 7.419893e-10 5.611102e-10
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Về bảng tần số:

  • Trong 2440 cây nấm mọc trong rừng, có 624 cây có mùi hôi. Xác suất (nguy cơ) một cây nấm có mùi hôi nếu nó mọc trong rừng là: P(Hôi | Rừng) = 624 / 2440 ≈ 25.6%.

  • Trong 1668 cây nấm mọc trên cỏ, có 576 cây có mùi hôi. Xác suất (nguy cơ) một cây nấm có mùi hôi nếu nó mọc trên cỏ là: P(Hôi | Cỏ) = 576 / 1668 ≈ 34.5%.

Diễn giải Relative Risk (RR)

  • g có RR = 0.8796311: Con số này nói rằng: “Khả năng một cây nấm có mùi hôi ở trong rừng (nhóm phơi nhiễm) chỉ bằng 0.88 lần (tức 88%) so với ở trên cỏ (nhóm tham chiếu)”. Hay tỷ lệ một cây nấm có mùi hôi khi nó mọc trong rừng thấp hơn một chút, chỉ bằng 88% so với khi nó mọc trên cỏ.

  • Khoảng tin cậy 95% (95% C.I.): [0.84, 0.92]. Vì khoảng tin cậy này hoàn toàn nằm dưới 1 và không chứa số 1, chúng ta có thể kết luận rằng việc mọc trong rừng thực sự làm giảm nguy cơ có mùi hôi một cách có ý nghĩa thống kê.

Tính Odds Ratio (OR)

or_habitat_odor <- oddsratio.wald(contingency_table_habitat_odor)
or_habitat_odor$measure
##    odds ratio with 95% C.I.
##      estimate     lower     upper
##   d 1.0000000        NA        NA
##   g 0.6514317 0.5686757 0.7462307

Diễn giải kết quả OR:

  • OR = 0.6514317. Con số này nói rằng: “Một cây nấm có mùi hôi ở trong rừng chỉ bằng 0.65 lần (tức 65%) so với ở trên cỏ”. Hay Odds (tỷ số chênh) của việc một cây nấm có mùi hôi khi nó mọc trong rừng thấp hơn đáng kể, chỉ bằng 65% so với khi nó mọc trên cỏ.

  • Khoảng tin cậy 95% (95% C.I.): [0.5686757, 0.7462307]. Khoảng tin cậy này cũng hoàn toàn nằm dưới 1, khẳng định rằng mối liên hệ này mạnh và có ý nghĩa thống kê.

4.5 Mối quan hệ giữa môi trường sống (habitat) và màu sắc mũ (cap.color)

Câu hỏi nghiên cứu: Liệu màu sắc mũ của nấm có liên quan và có thể giúp dự đoán môi trường sống của nó không?

Bảng tần số chéo và trực quan hóa

# Tạo bảng tần số chéo
cap_color_labels <- c(
  "n" = "Nâu", "b" = "Da bò", "c" = "Quế", "g" = "Xám",
  "r" = "Xanh lá", "p" = "Hồng", "u" = "Tím", "e" = "Đỏ",
  "w" = "Trắng", "y" = "Vàng"
)
df <- df %>%
  mutate(cap_color_full = recode(cap.color, !!!cap_color_labels))

habitat_capcolor_table <- table(df$habitat_full, df$cap_color_full)
kable(habitat_capcolor_table, caption = "Bảng tần số giữa môi trường sống và màu sắc mũ của nấm") %>%
  kable_styling(bootstrap_options = "striped")
Bảng tần số giữa môi trường sống và màu sắc mũ của nấm
Da bò Quế Đỏ Xám Nâu Hồng Xanh lá Tím Trắng Vàng
Bãi rác 48 0 48 0 48 48 0 0 0 0
Đô thị 48 0 0 96 112 0 0 0 112 0
Đồng cỏ 12 0 0 0 0 12 0 0 140 128
Lối đi 0 8 288 224 352 8 0 0 0 264
Trên cỏ 60 0 0 664 368 12 0 0 652 392
Trên lá 0 24 288 0 504 0 0 0 8 8
Trong rừng 0 12 876 856 900 64 16 16 128 280

Trực quan hoá

ggplot(df, aes(x = habitat_full, fill = cap_color_full)) +
  geom_bar(position = "dodge")

  labs(title = "Tỷ lệ màu sắc mũ theo môi trường sống",
    x = "Môi trường sống",
    y = "Tỷ lệ",
    fill = "Màu sắc mũ" ) +  theme_minimal(base_size = 14) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),legend.position = "bottom" ) +
  guides(fill = guide_legend(nrow = 2))
## NULL

Nhận xét:

  • Phân tích cho thấy sự phân bổ màu sắc mũ không hề đồng đều mà có quy luật rất rõ ràng. Ví dụ, môi trường Trong rừng là nơi có sự đa dạng màu sắc nhất, với số lượng lớn nấm mũ Đỏ (876 mẫu), Xám (856 mẫu), và Nâu (900 mẫu). Ngược lại, môi trường Đô thị lại rất đơn giản, chủ yếu chỉ có nấm mũ Nâu (112 mẫu) và Xám (96 mẫu). Sự khác biệt này cho thấy màu sắc mũ là một chỉ báo tốt để dự đoán môi trường sống.

  • Một số màu sắc chỉ xuất hiện ở những môi trường rất cụ thể. Đáng chú ý nhất là màu Xanh lá và Tím, cả hai đều chỉ được tìm thấy duy nhất ở môi trường Trong rừng (16 mẫu mỗi loại). Điều này biến chúng thành những đặc điểm nhận dạng cực kỳ giá trị cho hệ sinh thái rừng. Sự vắng mặt của những màu này ở các môi trường khác cũng là một thông tin quan trọng.

  • Thay vì phân bổ rộng rãi, một số màu sắc dường như “ưa thích” một vài môi trường cụ thể. Ví dụ, nấm có mũ màu Trắng có số lượng lớn nhất ở môi trường Trên cỏ (652 mẫu). Tương tự, nấm mũ Nâu chiếm ưu thế tuyệt đối ở môi trường Trên lá (504 mẫu). Điều này cho thấy có một mối liên kết mạnh mẽ giữa các loài nấm có màu sắc nhất định và điều kiện sinh thái của từng môi trường.

Kiểm định Chi-bình phương (Chi-squared Test)

Bài toán kiểm định:

\[ \begin{cases} H_0: \text{Môi trường sống và màu sắc mũ của nấm là hai biến độc lập.}\\ H_1: \text{Môi truòng sống và màu sắc mũ của nấm có sự liên quan.} \end{cases} \]

chisq.test(habitat_capcolor_table)
## 
##  Pearson's Chi-squared test
## 
## data:  habitat_capcolor_table
## X-squared = 5205.1, df = 54, p-value < 2.2e-16

Kết luận: Với p-value < 2.2e-16, chúng ta bác bỏ giả thuyết \(H_0\). Có một mối liên hệ thống kê rất mạnh mẽ, cho thấy màu sắc mũ là một yếu tố dự báo hữu ích cho môi trường sống. Các loài nấm với màu sắc nhất định có xu hướng thích nghi và phát triển mạnh ở những điều kiện sinh thái cụ thể.

Rủi ro tương đối (RR)

So sánh xác suất (tỷ lệ) một cây nấm có mũ màu nâu (cap.color = ‘n’) giữa nhóm “phơi nhiễm” (sống trong rừng: habitat = ‘d’) và nhóm “không phơi nhiễm” (sống trên cỏ: habitat = ‘g’).

  • Nhóm phơi nhiễm: Là những cây nấm sống trong rừng (habitat = ‘d’), xem liệu việc sống trong rừng có liên quan đến việc nấm có mũ màu nâu hay không.

  • Nhóm không phơi nhiễm: Là những cây nấm sống trên cỏ (habitat = ‘g’), đóng vai trò là nhóm đối chiếu để so sánh nguy cơ hoặc tỷ lệ chênh lệch nấm có mũ màu nâu so với nhóm sống trong rừng.

# Lọc dữ liệu và đảm bảo thứ tự levels
df_habitat_capcolor <- df %>%
  filter(habitat %in% c("d", "g"), cap.color %in% c("n", "w")) %>%
  mutate(
    habitat = factor(habitat, levels = c("d", "g")),
    cap.color = factor(cap.color, levels = c("n", "w"))
  )

# Tạo bảng tần số 2x2
contingency_table_habitat_capcolor <- table(df_habitat_capcolor$habitat, df_habitat_capcolor$cap.color)


riskratio.wald(contingency_table_habitat_capcolor)
## $data
##        
##            n   w Total
##   d      900 128  1028
##   g      368 652  1020
##   Total 1268 780  2048
## 
## $measure
##    risk ratio with 95% C.I.
##     estimate    lower    upper
##   d 1.000000       NA       NA
##   g 5.133701 4.337522 6.076024
## 
## $p.value
##    two-sided
##     midp.exact  fisher.exact    chi.square
##   d         NA            NA            NA
##   g          0 2.501935e-135 4.144903e-127
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Về bảng tần số:

  • Nguy cơ ở nhóm “Trong rừng” (d): Trong 1028 cây nấm có màu mũ không phải trắng mọc trong rừng, có 900 cây có mũ màu nâu. Xác suất (nguy cơ) một cây nấm có mũ nâu nếu nó mọc trong rừng là: P(Nâu | Rừng) = 900 / 1028 ≈ 87.5%.

  • Nguy cơ ở nhóm “Trên cỏ” (g): Trong 1020 cây nấm có màu mũ không phải trắng mọc trên cỏ, có 368 cây có mũ màu nâu. Xác suất (nguy cơ) một cây nấm có mũ nâu nếu nó mọc trên cỏ là: P(Nâu | Cỏ) = 368 / 1020 ≈ 36.1%.

Diễn giải kết quả RR:

  • g có RR = 5.133701. Con số này nói rằng: “Tỷ lệ một cây nấm có mũ màu nâu ở trong rừng (nhóm phơi nhiễm) cao gấp 5.13 lần so với tỷ lệ ở trên cỏ (nhóm tham chiếu)”. Hay tỷ lệ một cây nấm có mũ màu nâu khi nó mọc trong rừng cao hơn gấp 5.1 lần so với khi nó mọc trên cỏ.

  • Khoảng tin cậy 95% (95% C.I.): [4.34, 6.08]. Vì khoảng tin cậy này hoàn toàn nằm trên 1 và không chứa số 1, chúng ta có thể kết luận rằng việc mọc trong rừng thực sự làm tăng nguy cơ có mũ màu nâu một cách có ý nghĩa thống kê.

Tính Odds Ratio (OR)

or_habitat_capcolor <- oddsratio.wald(contingency_table_habitat_capcolor)
or_habitat_capcolor$measure
##    odds ratio with 95% C.I.
##     estimate    lower    upper
##   d  1.00000       NA       NA
##   g 12.45754 9.947875 15.60035

Diễn giải kết quả OR:

  • OR = 12.45754: Con số này nói rằng: “Việc một cây nấm có mũ màu nâu khi nó mọc trong rừng cao hơn gấp khoảng 12.5 lần so với khi nó mọc trên cỏ”.

  • Khoảng tin cậy 95% (95% C.I.): [9.95, 15.60]. Khoảng tin cậy này cũng hoàn toàn nằm trên 1, khẳng định rằng mối liên hệ này rất mạnh và có ý nghĩa thống kê.

4.6 Mối quan hệ giữa môi trường sống (habitat) và hình dạng mũ (cap.shape)

Câu hỏi nghiên cứu: Liệu hình dạng mũ của nấm có liên quan và có thể giúp dự đoán môi trường sống của nó không?

Bảng tần số chéo và trực quan hóa

cap_shape_labels <- c(
  "b" = "Hình chuông", "c" = "Hình nón", "x" = "Lồi",
  "f" = "Phẳng", "k" = "Có núm", "s" = "Lõm"
)
df <- df %>%
  mutate(cap_shape_full = recode(cap.shape, !!!cap_shape_labels))

# Tạo bảng tần số chéo
habitat_capshape_table <- table(df$habitat_full, df$cap_shape_full)
kable(habitat_capshape_table, caption = "Bảng tần số giữa môi trường sống và hình dạng mũ của nấm") %>%
  kable_styling(bootstrap_options = "striped", full_width = F) %>%   column_spec(1, width = "5em") %>%
  column_spec(2:ncol(habitat_capshape_table)+1, width = "12em")
Bảng tần số giữa môi trường sống và hình dạng mũ của nấm
Hình chuông Hình nón Phẳng Có núm Lõm Lồi
Bãi rác 0 0 64 64 0 64
Đô thị 0 0 168 0 32 168
Đồng cỏ 146 0 18 0 0 128
Lối đi 2 0 474 194 0 474
Trên cỏ 242 0 802 96 0 1008
Trên lá 52 4 260 260 0 256
Trong rừng 10 0 1366 214 0 1558

Trực quan hoá

ggplot(df, aes(x = habitat_full, fill = cap_shape_full)) +
  geom_bar(position = "dodge") +
  labs(
    title = "Số lượng các hình dạng mũ theo môi trường sống",
    x = "Môi trường sống",
    y = "Số lượng",
    fill = "Hình dạng mũ" # Đây là tên của phần chú thích
  ) +
  theme_minimal(base_size = 14) +
  # Xoay nhãn trục x để dễ đọc và đẩy chú thích xuống dưới
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "bottom"
  )

Nhận xét:

  • Sự thống trị của hai hình dạng mũ “Lồi” và “Phẳng”: Nhìn chung, hai hình dạng mũ Lồi và Phẳng chiếm ưu thế tuyệt đối ở hầu hết các môi trường sống. Đặc biệt, trong môi trường Trong rừng, có tới 1558 mẫu mũ Lồi và 1366 mẫu mũ Phẳng, cho thấy đây là các hình dạng rất phổ biến và thích nghi tốt với điều kiện rừng. Sự phổ biến này làm cho việc phân loại chỉ dựa trên hai hình dạng này trở nên khó khăn hơn so với dùng mùi hay màu sắc.

  • Mỗi môi trường có một “tổ hợp” hình dạng đặc trưng: Mặc dù bị hai hình dạng trên thống trị, mỗi môi trường vẫn có một “tổ hợp” hình dạng riêng. Ví dụ, nấm có mũ Hình chuông được tìm thấy nhiều nhất ở môi trường Trên cỏ (242 mẫu) và Đồng cỏ (146 mẫu), nhưng gần như không có ở các môi trường khác. Tương tự, nấm có Núm xuất hiện đáng kể ở Trong rừng (214 mẫu), Trên lá (260 mẫu) và Lối đi (194 mẫu), nhưng lại vắng mặt ở môi trường Đô thị.

  • Các hình dạng hiếm là chỉ báo mạnh cho môi trường cụ thể: Các hình dạng mũ ít phổ biến lại trở thành những chỉ báo rất giá trị. Ví dụ, hình dạng Lõm chỉ được tìm thấy duy nhất ở môi trường Đô thị (32 mẫu). Tương tự, hình dạng Hình nón cực kỳ hiếm và chỉ xuất hiện ở môi trường Trên lá (4 mẫu). Điều này có nghĩa là nếu bạn tìm thấy một cây nấm có mũ lõm, khả năng rất cao nó đến từ một khu vực đô thị.

Kiểm định Chi-bình phương (Chi-squared Test)

Bài toán kiểm định:

\[ \begin{cases} H_0: \text{Môi trường sống và hình dạng mũ của nấm là hai biến độc lập.}\\ H_1: \text{Môi trường sống và hình dạng mũ của nấm có sự liên quan.} \end{cases} \]

chisq.test(habitat_capshape_table)
## 
##  Pearson's Chi-squared test
## 
## data:  habitat_capshape_table
## X-squared = 2985.9, df = 30, p-value < 2.2e-16

Kết luận: Với p-value < 2.2e-16, chúng ta bác bỏ giả thuyết \(H_0\). Hình dạng mũ cũng có mối liên hệ có ý nghĩa thống kê với môi trường sống, dù mức độ phân loại có thể không rõ ràng bằng mùi hay màu sắc.

Rủi ro tương đối (RR)

So sánh xác suất (tỷ lệ) một cây nấm có mũ hình phẳng (cap.shape = ‘f’) giữa nhóm “phơi nhiễm” (sống trong rừng: habitat = ‘d’) và nhóm “không phơi nhiễm” (sống Trên cỏ: habitat = ‘g’).

  • Nhóm phơi nhiễm: Là những cây nấm sống trong rừng (habitat = ‘d’), xem liệu việc sống trong rừng có liên quan đến việc nấm có mũ hình phẳng hay không.

  • Nhóm không phơi nhiễm: Là những cây nấm sống trên cỏ (habitat = ‘g’), đóng vai trò là nhóm đối chiếu để so sánh nguy cơ hoặc tỷ lệ chênh lệch nấm có mũ hình phẳng so với nhóm sống trong rừng.

# Lọc dữ liệu và đảm bảo thứ tự levels
df_habitat_capshape <- df %>%
  filter(habitat %in% c("d", "g"), cap.shape %in% c("f", "x")) %>%
  mutate(
    habitat = factor(habitat, levels = c("d", "g")),
    cap.shape = factor(cap.shape, levels = c("f", "x"))
  )

# Tạo bảng tần số 2x2
contingency_table_habitat_capshape <- table(df_habitat_capshape$habitat, df_habitat_capshape$cap.shape)


riskratio.wald(contingency_table_habitat_capshape)
## $data
##        
##            f    x Total
##   d     1366 1558  2924
##   g      802 1008  1810
##   Total 2168 2566  4734
## 
## $measure
##    risk ratio with 95% C.I.
##     estimate     lower    upper
##   d 1.000000        NA       NA
##   g 1.045182 0.9909361 1.102397
## 
## $p.value
##    two-sided
##     midp.exact fisher.exact chi.square
##   d         NA           NA         NA
##   g  0.1062531    0.1116582  0.1061771
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Về bảng tần số:

  • Trong 2924 cây nấm, có 1366 cây có mũ phẳng. Xác suất (nguy cơ) một cây nấm có mũ phẳng nếu nó mọc trong rừng là: P(Phẳng | Rừng) = 1366 / 2924 ≈ 46.7%.

  • Trong 1810 cây nấm, có 802 cây có mũ phẳng. Xác suất (nguy cơ) một cây nấm có mũ phẳng nếu nó mọc trên cỏ là: P(Phẳng | Cỏ) = 802 / 1810 ≈ 44.3%.

Diễn giải Relative Risk (RR):

  • RR = 1.045182: Con số này nói rằng: “khả năng một cây nấm có mũ phẳng ở trong rừng (nhóm phơi nhiễm) cao gấp 1.045 lần so với khả năng ở trên cỏ (nhóm tham chiếu)”. Hay một cây nấm có mũ phẳng khi nó mọc trong rừng chỉ cao hơn một chút (cao hơn khoảng 4.5%) so với khi nó mọc trên cỏ.

  • Khoảng tin cậy 95% (95% C.I.): [0.99, 1.10]. Vì khoảng tin cậy chứa 1, chúng ta không có đủ bằng chứng thống kê để kết luận rằng có sự khác biệt thực sự về nguy cơ tìm thấy nấm mũ phẳng giữa hai môi trường này ở mức ý nghĩa 5%. P-value = 0.106 cũng lớn hơn 0.05, khẳng định điều này.

Tính Odds Ratio (OR)

or_habitat_capshape <- oddsratio.wald(contingency_table_habitat_capshape)
or_habitat_capshape$measure
##    odds ratio with 95% C.I.
##     estimate     lower    upper
##   d 1.000000        NA       NA
##   g 1.101969 0.9795039 1.239746

Diễn giải kết quả OR:

  • OR = 1.101969: Con số này nói rằng: “một cây nấm có mũ phẳng khi nó mọc trong rừng chỉ cao hơn một chút (cao hơn 10%) so với khi nó mọc trên cỏ”.

  • Khoảng tin cậy 95% (95% C.I.): [0.98, 1.24]. Tương tự như RR, khoảng tin cậy này cũng chứa số 1. Chúng ta cũng không có đủ bằng chứng thống kê để kết luận rằng có sự khác biệt thực sự về odds tìm thấy nấm mũ phẳng giữa hai môi trường này.

5 Tổng kết và thảo luận

Cuộc hành trình phân tích dữ liệu trên bộ sưu tập nấm đã mang lại những hiểu biết sâu sắc, không chỉ trả lời các câu hỏi nghiên cứu ban đầu mà còn mở ra những hướng đi mới. Phần này sẽ tóm tắt lại những phát hiện quan trọng nhất, nhìn nhận các hạn chế của phân tích, và đề xuất các ứng dụng thực tiễn cũng như hướng nghiên cứu trong tương lai.

5.1 Tóm tắt những phát hiện chính

Phân tích sâu bộ dữ liệu Mushroom đã mang lại nhiều kết quả quan trọng và có ý nghĩa thực tiễn, có thể tóm tắt qua các điểm chính sau:

  • Xác định các yếu tố dự báo chủ chốt về độc tính. kết quả phân tích đã xác định một cách rõ ràng “bộ ba quyền lực” trong việc nhận dạng nấm độc. Mùi hương (odor) nổi lên như một yếu tố phân loại gần như hoàn hảo. Sự tách biệt tuyệt đối giữa nhóm mùi an toàn (hạnh nhân, hồi, không mùi) và nhóm mùi nguy hiểm (hôi, tanh, cay…) cho thấy đây là chỉ báo đáng tin cậy nhất.

  • Màu sắc bào tử (spore.print.color) và vết bầm (bruises) cũng là những yếu tố dự báo cực kỳ mạnh mẽ. Các màu bào tử như sô-cô-la, trắng, xanh lá là dấu hiệu cảnh báo cao, trong khi việc có vết bầm lại là một chỉ báo mạnh mẽ của nấm ăn được. Tất cả các mối liên hệ này đều được khẳng định bằng kiểm định Chi-bình phương với p-value gần như bằng không.

  • Lượng hóa Sức mạnh của Mối liên hệ: Đối với mối quan hệ giữa vết bầm và độc tính, chúng ta không chỉ xác nhận sự liên quan mà còn lượng hóa được nó một cách ấn tượng. Odds Ratio (OR): Kết quả cho thấy odds của việc một cây nấm là độc ở nhóm không có vết bầm cao gấp khoảng 10 lần so với nhóm có vết bầm. Relative Risk (RR): Tương tự, nguy cơ (xác suất) một cây nấm là độc ở nhóm không có vết bầm cao hơn khoảng 3.7 lần so với nhóm có vết bầm. Cả hai chỉ số đều khẳng định việc không có vết bầm là một yếu tố rủi ro rất lớn.

  • Phân tích đã chứng minh rằng các đặc điểm hình thái không tồn tại một cách ngẫu nhiên mà có mối liên kết chặt chẽ với môi trường sống. Chúng ta hoàn toàn có thể dựa vào mùi, màu sắc và hình dạng mũ để đưa ra phỏng đoán có cơ sở về nơi một cây nấm được tìm thấy. Ví dụ, nấm mùi hôi thường được tìm thấy ở đồng cỏ và lối đi, trong khi nấm không mùi lại ưa thích môi trường rừng. Điều này mở ra hướng nghiên cứu về sự thích nghi của các loài nấm với hệ sinh thái của chúng.

  • Đặc điểm Bộ dữ liệu: Dữ liệu có sự phân bổ tương đối cân bằng giữa nấm độc (48.2%) và nấm ăn được (51.8%), đây là một điều kiện lý tưởng cho các phân tích thống kê và xây dựng các mô hình học máy trong tương lai mà không lo ngại về vấn đề mất cân bằng lớp.

5.2 Hạn chế của phân tích

Mặc dù các kết quả rất rõ ràng và mạnh mẽ, việc duy trì một tư duy khoa học đòi hỏi chúng ta phải nhận thức được những hạn chế của nghiên cứu:

  • Tính đại diện của dữ liệu: Các quy tắc và mối quan hệ được rút ra từ bộ dữ liệu này chỉ có giá trị trong phạm vi các loài được mô tả trong “Sổ tay hướng dẫn của Audubon”. Chúng có thể không áp dụng được cho tất cả các loài nấm trên toàn thế giới, đặc biệt là các loài ở những vùng địa lý khác. Việc áp dụng các quy tắc này một cách máy móc ngoài thực địa mà không có kiến thức chuyên môn sâu rộng vẫn tiềm ẩn rủi ro.

  • Phương pháp xử lý dữ liệu thiếu: Việc điền giá trị thiếu trong cột stalk.root bằng mode là một giả định hợp lý để bảo toàn kích thước mẫu. Tuy nhiên, phương pháp này có thể đã làm thay đổi nhẹ cấu trúc phân phối thực tế của biến và có khả năng ảnh hưởng đến các phân tích có liên quan đến đặc điểm này.

  • Bản chất của phân tích: Đây là một phân tích dựa trên dữ liệu quan sát, không phải một thí nghiệm có kiểm soát. Chúng ta có thể xác định các mối liên hệ mạnh (associations), nhưng không thể khẳng định một cách chắc chắn về mối quan hệ nhân-quả (causation).

5.3 Đề xuất và ứng dụng Thực tiễn

Các phát hiện từ phân tích có thể được chuyển thành các ứng dụng thực tế, mang lại giá trị trực tiếp cho cộng đồng.

Xây dựng Quy tắc Nhận dạng An toàn Đơn giản: Có thể tạo ra một hệ thống quy tắc phân cấp đơn giản nhưng hiệu quả cao cho người mới bắt đầu.

  • Quy tắc 1: Nếu nấm có bất kỳ mùi khó chịu nào (hôi, tanh, cay, hăng…) -> DỪNG LẠI, ĐÂY LÀ NẤM ĐỘC.

  • Quy tắc 2: Nếu nấm không mùi hoặc mùi dễ chịu, hãy kiểm tra màu sắc bào tử. Nếu màu sô-cô-la, trắng, hoặc xanh lá -> CẢNH BÁO CAO, Rất có thể là ĐỘC.

  • Quy tắc 3: Kiểm tra vết bầm. Nếu nấm không có vết bầm -> TĂNG CƯỜNG CẢNH GIÁC.

Thiết kế Ứng dụng Nhận dạng Thông minh: Khi xây dựng một ứng dụng nhận dạng nấm trên di động, các câu hỏi về odor, spore.print.color, và bruises nên được đặt lên hàng đầu trong giao diện người dùng để nhanh chóng thu hẹp khả năng và đưa ra cảnh báo sớm.

5.4 Hướng nghiên cứu tiếp theo

Phân tích này là một nền tảng vững chắc, mở ra nhiều hướng nghiên cứu sâu hơn và hấp dẫn:

  • Xây dựng mô hình dự đoán: Sử dụng các thuật toán học máy như Cây quyết định (Decision Tree), Rừng ngẫu nhiên (Random Forest) hoặc Hồi quy Logistic để xây dựng một mô hình có khả năng dự đoán độc tính với độ chính xác cao. Cây quyết định sẽ đặc biệt thú vị vì nó có thể trực quan hóa các quy tắc phân loại, tương tự như cách chúng ta đã phân tích.

  • Phân tích tương tác giữa các biến: Nghiên cứu xem liệu sự kết hợp của các đặc điểm có tạo ra một yếu tố dự báo mạnh hơn không. Ví dụ: “Một cây nấm mũ màu nâu (cap-color=n) mọc trên lối đi (habitat=p) có nguy cơ độc cao hơn một cây nấm mũ nâu mọc trong rừng (habitat=d) hay không?”. Đây là các phân tích tương tác (interaction analysis).