Chuyển đến nội dung chính

Kiểm định chính xác Fisher: Ra quyết định với mẫu nhỏ

Học cách phân tích mối quan hệ phân loại khi kích thước mẫu nhỏ.
· 9 phút đọc

Khám phá cùng AI

Các tổ chức đưa ra quyết định mỗi ngày dựa trên hành vi của khách hàng, hiệu suất của sản phẩm và biến động vận hành. Để đảm bảo các quyết định này dựa trên những mối quan hệ và khuôn mẫu thực sự trong dữ liệu, các nhà phân tích thường sử dụng các kiểm định thống kê. 

Trong khi các kiểm định thống kê phổ biến hoạt động tốt với bộ dữ liệu lớn, doanh nghiệp không phải lúc nào cũng có đặc ân đó. Thực tế, nhiều quyết định phải được đưa ra dựa trên kích thước mẫu nhỏ, phân khúc khách hàng ngách hoặc các sự kiện hiếm gặp. Trong những tình huống này, các kiểm định truyền thống như chi-bình phương có thể không đáp ứng, dẫn đến kết quả gây hiểu nhầm hoặc thiếu độ chính xác cần thiết để tự tin hành động dựa trên các insight. 

Đó là lúc kiểm định chính xác Fisher trở nên hữu ích. Tiếp tục đọc và tôi sẽ chỉ cho bạn cách áp dụng.

Kiểm định chính xác Fisher là gì?

Kiểm định chính xác Fisher được dùng để đánh giá mối liên hệ giữa các biến phân loại khi dữ liệu hạn chế. Kiểm định này thường được áp dụng cho bảng chéo 2×2 và tính xác suất chính xác để quan sát dữ liệu cực trị như đã thu thập, giả định giả thuyết không về tính độc lập là đúng.

Ví dụ, một nhà phân tích có thể dùng kiểm định chính xác Fisher khi đánh giá hiệu quả của một chiến dịch marketing nhắm chọn. Nếu phân tích hiệu quả giữa email và mạng xã hội đối với một nhóm khách hàng ngách có cỡ mẫu nhỏ, người đó có thể lập bảng chéo và chạy kiểm định Fisher. Hoặc trong bối cảnh kiểm soát chất lượng, nhà phân tích có thể dùng kiểm định này để xử lý các thách thức trong báo cáo sự cố và theo dõi lỗi. Khi một số loại hỏng hóc chỉ xảy ra vài lần, kiểm định chính xác Fisher có thể đánh giá liệu các yếu tố như loại máy có thực sự liên quan đến việc xuất hiện lỗi hay không.

Lý thuyết thống kê và nền tảng toán học

Sau khi đã có trực giác về tầm quan trọng của kiểm định, chúng ta có thể chính thức hóa nó. Cốt lõi, kiểm định chính xác Fisher là một phương pháp thống kê dùng để xác định liệu có mối liên hệ không ngẫu nhiên giữa hai biến phân loại hay không. Nó thường được áp dụng cho các bảng chéo 2×2 để so sánh hai nhóm trên hai kết quả, ví dụ, “điều trị so với đối chứng” trên “cải thiện so với không cải thiện.”

Thú vị là nguồn gốc của nó bắt nguồn từ một trong những câu chuyện nổi tiếng nhất trong thống kê, được biết đến là thí nghiệm “quý cô nếm trà”. Sir Ronald A. Fisher thiết kế một thí nghiệm để đánh giá tuyên bố của Tiến sĩ Muriel Bristol rằng bà có thể phân biệt được liệu sữa hay trà được rót vào cốc trước chỉ bằng vị giác. Trong thí nghiệm, Fisher sắp xếp tám cốc và yêu cầu bà xác định cốc nào “sữa trước” và cốc nào “trà trước”. Do cỡ mẫu nhỏ, Fisher đã phát triển một phương pháp chính xác để xác định liệu khuôn mẫu phán đoán đúng có thể xảy ra do ngẫu nhiên hay không, đặt nền móng cho những gì ngày nay chúng ta gọi là kiểm định chính xác Fisher.

Trong các tình huống dữ liệu hạn chế, mất cân bằng hoặc khó thu thập, tương tự nghiên cứu lâm sàng, kiểm định Fisher giúp xác định liệu điều trị và kết cục có liên hệ một cách có ý nghĩa hay không. Sinh thái học, dịch tễ học, di truyền học và kiểm soát chất lượng là những lĩnh vực có dữ liệu thưa và dựa vào kiểm định này.

