Andrejs Dunkels (1939 – 1998) นักคณิตศาสตร์ชาวสวีเดนเคยพูดไว้ว่า “มันง่ายมากที่จะหลอกคนอื่นด้วยสถิติ แต่มันยากมากถ้าจะบอกเล่าความจริงโดยไม่ใช้สถิติมาช่วย” – This is so deep.

สถิติคือเครื่องมือค้นหาความจริง และคนที่เข้าใจมันจริงๆเท่านั้นถึงมีสิทธิ์เข้าถึงความจริงเหล่านั้น บทความนี้จะเล่าความจริงเกี่ยวกับค่า p-value และการทดสอบสมมติฐานด้วยระบบ null hypothesis significance testing

ก่อนจะอ่านบทความนี้ต่อ เรา assume ว่าทุกคนรู้จัก central limit theorem และการใช้ confidence interval เพื่อทดสอบสมมติฐานทางสถิติแล้ว ถ้าใครยังไม่ชัวร์ ลองอ่านบทความเก่าของเราได้เลย 😛

If you want to know the truth, let’s find the truth.

Closer to The Truth

สมมติว่าเราอยากทำ inference ศึกษาเกี่ยวกับคนไทยทั้งประเทศ (population) เราควรจะเก็บ sample size ขนาดเท่าไหร่ดี? เป็นคำถามสำคัญก่อนที่เราจะเริ่มงานวิจัยทางสถิติใดๆก็ตาม

Logic ของการกำหนดจำนวน n ก็ง่ายๆ ยิ่งเราเก็บ n ได้มากขึ้นเท่าไหร่ ก็จะยิ่งได้ผลที่เข้าใกล้ความจริงของประชากรมากขึ้นเท่านั้น (unknown parameter) การเพิ่ม sample size ในทางสถิติจะทำให้เกิดผล 3 อย่าง

  1. มั่นใจในผลได้มากขึ้น (higher confidence)
  2. ผลที่ได้มีความแม่นยำมากขึ้น (greater precision)
  3. p-value จะลดลงเรื่อยๆ (p-value is sensitive to sample size)

ทำไม n เยอะขึ้นแล้ว p-value ถึงลดลง?

p-value จะลดลงเสมอถ้า null hypothesis ที่เราตั้งไว้ตอนแรกไม่เป็นความจริง การเพิ่ม n คือการหาหลักฐานเพื่อเพิ่มโอกาสในการปฏิเสธ false hypothesis ลองดู case study ต่อไปนี้

The Truth We Never Know

Case study – จงหาความจริงว่าคนไทยนอนเฉลี่ยวันละกี่ชั่วโมง?

Image result for spider verse scene
Spider-Verse (2018)

เพื่อความสมจริงของ case study นี้ เราจะสร้าง vector ความยาว 67 ล้าน แทนชั่วโมงการนอนของคนไทยทั้งประเทศด้วยฟังชั่น rpois() และกำหนดให้ population mean (mu) = 8.0 ชั่วโมงต่อวัน

## the truth is 8 hours a day
set.seed(1)
thai_pop <- rpois(n = 67000000, lambda = 8.0)

Note – ความจริงเราไม่มีทางรู้ค่า mu ได้ เพราะว่า mu คือ unknown population parameter ถ้าเรารู้ mu ตั้งแต่แรก (i.e. สามารถเข้าถึงข้อมูลคนไทยทั้งประเทศได้) ก็ไม่มีเหตุผลให้เราต้องทำ significance test เลย

[su_label type=”important”]Important[/su_label] อ่านมาถึงตรงนี้ ทุกคนต้องแกล้งทำเป็นไม่รู้ว่า mu จริงๆมีค่าเท่ากับเท่าไร? (เพราะชีวิตจริงเราไม่มีทางรู้ค่า mu อยู่แล้ว) สมมติเรามี hypothesis ว่าคนไทยน่าจะนอนเฉลี่ยวันละ 7.5 ชั่วโมง เพราะช่วงนี้เศรษฐกิจไม่ดี คนทำงานหนักขึ้น มีเวลาพักผ่อนน้อยลง เขียนเป็น null hypothesis ในทางสถิติได้แบบนี้

  • Ho: คนไทยนอนเฉลี่ยเท่ากับ 7.5 ชั่วโมงต่อวัน (mu = 7.5)
  • Ha: คนไทยนอนเฉลี่ยไม่เท่ากับ 7.5 ชั่วโมงต่อวัน (mu != 7.5)

เสร็จแล้วสุ่มตัวอย่างแบบแรนดอม n = 30 คน จากประชากรทั้งหมดในเวคเตอร์ thai_pop ที่เราสร้างขึ้นมาและทดสอบ one sample t-test เปรียบเทียบ sample mean กับค่า hypothesized mu 7.5 ที่ระดับ alpha = .05

## survey data n=30
set.seed(1)
survey <- sample(thai_pop, size = 30)