Kiểm định chính xác Fisher đánh giá tính độc lập bằng cách tính các xác suất siêu bội chính xác. Đối với một bảng 2×2:

 

Nhóm B1

Nhóm B2

Tổng

Nhóm A1

a

b

a+b

Nhóm A2

c

d

c+d

Tổng

a+c

b+d

n

Xác suất quan sát đúng cấu hình đó dưới giả thuyết không (không có liên hệ) được tính bằng phân phối siêu bội:

Có thể kiểm định một phía, chẳng hạn trả lời “A1 có khả năng xảy ra ở B1 cao hơn B2 không?” hoặc hai phía: “Bất kỳ mối liên hệ nào?”. Không giống các xấp xỉ mẫu lớn (ví dụ, chi-bình phương), phương pháp Fisher đảm bảo độ chính xác ngay cả khi tần suất kỳ vọng thấp.

Giả định và điều kiện tiên quyết

Để áp dụng kiểm định chính xác Fisher, chúng ta cần các điều kiện sau.

  • Dữ liệu phải là phân loại
  • Trình bày trong bảng chéo 2×2
  • Các quan sát độc lập
  • Tổng hàng và cột cố định dưới giả thuyết không

Kiểm định Fisher được ưu tiên khi bất kỳ tần suất kỳ vọng nào trong lưới rất thấp (dưới 5), hoặc kết quả thưa thớt hay mất cân bằng mạnh.

Kiểm định chính xác Fisher trong Python

Giả sử chúng ta kiểm định liệu một loại thuốc cải thiện hồi phục hay không:

 

Hồi phục

Không hồi phục

Tổng

Điều trị

8

2

10

Đối chứng

4

11

15

Tổng

12

13

25

Giả thuyết như sau:

  • H₀: Điều trị và hồi phục độc lập nhau
  • H₁: Điều trị cải thiện hồi phục (một phía)

Và đây là cách tôi xem xét trong Python:

from scipy.stats import fisher_exact

# Construct contingency table
table = [[8, 2],
         [4, 11]]

oddsratio, p_value = fisher_exact(table, alternative='two-sided')
print("Odds Ratio:", oddsratio)
print("Two-sided p-value:", round(p_value, 2))

# One-sided test (treatment better)
_, p_value_one = fisher_exact(table, alternative='greater')
print("One-sided p-value:", round(p_value_one, 2))
Odds Ratio: 11.0
Two-sided p-value: 0.02
One-sided p-value: 0.01

Giá trị p nhỏ 0,02 gợi ý có mối liên hệ thực sự giữa điều trị và hồi phục.

Bây giờ, hãy lấy một ví dụ thực tế dùng dữ liệu công khai NHANES 2017–2018 để xem xét mối liên hệ giữa “tình trạng hút thuốc hiện tại” và “từng được thông báo mắc hen suyễn” ở người trưởng thành.

Các tệp sử dụng (đều từ trang chính thức của NHANES):

  • DEMO_J.XPT — Nhân khẩu học (tuổi, giới, trọng số, v.v.)

  • SMQ_J.XPT — Hút thuốc - Sử dụng thuốc lá (lịch sử và hiện trạng hút thuốc)

  • MCQ_J.XPT — Tình trạng y tế (bao gồm "từng được thông báo mắc hen suyễn")

Dưới đây là các bước chúng ta sẽ thực hiện:

  1. Tải xuống và nạp các bộ dữ liệu

  2. Tạo các biến nhị phân:

    1. current_smoker (có/không)

    2. asthma_ever (có/không)

  3. Xây dựng bảng chéo 2×2

  4. Chạy kiểm định chính xác Fisher (hai phía và một phía)

  5. Tính khoảng tin cậy 95% cho tỉ số odds

  6. Diễn giải kết quả

Lưu ý: Phân tích NHANES đúng cần có trọng số khảo sát và thiết kế phức tạp.

Ở đây, chúng ta bỏ qua trọng số cho mục đích giảng dạy. Hãy import các thư viện cần thiết.

# %% Imports
import pandas as pd
import numpy as np
from scipy.stats import fisher_exact
from statsmodels.stats.contingency_tables import Table2x2

Hãy tải thủ công các tệp XPT từ CDC và đặt chúng trong thư mục cục bộ data/:

  • Truy cập:

    • Nhân khẩu học: Dữ liệu Nhân khẩu học 2017–2018 (DEMO_J)

    • Tình trạng y tế: MCQ_J

    • Hút thuốc - Sử dụng thuốc lá: SMQ_J

  • Tải xuống:

    • DEMO_J Data [XPT]

    • MCQ_J Data [XPT]

    • SMQ_J Data [XPT]

  • Lưu với tên:

    • data/DEMO_J.XPT

    • data/MCQ_J.XPT

    • data/SMQ_J.XPT

# Set paths or URLs here.
# If you've downloaded locally, point to the local paths:
DEMO_PATH = "data/DEMO_J.XPT"
MCQ_PATH  = "data/MCQ_J.XPT"
SMQ_PATH  = "data/SMQ_J.XPT"

# If you prefer to read directly from URLs, uncomment these instead:
# DEMO_PATH = "https://wwwn.cdc.gov/Nchs/NHanes/2017-2018/DEMO_J.XPT"
# MCQ_PATH  = "https://wwwn.cdc.gov/Nchs/NHanes/2017-2018/MCQ_J.XPT"
# SMQ_PATH  = "https://wwwn.cdc.gov/Nchs/NHanes/2017-2018/SMQ_J.XPT"

# Read SAS transport (.XPT) files
demo = pd.read_sas(DEMO_PATH, format="xport")
mcq  = pd.read_sas(MCQ_PATH,  format="xport")
smq  = pd.read_sas(SMQ_PATH,  format="xport")
demo.head()

mcq.head()

smq.head()

Hãy xem một số biến chính trong các DataFrame này. Ở đây, SEQN là mã số người trả lời và có thể dùng làm khóa nối.

# %% Inspect key variables

# SEQN is the respondent ID present in all three files.
# Check columns and pick what we need:
print("DEMO columns (subset):", demo.columns[:10])
print("MCQ columns (subset):", mcq.columns[:10])
print("SMQ columns (subset):", smq.columns[:10])
DEMO columns (subset): Index(['SEQN', 'SDDSRVYR', 'RIDSTATR', 'RIAGENDR', 'RIDAGEYR', 'RIDAGEMN',
       'RIDRETH1', 'RIDRETH3', 'RIDEXMON', 'RIDEXAGM'],
      dtype='object')
MCQ columns (subset): Index(['SEQN', 'MCQ010', 'MCQ025', 'MCQ035', 'MCQ040', 'MCQ050', 'AGQ030',
       'MCQ053', 'MCQ080', 'MCQ092'],
      dtype='object')
SMQ columns (subset): Index(['SEQN', 'SMQ020', 'SMD030', 'SMQ040', 'SMQ050Q', 'SMQ050U', 'SMD057',
       'SMQ078', 'SMD641', 'SMD650'],
      dtype='object')

Hãy lọc các cột cần thiết và cũng lọc theo tuổi (trên 20). 

# %% Keep only necessary variables and filter adults

demo_sub = demo[["SEQN", "RIDAGEYR", "RIAGENDR"]].copy()
mcq_sub  = mcq[["SEQN", "MCQ010"]].copy()
smq_sub  = smq[["SEQN", "SMQ040"]].copy()

# Merge on SEQN (inner join: keep only participants present in all three files)
df = (
    demo_sub
    .merge(mcq_sub, on="SEQN", how="inner")
    .merge(smq_sub, on="SEQN", how="inner")
)
# Restrict to adults aged 20+
df = df[df["RIDAGEYR"] >= 20].copy()
df.head()

MCQ010 đại diện cho bệnh nhân có tình trạng Hen suyễn, trong đó giá trị 1 là Có và 2 là Không. Tương tự, SMQ040 cho biết người trả lời có hút thuốc hay không. 

# %% Recode variables into binary indicators

# 1. Asthma: MCQ010
#    1 = Yes, 2 = No, 7 = Refused, 9 = Don't know
#    We'll create asthma_ever: 1 = yes, 0 = no, NaN otherwise

df["asthma_ever"] = np.nan
df.loc[df["MCQ010"] == 1, "asthma_ever"] = 1
df.loc[df["MCQ010"] == 2, "asthma_ever"] = 0