## one sample t-test
result <- t.test(x = survey, mu = 7.5, alternative = "two.sided")
cat("mean   :", mean(survey),
    "\np-value:", result$p.value,
    "\n95% CI :", round(result$conf.int, 2))

Test result ได้ค่า mean = 7.9333, p-value = 0.3686 และ 95% CI = [6.96, 8.90] เราไม่สามารถปฏิเสธ null hypothesis mu = 7.5 ได้ เพราะค่า p-value > .05 และค่า null ตกอยู่ในช่วงความเชื่อมั่นที่เราสร้างขึ้นมาพอดี

ที่ n=30 ช่วงความเชื่อมั่นเก็บค่า null ไม่สามารถปฏิเสธ null hypothesis ได้

แต่เด๋วก่อน! แล้วถ้าเราสุ่มตัวอย่าง n มากขึ้นเป็น 100, 300, 1000 ตามลำดับ test result จะออกมาเป็นเหมือนเดิมหรือเปล่า Let’s find out, shall we? เราจะทำการสุ่มทุกอย่างเหมือนเดิม แต่เพิ่ม sample size ↑

## increase sample size
sample_size <- c(30, 100, 300, 1000)

## loop through the t-test process
for(n in sample_size) {
    set.seed(1)
    survey <- sample(thai_pop, size = n)
    result <- t.test(x = survey, mu = 7.5, alternative = "two.sided")
    cat("\nn      :", n,
        "\nmean   :", mean(survey),
        "\np-value:", result$p.value,
        "\n95% CI :", result$conf.int, "\n")
}

แอดสรุปผล test result จากการสุ่มทั้งหมด 4 รอบในตารางด้านล่าง การเพิ่ม n ในการสุ่มแต่ละรอบ (assume ว่าการสุ่มเป็นไปอย่าง random) ค่า p-value จะลดลงเรื่อยๆ และ 95% CI จะแคบลงเรื่อยๆเช่นกัน

np-value95% CIConclusion
300.3686[6.96, 8.90]NOT significance
1000.0057[7.73, 8.82]Significance
3000.0012[7.71, 8.35]Significance
10000.0000[7.83, 8.17]Significance

แค่เพิ่ม n จาก 30 เป็น 100 เราก็สามารถปฏิเสธ null hypothesis mu = 7.5 ได้แล้ว (มีนัยสำคัญที่ระดับ alpha = .05) สรุปว่าคนไทยนอนเฉลี่ยไม่เท่ากับ 7.5 ชั่วโมงต่อวัน ทำไมถึงเป็นแบบนี้ หาคำตอบได้ในย่อหนัาถัดไป

ยิ่งเราสุ่มตัวอย่างมากขึ้น ผลสถิติของเราก็จะเข้าใกล้ความจริง mu = 8.0 มากขึ้นเรื่อยๆ

The Truth’s Revealed

Spider-Verse (2018)

p-value ไม่ใช่แค่ตัวแปรสุ่มทั่วไป แต่มันยังขึ้นอยู่กับขนาดของกลุ่มตัวอย่างที่เราสุ่มขึ้นมาอีกด้วย นักสถิติมักพูดว่า “p-value is sensitive to sample size” แต่ประโยคนี้จะเป็นจริงก็ต่อเมื่อเงื่อนไขสองข้อนี้เกิดขึ้นพร้อมกัน

  1. null hypothesis ต้องไม่ใช่เรื่องจริง i.e. false hypothesis
  2. การสุ่มตัวอย่างต้องเป็นไปอย่าง random

Case study ในบทความนี้ เราทดสอบ mu = 7.5 ทั้งๆที่ความจริง true mu = 8.0 เป็นตัวอย่างง่ายๆของการตั้ง false hypothesis ยิ่งเราเก็บ n เยอะขึ้นเท่าไหร่ โอกาสที่เราจะปฏิเสธ mu = 7.5 ก็จะมีสูงขึ้นเท่านั้น

[su_label type=”important”]Important[/su_label] และนี่คือบทสรุปของบทความนี้ จำอะไรไม่ได้ ขอให้จำตรงนี้ก็พอ 555+ การเพิ่ม sample size ส่งผลยังไงกับค่า p-value และ confidence interval บ้าง? assume ว่าการสุ่มตัวอย่างเป็นไปอย่าง random

  1. n ↑ เราก็มั่นใจในผลสถิติของเรามากขึ้นว่าไม่ใช่เรื่องฟลุ๊คๆ (greater confidence)
  2. n ↑ ช่วงความเชื่อมั่นจะแคบลง แปลว่าการทำ inference ของเราแม่นยำมากขึ้น (greater precision, closer to the truth)
  3. n ↑ p-value จะลดลงเรื่อยๆถ้า null hypothesis ที่ตั้งไว้ตอนแรกไม่ใช่เรื่องจริง เพราะว่า false hypothesis หรือความเชื่อที่ผิดจะต้องถูกปฏิเสธในที่สุด