# 2. Current smoker: SMQ040
#    1 = Every day, 2 = Some days, 3 = Not at all, 7/9 = missing
#    We'll create current_smoker: 1 = yes (1 or 2), 0 = no (3), NaN otherwise

df["current_smoker"] = np.nan
df.loc[df["SMQ040"].isin([1, 2]), "current_smoker"] = 1
df.loc[df["SMQ040"] == 3, "current_smoker"] = 0

# Drop rows with missing recodes
df_clean = df.dropna(subset=["asthma_ever", "current_smoker"]).copy()
df_clean[["RIDAGEYR", "MCQ010", "asthma_ever", "SMQ040", "current_smoker"]].head()

Chúng ta tạo các cột mới, asthma_ever và current_smoker

Hãy tạo bảng chéo để có thể dùng Kiểm định chính xác Fisher.

# %% Build a 2×2 contingency table

# Ensure ints
df_clean["asthma_ever"] = df_clean["asthma_ever"].astype(int)
df_clean["current_smoker"] = df_clean["current_smoker"].astype(int)

contingency = pd.crosstab(
    df_clean["current_smoker"],
    df_clean["asthma_ever"],
    rownames=["Current smoker (1=yes,0=no)"],
    colnames=["Ever told asthma (1=yes,0=no)"]
)
contingency

Chuyển bảng chéo thành mảng NumPy.

# %% Fisher's Exact Test

# Convert to 2x2 numpy array with explicit ordering:
# rows: [non-smoker, smoker] ; cols: [no asthma, asthma]
table = np.array([
    [contingency.loc[0, 0], contingency.loc[0, 1]],
    [contingency.loc[1, 0], contingency.loc[1, 1]]
])

table
array([[1102,  226],
       [ 832,  172]])

Cuối cùng, chạy kiểm định Fisher hai phía và một phía.

# Run Fisher's exact test (two-sided and one-sided)
oddsratio, p_two_sided = fisher_exact(table, alternative="two-sided")
_, p_smoker_higher_asthma = fisher_exact(table, alternative="greater")
_, p_smoker_lower_asthma  = fisher_exact(table, alternative="less")

print("2x2 table (rows: non-smoker, smoker; cols: no asthma, asthma)")
print(table)
print()
print(f"Odds ratio (Fisher): {oddsratio:.3f}")
print(f"Two-sided p-value: {p_two_sided:.5f}")
print(f"One-sided p-value (H1: smokers have higher asthma odds): {p_smoker_higher_asthma:.5f}")
print(f"One-sided p-value (H1: smokers have lower asthma odds): {p_smoker_lower_asthma:.5f}")
2x2 table (rows: non-smoker, smoker; cols: no asthma, asthma)
[[1102  226]
 [ 832  172]]

Odds ratio (Fisher): 1.008
Two-sided p-value: 0.95571
One-sided p-value (H1: smokers have higher asthma odds): 0.49274
One-sided p-value (H1: smokers have lower asthma odds): 0.55144

Giá trị p cao cho thấy không có bằng chứng về mối liên hệ có ý nghĩa thống kê giữa việc hút thuốc hiện tại và từng được chẩn đoán hen suyễn trong mẫu này.

Tỉ số odds xấp xỉ 1 có nghĩa là người hút thuốc hiện tại có khả năng báo cáo chẩn đoán hen suyễn gần như tương đương với người không hút thuốc. Bất kỳ khác biệt nào quan sát được đều nằm trong phạm vi có thể xảy ra do ngẫu nhiên.

So sánh với các phương pháp thống kê thay thế

Các kiểm định thống kê khác nhau được dùng để phân tích mối quan hệ trong bảng chéo tùy thuộc vào kích thước mẫu, cấu trúc dữ liệu và giả định:

Kiểm định chính xác Fisher

Phù hợp nhất với mẫu nhỏ và khi một số ô có tần suất kỳ vọng thấp. Cung cấp giá trị p chính xác, rất đáng tin cậy, nhưng có thể chậm khi bảng lớn.

Kiểm định chi-bình phương

Lựa chọn tiêu chuẩn cho kích thước mẫu lớn. Nhanh, phổ biến và dễ áp dụng, nhưng trở nên thiếu chính xác khi tần suất kỳ vọng dưới 5 do phụ thuộc vào xấp xỉ.