[su_label type=”black”]Mind Blown[/su_label] แอดเขียนอธิบายมาโคตรยาว ประเด็นสำคัญของเรื่องนี้อยู่ที่ null hypothesis ส่วนใหญ่เป็น false hypothesis (เกือบ) ทั้งหมดเลย แปลว่า null hypothesis เกิดมาเพื่อถูกปฏิเสธ ไม่ได้เกิดมาเพื่อถูกยอมรับ และเป็นเหตุผลที่เราไม่ใช้คำว่า accept null เวลาที่ p-value > .05 หรือผลสถิติไม่มีนัยสำคัญ

Falsifiable Null Hypothesis

ลองจินตนาการถ้าวันนี้เราสามารถเข้าถึงคนไทยทั้งประเทศ 67 ล้านคน แล้วถามว่านอนวันละกี่ชั่วโมง ค่าเฉลี่ย true mu ก็มีความเป็นไปได้น้อยมากที่จะเท่ากับค่า null hypothesis ที่เรากำหนดไว้ก่อนทำ statistical test

ถึงแม้ว่าในตัวอย่างวันนี้ เราจะตั้งค่า hypothesized mu (Ho) ของเราเท่ากับ 8.00 ก็เป็นการตั้ง false hypothesis อยู่ดี ทำไม? เพราะว่า true mu ที่คำนวณจาก thai_pop ทั้งหมดเท่ากับ 8.000008 (รูปด้านล่าง)

ยิ่งในชีวิตจริงที่เราไม่มีทางรู้ค่า mu จริงๆได้เลย โอกาสที่เราจะตั้ง null hypothesis ผิดตั้งแต่แรกมีสูงมาก ซึ่งเป็นเหตุผลสำคัญที่ค่า p-value จะลดลงเรื่อยๆถ้าเราสุ่ม n มากขึ้น เหมือนตัวอย่างในบทความนี้

ถ้ายังไม่เชื่อ ลองคิดตามกรณีนี้

นักวิจัยของ facebook ทำ AB testing บนเว็บไซต์เพื่อทดสอบว่าแคมเปญ A หรือ B แบบไหนที่มีประสิทธิภาพในการเพิ่มยอด like มากกว่ากัน เขียนเป็นสมมติฐานทางสถิติได้แบบนี้

  • Ho: mean(campaign A) – mean(campaign B) = 0
  • Ha: mean(campaign A) – mean(campaign B) != 0

facebook analyst สุ่มตัวอย่างขึ้นมากลุ่มละ 1000 คน แล้วทำ significance test แต่คำถามที่เราอยากให้ทุกคนคิดดีๆ – “ถ้า facebook ทดสอบสองแคมเปญนี้กับ users ทั้งโลกได้ mean(campaign A) – mean(campaign B) จะเท่ากับศูนย์ เหมือนที่เราเขียนไว้ใน null hypothesis หรือเปล่า?” Mind Blown !!

แล้วถ้า null hypothesis ผิดตั้งแต่แรกจริงๆ เราจะพยายามทดสอบ significance test ไปเพื่อออ?

Statistical significance (p-value) บอกได้แค่ความแตกต่างนั้นมีอยู่จริงหรือเปล่า? แต่ไม่ได้บอกว่าความแตกต่างนั้นจะ make sense ในชีวิตจริงหรือเปล่า? นักสถิติยุคหลังไม่ได้สนใจแค่ค่า p-value หรือ CI อีกต่อไปแล้ว แต่เราสนใจเรื่อง practical significance มากกว่า (อยากรู้ว่าทำยังไง รออ่านได้ในบทความต่อไปของเรา)

ตอนนี้ทุกคนรู้แล้วว่าความจริงคืออะไร? Let’s use statistics wisely ขอบคุณที่อ่านจนจบ แอดไปล่ะ ฟิ้ว!

Posted by:Kasidis Satangmongkol

Data Analyst & Market Researcher ทำเพจ เขียนบล๊อก สอนหนังสือ แชร์ความรู้ เขียนโปรแกรม พูดคุยกับเราได้ที่ m.me/datarockie

4 replies on “ทำไม p-value ถึงลดลงเรื่อยๆถ้าเราเพิ่ม Sample Size?

  1. ทำไมถึงใช้ rpois() กับ parameter ที่เป็นชั่วโมงการนอนครับ

    1. The example in this post also involves surveying samples. When you ask people how many hours you sleep a day, I guess people rarely say 6.2 or 7.4 hour a night.

      ps. the distribution is the not the essence of this post, I hope you get the true essence out of it.

      1. มันคือ discrete variable ไม่ใช่ continuous variable จึงใช้ function แบบ rnorm() ไม่ได้ใช่ไหมครับ ?
        (พอดีผมเป็นมือใหม่หัดเขียน R น่ะครับ เพิ่งเรียนคอร์สออนไลน์ฟรีกับพี่ทอยจบสด ๆ ร้อน สอนดีมากครับ บทความก็เขียนดีครับ เข้าใจ concept เลยครับ ^^)

Leave a Reply