Kiểm định chính xác Barnard

Một lựa chọn mạnh hơn so với kiểm định Fisher trong bảng 2×2. Không giả định biên cố định, giúp kết quả nhạy hơn, nhưng phương pháp ít được triển khai rộng rãi trong phần mềm.

Kiểm định McNemar

Thiết kế cho dữ liệu phân loại bắt cặp hoặc ghép cặp (ví dụ, trước - sau điều trị trên cùng đối tượng). Tính đến sự phụ thuộc giữa các quan sát, nhưng không thể dùng khi các điểm dữ liệu độc lập.

Phương pháp

Khi nào dùng

Điểm mạnh

Hạn chế

Kiểm định chính xác Fisher

Mẫu nhỏ, tần suất kỳ vọng thấp

Giá trị p chính xác

Bảo thủ, chậm với bảng lớn

Kiểm định chi-bình phương

Kích thước mẫu lớn

Nhanh, được dùng rộng rãi

Thiên lệch khi tần suất kỳ vọng < 5

Kiểm định chính xác Barnard

Thay thế Fisher, mạnh hơn

Không bị ràng buộc bởi biên cố định

Ít phổ biến trong phần mềm

Kiểm định McNemar

Dữ liệu phân loại bắt cặp

Xử lý phụ thuộc

Không dùng cho mẫu độc lập

Cân nhắc tính toán

Hiệu năng có thể là vấn đề với kiểm định chính xác Fisher vì phép tính mở rộng kém khi vượt ra ngoài các bảng chéo 2×2 đơn giản. Dù phần mở rộng Freeman–Halton cho phép áp dụng kiểm định cho bảng 2×3 và 3×3, chi phí tính toán tăng nhanh khi kích thước bảng lớn dần. Do đó, các thuật toán hiệu quả và tối ưu hóa đặc biệt quan trọng trong các lĩnh vực như di truyền học và nghiên cứu lâm sàng, nơi kiểm định chính xác có thể cần thực hiện lặp lại trên nhiều bộ dữ liệu nhỏ nhưng phức tạp.

Diễn giải và báo cáo thống kê

Khi diễn giải và báo cáo kết quả kiểm định chính xác Fisher, điều quan trọng là nêu giá trị p chính xác, cung cấp tỉ số odds cùng khoảng tin cậy 95%, và nêu rõ đã thực hiện kiểm định một phía hay hai phía. Kết quả cũng nên được đặt trong ngữ cảnh thực tiễn để giúp người đọc hiểu ý nghĩa trong đời sống. Ví dụ, có thể viết: “Kiểm định chính xác Fisher cho thấy mối liên hệ có ý nghĩa giữa điều trị và hồi phục (OR=11,0, p=0,02, hai phía).”

Mở rộng và ứng dụng nâng cao

Các phần mở rộng và ứng dụng nâng cao của kiểm định chính xác Fisher giúp xử lý các kịch bản dữ liệu phức tạp hơn và cải thiện độ chính xác khi làm việc với bộ dữ liệu nhỏ hoặc thưa. Phần mở rộng Freeman–Halton cho phép áp dụng kiểm định cho các bảng chéo lớn hơn ngoài định dạng 2×2 tiêu chuẩn, như 2×3 hoặc 3×3. Kiểm định mid-P exact là một lựa chọn ít bảo thủ hơn so với Fisher, cải thiện lực kiểm định trong khi vẫn đảm bảo độ tin cậy. Các kiểm định Bayesian exact đưa kiến thức tiên nghiệm vào phân tích, đặc biệt hữu ích khi dữ liệu hạn chế hoặc khi phán đoán chuyên gia có thể định hướng suy luận. Ngoài ra, các phương pháp hiệu chỉnh sai lệch cho tỉ số odds giúp ước lượng kích thước hiệu ứng chính xác hơn trong các nghiên cứu có cỡ mẫu nhỏ hoặc số đếm bằng 0, đảm bảo diễn giải tốt hơn về độ mạnh và hướng của mối liên hệ.

Hạn chế và cân nhắc phương pháp luận

Kiểm định chính xác Fisher có thể bảo thủ, điều này làm giảm lực thống kê và khiến việc phát hiện hiệu ứng thực trở nên khó hơn, đặc biệt trong các nghiên cứu nhỏ. Khi dữ liệu rất thưa, việc diễn giải kết quả có thể thách thức do khoảng tin cậy rộng và ước lượng trở nên không ổn định. Ngoài ra, áp dụng kiểm định lặp lại trên nhiều biến làm tăng nguy cơ phát hiện sai, vì vậy cần kiểm soát chặt chẽ vấn đề kiểm định đa bội.

Trực quan hóa bảng chéo

Các lựa chọn trực quan hóa tốt để trình bày kết quả bảng chéo bao gồm biểu đồ cột xếp chồng, biểu đồ cột đặt cạnh nhau và biểu đồ khảm. Những hình này giúp truyền đạt rõ mối quan hệ giữa các biến phân loại và làm cho các khuôn mẫu hay khác biệt giữa nhóm dễ diễn giải hơn.

Dưới đây là ví dụ bằng Python:

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({
    "Outcome": ["Recovered", "Not Recovered"] * 2,
    "Count": [8, 2, 4, 11],
    "Group": ["Treatment"] * 2 + ["Control"] * 2
})

sns.barplot(data=df, x="Outcome", y="Count", hue="Group")
plt.title("Treatment Outcomes")
plt.show()

Kết luận

Kiểm định chính xác Fisher vẫn là tiêu chuẩn vàng để phân tích các bộ dữ liệu phân loại nhỏ. Khởi nguồn từ một tách trà trong khu vườn, nó đã phát triển thành một công cụ quan trọng và được sử dụng rộng rãi trong y học, di truyền học, nghiên cứu đối tượng người và thí nghiệm kinh doanh.

Đăng ký lộ trình kỹ năng Nền tảng Thống kê bằng Python của chúng tôi để tiếp tục học, ngoài kiểm định giả thuyết, bạn sẽ thực hành xây dựng mô hình thống kê với hồi quy tuyến tính và logistic.

Vidhi Chugh

Tác giả

Vidhi Chugh

Tôi là một Chiến lược gia và Nhà đạo đức học về AI, làm việc tại giao điểm giữa khoa học dữ liệu, sản phẩm và kỹ thuật để xây dựng các hệ thống máy học có khả năng mở rộng. Được xếp hạng trong danh sách “Top 200 Nhà đổi mới trong Kinh doanh và Công nghệ” trên thế giới, tôi theo đuổi sứ mệnh dân chủ hóa máy học và giản lược thuật ngữ chuyên môn để mọi người đều có thể tham gia vào quá trình chuyển đổi này.

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

Kiểm định chính xác Fisher khác gì so với kiểm định chi-bình phương?

Kiểm định chính xác Fisher tính xác suất chính xác và lý tưởng cho cỡ mẫu nhỏ hoặc tần suất kỳ vọng ở ô thấp, trong khi kiểm định chi-bình phương dùng xấp xỉ mẫu lớn có thể trở nên thiếu chính xác khi tần suất kỳ vọng dưới 5.

Ứng dụng thực tiễn của kiểm định chính xác Fisher trong nghiên cứu y khoa là gì?

Thường được dùng để đánh giá hiệu quả điều trị, phân tích kết cục thử nghiệm lâm sàng, điều tra các liên hệ bệnh tật và nghiên cứu yếu tố nguy cơ di truyền — đặc biệt khi cỡ mẫu bệnh nhân nhỏ.

Kiểm định chính xác Fisher có thể dùng cho bảng chéo lớn hơn 2×2 không?

Có, kiểm định chính xác Fisher có thể được mở rộng cho các bảng lớn hơn bằng các phương pháp như phần mở rộng Freeman–Halton, dù tính toán sẽ nặng nề hơn khi kích thước bảng tăng.

Cần những giả định nào để dùng kiểm định chính xác Fisher?

Dữ liệu phải là phân loại, được tổ chức trong một bảng chéo, với các quan sát độc lập và tổng hàng, tổng cột cố định dưới giả thuyết không.

Phân phối siêu bội liên quan thế nào đến kiểm định chính xác Fisher?

Kiểm định chính xác Fisher dựa trên phân phối siêu bội để tính xác suất, mô hình hóa khả năng quan sát một cách sắp xếp số đếm cụ thể khi các tổng biên được cố định.

Chủ đề

Liên quan