Think Stats II – chương 1

Phân tích dữ liệu khám phá

Dịch từ cuốn Think Stats: Exploratory Data Analysis in Python của Allen B. Downey, NXB Green Tea Press. Sách điện tử được phát hành miễn phí theo giấy phép: Creative Commons Attribution-NonCommercial 4.0 Unported License. Trong quá trình phân phối bạn nên ghi rõ nguồn gốc cuốn sách.

Trở về Mục lục cuốn sách

Luận điểm của cuốn sách này là dữ liệu kết hợp với các phương pháp thực dụng sẽ trả lời được các câu hỏi và dẫn dắt những quyết định trong điều kiện không chắc chắn.

Chẳng hạn, tôi xin nêu một trường hợp cụ thể đặt ra từ một câu hỏi mà tôi nghe được khi tôi cùng vợ đang chờ sinh con đầu: liệu những đứa trẻ đầu lòng có xu hướng chào đời chậm hay không?

Nếu bạn tra Google câu hỏi này, bạn sẽ tìm thấy nhiều cuộc thảo luận khác nhau. Có người cho rằng đúng, người khác cho rằng đó chỉ là tưởng tượng, và có người cho rằng phải ngược lại: bé đầu lòng sẽ ra sớm.

Trong nhiều cuộc thảo luận nói trên, có người đưa ra con số để hỗ trợ cho khẳng định của mình. Tôi đã thấy nhiều ví dụ kiểu như:

“Hai người bạn tôi gần đây vừa sinh cháu đầu, cả hai đều sinh cháu chậm 2 tuần trước khi dùng biện pháp ép sinh.”

“Cháu đầu lòng của tôi ra đời chậm 2 tuần và bây giờ đứa thứ hai sẽ ra đời sớm 2 tuần!!”

“Tôi không nghĩ rằng điều đó đúng vì chị của tôi là cả, và được ra đời sớm, và các anh chị em họ của tôi cũng vậy.”

Những thông báo kiểu này được gọi là dẫn chứng chủ quan vì chúng dựa trên số liệu chưa được công bố và thường mang tính cá nhân. Khi nói chuyện thông thường, chẳng có gì sai khi kể chuyện cá nhân như vậy, nên tôi cũng không hề có ý trách những người nêu ý kiến nói trên.

Nhưng ta có thể muốn các bằng chứng có sức thuyết phục cao hơn và câu trả lời đáng tin cậy hơn. Khi xét theo các thiêu chuẩn đó, dẫn chứng cá nhân thường không đạt, vì:

Số lần quan sát ít:
Nếu thời gian thai nghén đối với trẻ đầu lòng là lâu hơn, thì mức độ khá biệt có lẽ vẫn nhỏ so với quy luật tự nhiên vì thời gian này luôn biến động. Trong trường hợp này, có thể ta phải so sánh nhiều trường hợp thai nghén để chắc chắn rằng có sự khác biệt.
Sự thiên lệch trong lựa chọn:
Người tham gia vào cuộc tranh luận này có thể quan tâm đến câu hỏi chỉ vì con đầu lòng của họ ra đời muộn. Trong trường hợp này quá trình chọn lựa số liệu sẽ làm thiên lệch kết quả.
Sự thiên lệch khi khẳng định:
Người tin vào lời khẳng định có nhiều khả năng đóng góp những ví dụ minh chứng cho điều đó. Những người nghi ngờ về lời khẳng định có nhiều khả năng dẫn ra những phản ví dụ.
Sự không chính xác:
Các kinh nghiệm thường gắn với chuyện cá nhân, và thường bị nhớ nhầm, truyền đạt nhầm, thuật lại không chính xác, v.v.

Vậy bằng cách nào để ta làm tốt hơn?

1.1 Cách tiếp cận thống kê

Để nhận định những hạn chế của kinh nghiệm, chúng ta sẽ dùng các công cụ thống kê, bao gồm:

Thu thập số liệu:
Ta sẽ dùng số liệu từ một cuộc điều tra lớn mang tầm cỡ quốc gia, được thiết kế rõ ràng nhằm mục tiêu đưa ra những suy luận đúng đắn theo thống kê, về dân số Hoa Kỳ.
Thống kê mô tả:
Chúng ta sẽ tính ra các đặc trưng thống kê để có thể tóm gọn được số liệu, và đánh giá những cách khác nhau để hiển thị số liệu.
Phân tích khảo sát số liệu:
Ta sẽ tìm kiếm những dạng mẫu, sự khác biệt, và những đặc điểm khác để giải đáp câu hỏi cần quan tâm. Đồng thời ta cũng kiểm tra sự không thống nhất và phát hiện ra những hạn chế.
Ước lượng:
Chúng ta sẽ dùng dữ liệu từ một mẫu để ước tính các đặc trưng của quần thể.
Kiểm định giả thiết:
Khi chúng ta thấy hiệu ứng rõ rệt, như một sự khác biệt giữa hai nhóm, ta sẽ đánh giá xem sự khác biệt đó là thực sự, hay là chỉ tình cờ diễn ra.

Bằng cách thực hiện những bước này cẩn thận để tránh những lỗi dễ mắc, ta có thể đi đến những kết luận hợp lý hơn và có nhiều khả năng sẽ đúng.

1.2 Cuộc điều tra quốc gia Hoa Kỳ về phát triển gia đình

Từ năm 1973, Trung tâm Kiểm soát và phòng chống dịch bệnh của Hoa Kỳ (U.S. Centers for Disease Control and Prevention, CDC) đã tiến hành đợt điều tra trên quy mô quốc gia về sự phát triển gia đình (National Survey of Family Growth, NSFG), vốn nhằm mục đích thu thập “thông tin về cuộc sống gia đình, kết hôn và li dị, thai nghén, vô sinh, sử dụng biện pháp tránh thai, và sức khỏe nam nữ. Kết quả của cuộc điều tra được dùng […] để hoạch định những dịch vụ chăm sóc sức khỏe và chương trình giáo dục sức khỏe, và để tiến hành nghiên cứu thống kê về gia đình, sức khỏe và khả năng sinh sản.” Xem http://cdc.gov/nchs/nsfg.htm.

Chúng ta sẽ dùng số liệu thu thập từ đợt điều tra này để xem có phải là bé đầu lòng thường hay ra đời muộn không, và cả những câu hỏi khác. Để tận dụng được số liệu này, chúng ta phải hiểu được cách thức tiến hành cuộc điều tra này.

NSFG là công trình nghiên cứu cắt ngang, tức là nó chỉ ghi nhận tình hình của hệ thống tại một thời điểm nhất định. Hình thức nghiên cứu thường gặp khác là nghiên cứu dọc, trong đó quan sát hệ thống lặp lại nhiều lần trong suốt một khoảng thời gian.

Đợt điều tra NSFG đã được tiến hành 7 lần; mỗi lần triển khai được gọi là một cycle (chu trình). Ta sẽ dùng dữ liệu từ Cycle 6, với thời gian tiến hành từ tháng 1/2002 đến 3/2003.

Mục tiêu của đợt điều tra là rút ra kết luận về một tổng thể; đối với NSFG tổng thể là cư dân Mỹ có độ tuổi từ 15 đến 44. Điều tra lý tưởng phải thu thập được dữ liệu từ tất cả mọi người trong quần thể, song hiếm khi điều này thự hiện được. Thay vào đó, ta thu thập số liệu từ một tập hợp con của quần thể, được gọi là mẫu. Những người tham gia vào cuộc điều tra được gọi là respondent (người hồi đáp).

Nhìn chung, các nghiên cứu cắt ngang nhằm mục đích đại biểu, tức là mỗi thành viên trong tổng thể cần nghiên cứu đều có cơ hội tham gia như nhau. Dĩ nhiên là điều lý tưởng đó rất khó xảy ra trên thực tế, song những người tiến hành điều tra cố gắng thực hiện điều này ở mức tốt nhất có thể.

NSFG không có tính đại biểu; nó được cố ý lặp mẫu. Các nhà thiết kế cho đợt nghiên cứu này đã tuyển ba nhóm người—Hispanics, Mỹ-Phi và thiếu niên—với tần số cao hơn mức đại biểu của họ trong dân số Hoa Kỳ. Lý do cho việc tuyển lặp mẫu này là cần đảm bảo được số người được điều tra trong mỗi nhóm phải đủ lớn để rút ra suy luận thống kê đúng.

Dĩ nhiên, nhược điểm của lặp mẫu là không dễ để rút ra kết luận về tổng thể dựa trên con số thống kê từ cuộc điều tra. Ta sẽ trở lại vấn đề này sau.

Khi làm việc với dữ liệu kiểu này, điều quan trọng là cần quen với sổ mã hóa (codebook), vốn ghi lại cách bố trí nghiên cứu, những câu hỏi điều tra, và cách mã hóa những hồi đáp. Sổ mã hóa và tài liệu hướng dẫn dữ liệu NSFG có thể được tải về từ

http://www.cdc.gov/nchs/nsfg/nsfg_cycle6.htm

1.3  Nhập số liệu

Mã lệnh và số liệu dùng trong cuốn sách này có thể được lấy về từ https://github.com/AllenDowney/ThinkStats2. Để biết thêm thông tin liên quan đến việc tải về và thao tác với mã lệnh này, hãy xem Mục 0.2.

Một khi đã tải về mã lệnh, bạn sẽ có một file tên là ThinkStats2/code/nsfg.py. Nếu chạy nó, chương trình sẽ đọc một file số liệu, thực hiện một số kiểm tra, rồi in ra một dòng thông báo kiểu như, “All tests passed.” (Đã hoàn thành các bài kiểm tra.)

Hãy xem nó làm việc gì. Dữ liệu về mang thai từ Chu kì 6 của chương trình NSFG được đặt trong một file có tên là 2002FemPreg.dat.gz; đây là file nén dạng gzip chứa văn bản chữ (ASCII), với các cột có bề rộng cố định. Mỗi dòng trong file này là một bản ghi có chứa dữ liệu về một trường hợp mang thai.

Định dạng của file nêu trên được quy định trong 2002FemPreg.dct, vốn là một file từ điển Stata. Stata là một hệ thống phần mềm thống kê; còn “từ điển” ở đây là một danh sách các tên biến, kiểu và chỉ số để hình dung xem cần tìm mỗi biến ở đâu trên từng dòng dữ liệu.

Chẳng hạn, sau đây là một vài dòng từ file 2002FemPreg.dct:

infile dictionary {
  _column(1)  str12  caseid    %12s  "RESPONDENT ID NUMBER"
  _column(13) byte   pregordr   %2f  "PREGNANCY ORDER (NUMBER)"
}

Từ điển này mô tả hai biến: caseid là một chuỗi gồm 12 kí tự để biểu diễn mã số của người hồi đáp; pregorder là một số nguyên một byte để chỉ ca mang thai nào mà bản ghi miêu tả cho người hồi đáp này.

Đoạn mã bạn vừa tải về bao gồm thinkstats2.py, vốn là một module trong Python có chứa nhiều lớp và hàm được dùng trong sách này, gồm cả các hàm để đọc từ điển dạng Stata và file dữ liệu NSFG. Sau đây là cách sử dụng chúng trong nsfg.py:

def ReadFemPreg(dct_file='2002FemPreg.dct',
                dat_file='2002FemPreg.dat.gz'):
    dct = thinkstats2.ReadStataDct(dct_file)
    df = dct.ReadFixedWidth(dat_file, compression='gzip')
    CleanFemPreg(df)
    return df

ReadStataDct nhận tham biến là file từ điển, rồi trả lại dct, một đối tượng FixedWidthVariables có chứa thông tin từ file từ điển này. dct cung cấp hàm ReadFixedWidth, để đọc file dữ liệu nêu trên.

1.4  DataFrame (khung dữ liệu)

Kết quả của ReadFixedWidth là một DataFrame; đây là cấu trúc dữ liệu cơ bản mà pandas cung cấp. Pandas là một gói chương trình thống kê và dữ liệu Python mà ta sẽ sử dụng xuyên suốt cuốn sách này. Trong một DataFrame, mỗi bản ghi chiếm một dòng, và trong trường hợp này là mỗi ca mang thai ứng với một dòng; còn một cột ứng với mỗi biến số.

Ngoài dữ liệu, một DataFrame còn chứa các tên biến cùng kiểu của chúng; và nó cung cấp các phương thức để truy cập và sửa đổi dữ liệu.

Nếu bạn in df thì sẽ nhận được một cái nhìn sơ lược về số dòng, số cột, và hình dạng của DataFrame này, ở đây là 13593 hàng/bản ghi và 244 cột/biến.

>>> import nsfg
>>> df = nsfg.ReadFemPreg()
>>> df
...
[13593 rows x 244 columns]

Thuộc tính columns trả lại một dãy các tên cột dưới dạng chuỗi Unicode:

>>> df.columns
Index([u'caseid', u'pregordr', u'howpreg_n', u'howpreg_p', ... ])

Kết quả này là một Index, vốn là một cấu trúc dữ liệu khác trong pandas. Ta sẽ tìm hiểu thêm về Index sau, nhưng bây giờ hãy coi nó như một danh sách:

>>> df.columns[1]
'pregordr'

Để truy cập một cột trong Khung dữ liệu, bạn có thể dùng cột như một tên khóa:

>>> pregordr = df['pregordr']
>>> type(pregordr)
<class 'pandas.core.series.Series'>

Kết quả là một Series, cũng là một cấu trúc dữ liệu khác trong pandas. Một Series cũng như một danh sách Python với một số đặc tính phụ thêm khác. Khi bạn in một Series ra, bạn sẽ nhận được các chỉ số cùng giá trị tương ứng:

>>> pregordr
0     1
1     2
2     1
3     2
...
13590    3
13591    4
13592    5
Name: pregordr, Length: 13593, dtype: int64

Ở ví dụ này, các chỉ số là những số nguyên từ 0 đến 13592, nhưng nói chung thì chúng có thể thuộc bất kì kiểu dữ liệu nào cũng được.

Dòng cuối cùng bao gồm tên của biến, độ dài của Series, và kiểu dữ liệu; int64 là một trong những kiểu dữ liệu do NumPy cung cấp. Nếu bạn chạy ví dụ này trên máy tính 32-bit thì bạn có thể sẽ nhìn thấy int32.

Bạn có thể truy cập những phần tử của một Series bằng cách dùng các chỉ số và lát cắt:

>>> pregordr[0]
1
>>> pregordr[2:5]
2    1
3    2
4    3
Name: pregordr, dtype: int64

Kết quả của phép lấy chỉ số là một int64; còn kết quả của một lát cắt thì lại lại một Series khác.

Bạn cũng có thể truy cập các cột trong một Khung dữ liệu bằng cách viết dấu chấm:

>>> pregordr = df.pregordr

Cách viết này chỉ có tác dụng khi tên cột là một tên gọi hợp lệ trong Python; tên gọi này phải bắt đầu bằng một chữ cái, không được chứa dấu cách, v.v.

1.5  Các biến

Ta đã thấy hai biến trong bộ dữ liệu NSFG dataset, caseidpregordr, và cũng thấy rằng có tổng cộng là 244 biến. Để phục vụ cho việc khám phá, trong cuốn sách này tôi dùng các biến sau:

  • caseid là số thứ tự của người hồi đáp.
  • prglength là số nguyên, biểu thị số tuần của thời gian mang thai.
  • outcome là mã số nguyên chỉ kết quả của thai nghén. Số 1 để chỉ việc sinh nở thành công.
  • pregordr là số thứ tự biểu diễn lần mang thai; chẳng hạn; mang thai lần đầu ứng với số 1, lần thứ hai ứng với 2, và cứ như vậy.
  • birthord là số nguyên chỉ thứ tự của đứa trẻ sinh ra trong trường hợp còn sống; chẳng hạn khi sinh con đầu lòng thì mã số bằng 1. Nếu trường hợp ca đẻ không thành công, thì trường này sẽ được bỏ trống.
  • birthwgt_lbbirthwgt_oz chứa các phần tính theo pound và ounce (các đơn vị khối lượng) của cân nặng đứa trẻ.
  • agepreg là tuổi của người mẹ tại cuối thời kì mang thai.
  • finalwgt là trọng lượng thống kê ứng với người hồi đáp. Đó là giá trị số có phần thập phân, để chỉ [tỉ lệ] số người trong tổng dân số Hoa Kỳ được đại diện bởi người hồi đáp này. 

Nếu bạn đọc kĩ cuốn tài liệu giải thích, bạn sẽ thấy có nhiều biến trong số đó chỉ là recode, nghĩa là chúng không thuộc về dữ liệu gốc được thu thập trong cuộc điều tra, mà được tính toán từ số liệu gốc. 

Chẳng hạn, prglngth cho các đứa bé ra đời thì bằng biến số gốc wksgest (weeks of gestation, số tuần mang thai) nếu biến đó có sẵn; còn nếu chưa có sẵn thì được tính bằng mosgest * 4.33 (số tháng mang thai nhân với số tuần trong một tháng).

Các số liệu suy diễn thường dựa trên logic để kiểm tra sự thống nhất và độ chính xác của số liệu. Nói chung, dùng số liệu suy diễn là tốt trừ phi có một lý do thuyết phục để bạn tự xử lý số liệu gốc.

1.6  Chuyển đổi dữ liệu

Khi nhập vào những dữ liệu như thế này, bạn thường phải kiểm tra lỗi, xử lý các giá trị đặc biệt, chuyển dữ liệu thành các định dạng khác nhau, và thực hiện tính toán. Những thao tác này được gọi là việc làm sạch dữ liệu.

nsfg.py bao gồm CleanFemPreg, một hàm giúp làm sạch các biến mà tôi dự định sẽ dùng đến.

def CleanFemPreg(df):
    df.agepreg /= 100.0

    na_vals = [97, 98, 99]
    df.birthwgt_lb.replace(na_vals, np.nan, inplace=True)
    df.birthwgt_oz.replace(na_vals, np.nan, inplace=True)

    df['totalwgt_lb'] = df.birthwgt_lb + df.birthwgt_oz / 16.0    

agepreg chứa tuổi người mẹ ở cuối thời kỳ mang thai. Trong file số liệu, agepreg được mã hóa bằng số các khoảng thời gian phần trăm của năm.  Bởi vậy, dòng lệnh đầu tiên có nhiệm vụ chia từng phần tử của agepreg cho 100, để trả lại số năm (dạng số thập phân).

birthwgt_lbbirthwgt_oz có chứa trọng lượng của đứa trẻ, theo số pound và số ounce, nếu ca sinh nở thành công. Ngoài ra thì con số này còn giữ vài giá trị mã hóa đặc biệt:

97 NOT ASCERTAINED
98 REFUSED  
99 DON'T KNOW

(các ý kiến phản hồi: Không chắc chắn, Từ chối không trả lời, Không biết)

Những giá trị đặc biệt được mã hóa dưới dạng số đều rất nguy hiểm bởi nếu chúng không được xử lý đúng đắn thì sẽ sinh ra các kết quả giả, như đứa trẻ nặng 99 pound. Phương thức replace nhằm thay thế những giá trị này bằng np.nan, một giá trị số thập đặc biệt biểu diễn cho “not a number” (không phải con số). Giá trị cờ inplace báo cho replace sửa đổi những Series đã có thay vì tạo nên Series mới.

Theo tiêu chuẩn số thập phân (phẩy động) IEEE, tất cả những phép toán sẽ trả lại nan nếu một đối số bất kì là nan:

>>> import numpy as np
>>> np.nan / 100.0
nan

Bởi vậy những phép tính với nan có xu hướng đúng đắn, và đa số các hàm trong pandas cũng xử lý nan được. Nhưng xử lý các số liệu bị thiếu sẽ là vấn đề mà sau này ta thường gặp.

Dòng cuối cùng trong CleanFemPreg tạo ra một cột mới, totalwgt_lb, để cộng số pound và ounce thành một con số tổng hợp tính theo pound.

Một ghi chú quan trọng: khi bạn thêm một cột mới vào một Khung dữ liệu, bạn phải dùng cú pháp từ điển, như sau 

    # CORRECT
    df['totalwgt_lb'] = df.birthwgt_lb + df.birthwgt_oz / 16.0 

chứ không phải dùng dấu chấm như thế này:

    # WRONG!
    df.totalwgt_lb = df.birthwgt_lb + df.birthwgt_oz / 16.0 

Cách viết với dấu chấm vẫn bổ sung thêm một thuộc tính vào đối tượng Khung dữ liệu, song thuộc tính đó không được coi là một cột.

1.7  Kiểm chứng

Khi dữ liệu được xuất từ một môi trường phần mềm này và nhập vào một môi trường phần mềm khác, có thể sẽ xuất hiện lỗi. Và khi bạn đang làm quen dần với bộ số liệu mới, có thể bạn sẽ diễn giải số liệu một cách không đúng, hay lại dẫn đến những hiểu nhần khác nữa. Nếu dành thời gian để kiểm chứng dữ liệu hiện có, bạn hoàn toàn có thể tiết kiệm thời gian sau này và tránh được lỗi.

Một cách để kiểm chứng dữ liệu là tính ra những đặc trưng thống kê cơ bản rồi so sánh chúng với các giá trị đã được xuất bản. Chẳng hạn, cuốn sách giải thích mã hóa NSFG bao gồm các bảng tóm lược từng biến. Sau đay là bảng của biến outcome, biến mã hóa kết quả của từng trường hợp mang thai:

value label           Total
1 LIVE BIRTH              9148
2 INDUCED ABORTION        1862
3 STILLBIRTH               120
4 MISCARRIAGE             1921
5 ECTOPIC PREGNANCY        190
6 CURRENT PREGNANCY        352

(Ý nghĩa các giá trị: ca sinh thành công, phá thai, thai chết yểu, hư thai, thai ngoài tử cung, hiện đang mang thai)

Lớp Series cung cấp một phương thức, value_counts, để đếm số lần mỗi giá trị xuất hiện. Nếu chọn Series outcome từ Khung dữ liệu, ta có thể dùng value_counts để so sánh với dữ liệu đã công bố:

>>> df.outcome.value_counts().sort_index()
1    9148
2    1862
3     120
4    1921
5     190
6     352

Kết quả của value_counts là một Series; sort_index có nhiệm vụ sắp xếp Series theo chỉ số, bởi vậy các giá trị đã xuất hiện theo thứ tự.

Khi so sánh kết quả này với bảng được công bố, có vẻ như những giá trị trong outcome đều đúng. Tương tự, đây là bảng được công bố cho biến birthwgt_lb

value label                  Total
. INAPPLICABLE            4449
0-5 UNDER 6 POUNDS          1125
6 6 POUNDS                2223
7 7 POUNDS                3049
8 8 POUNDS                1889
9-95 9 POUNDS OR MORE         799

Và sau đây là các số đếm giá trị:

>>> df.birthwgt_lb.value_counts(sort=False)
0        8
1       40
2       53
3       98
4      229
5      697
6     2223
7     3049
8     1889
9      623
10     132
11      26
12      10
13       3
14       3
15       1
51       1

Các số đếm với 6, 7, và 8 pound đều thỏa mãn. Và nếu bạn cộng lại các số từ 0-5 và từ 9-95, thì chúng cũng thỏa mãn. Nhưng nếu nhìn kĩ lại, bạn sẽ phát hiện ra một giá trị phải là lỗi, trẻ sơ sinh nặng 51 pound!

Để xử lý lỗi này, tôi đã thêm một dòng lệnh vào trong CleanFemPreg:

df.birthwgt_lb[df.birthwgt_lb > 20] = np.nan

Dòng lệnh này thay thế những giá trị không đúng bằng np.nan. Biểu thức trong ngoặc cho một Series có kiểu bool, trong đó True để chỉ rằng điều kiện là đúng. Khi một Series kiểu bool được dùng làm chỉ số, thì nó chỉ chọn ra những phần tử nào thỏa mãn điều kiện nêu ra. 

1.8 Diễn giải

Để làm việc với dữ liệu một cách hiệu quả, cùng lúc bạn phải nghĩ ở hai cấp độ: cấp độ thống kê và cấp độ tình huống.

Lấy ví dụ, ta hãy xem một chuỗi những kết quả thu được từ những hồi đáp. Vì cách thức tổ chức file dữ liệu, nên ta phải thực hiện xử lý đôi chút mới thu được dữ liệu về thai nghén từ mỗi phản hồi. Sau đây là một hàm thực hiện công việc trên:

def MakePregMap(df):
    d = defaultdict(list)
    for index, caseid in df.caseid.iteritems():
        d[caseid].append(index)
    return d

df là Khung dữ liệu chứa dữ liệu thai nghén. Phương thức iteritems duyệt theo chỉ số (số thứ tự dòng) và mã caseid cho từng ca.

d là một từ điển có nhiệm vụ ánh xạ mỗi số thứ tự tự ca đến một danh sách các chỉ số. Nếu bạn chưa quen với defaultdict, thì hãy tìm nó trong module collections của Python. Bằng cách dùng d, ta có thể tra tìm một người hồi đáp và lấy các chỉ số về những lần mang thai của người hồi đáp đó.

Ví dụ sau đây sẽ tra tìm một người hồi đáp rồi in ra tất cả những kết quả những lần mang thai của cô ta:

>>> caseid = 10229
>>> indices = preg_map[caseid]
>>> preg.outcome[indices].values
[4 4 4 4 4 4 1]

indices là danh sách các chỉ số của những trường hợp mang thai tương ứng với người hồi đáp thứ 10229.

Bằng cách dùng danh sách này như một chỉ số cho preg.outcome ta sẽ chọn được các hàng đã chỉ định và cho ra một Series. Thay vì in ra toàn bộ Series, tôi chọn thuộc tính values, vốn là một ma trận NumPy.

Mã số 1 trong kết quả biểu diễn cho ca sinh thành công. Mã số 4 biểu diễn cho trường hợp hư thai, nghĩa là việc mang thai kết thúc bột phát mà không rõ nguyên nhân y tế.

Xét trên khía cạnh thống kê, trường hợp hồi đáp này không có gì quá bất thường. Việc hư thai vẫn thường xảy ra và những người hồi đáp khác cũng có thể báo cáo nhiều trường hợp hư thai.

Tuy nhiên cần nhớ trong tình huống này, dữ liệu đã kể về câu chuyện người phụ nữ đã mang thai sáu lần, và sáu lần đó đều hư thai. Lần mang thai thứ bảy, gần đây nhất, đã đem lại kết quả là ca sinh thành công. Nếu ta xét dữ liệu này với cảm xúc, thì lẽ tự nhiên sẽ thấy cảm động vì nội dung câu chuyện.

Mỗi bản ghi trong tập dữ liệu NSFG biểu diễn một người đã thật thà trả lời nhiều câu hỏi khó và mang tính cá nhân. Ta có thể dùng số liệu này để trả lời các câu hỏi thống kê về đời sống gia đình, khả năng sinh sản, và sức khỏe. Cùng lúc, ta phải có trách nhiệm nghĩ đến những người được biểu diễn bởi số liệu này, và tôn trọng họ. 

1.9  Bài tập

Bài tập 1   Trong tập dữ liệu vừa tải về, bạn sẽ tìm thấy một file có tên chap01ex.ipynb, vốn là một “notebook” (bản chép các phép tính) của IPython. Bạn có thể bật IPython notebook từ cửa sổ dòng lệnh như sau:
$ ipython notebook &

Nếu IPython đã được cài đặt, nó sẽ khởi động một server chạy trên nền và mở một trình duyệt để ta xem notebook này. Nếu chưa quen dùng IPython, bạn có thể xem qua http://ipython.org/ipython-doc/stable/notebook/notebook.html.

Bạn có thể thêm lựa chọn dòng lệnh để khiến cho các hình vẽ xuất hiện ngay trên các dòng chữ, tức là trong bản chép thay vì bật ra một cửa sổ mới:

$ ipython notebook --pylab=inline &

Hãy mở chap01ex.ipynb. Có những ô phép tính đã được điền vào đầy đủ, và bạn cần thực hiện chúng. Những ô còn lại cho bạn chỉ dẫn bài tập mà bạn cần làm. 

Một đáp án cho bài tập này ở trong file chap01soln.ipynb

Bài tập 2   Hãy tạo một file có tên chap01ex.py rồi viết mã lệnh để đọc file hồi đáp, 2002FemResp.dat.gz. Bạn có thể muốn bắt đầu từ một bản sao của file nsfg.py rồi chỉnh sửa nó. Biến pregnum là recode để chỉ người hồi đáp đã mang thai bao lần. Hãy in các số đếm chi biến này rồi so sánh chúng với kết quả đã công bố trong cuốn giải thích NSFG. Bạn cũng có thể kiểm tra chéo giữa số liệu hồi đáp và các file trường hợp mang thai bằng cách so sánh pregnum của mỗi hồi đáp với số bản ghi trong file thống kê mang thai. Bạn có thể dùng nsfg.MakePregMap để lập một từ điển với ánh xạ từ mỗi caseid đến một danh sách các chỉ số cho Khung dữ liệu mang thai.  Một đáp án cho bài tập này ở trong file chap01soln.py

 

Bài tập 3   Cách hay nhất để học môn thống kê là thực hiện một dự án mà bạn quan tâm. Liệu có một câu hỏi như “Liệu đứa trẻ đầu lòng sẽ ra đời sớm” mà bạn bạn muốn tìm hiểu? Hãy nghĩ về những câu hỏi mà cá nhân bạn thấy hay, hoặc những vấn đề chung trong tri thức nhân loại, hoặc những chủ đề gây tranh cãi, hoặc những câu hỏi có hệ quả chính trị, mà thử xem nếu bạn có thể lập câu hỏi phù hợp với phương pháp điều tra thống kê. Hãy tìm kiếm dữ liệu giúp bạn trả lời câu hỏi này. Dữ liệu được chính phủ cung cấp thường là nguồn phù hợp vì những nghiên cứu công cộng này thường công bố kết quả công khai. Bạn có thể bắt đầu từ những trang web (ở Hoa Kỳ) http://www.data.gov/, và http://www.science.gov/, còn ở Anh, http://data.gov.uk/. Hai nguồn dữ liệu mà tôi ưa thích gồm có Điều tra xã hội tổng hơp (General Social Survey) tại http://www3.norc.org/gss+website/, và Điều tra xã hội Châu Âu (European Social Survey) tại http://www.europeansocialsurvey.org/.Nếu dường như có ai đó đã trả lời câu hỏi của bạn rồi, thì hãy xét kĩ xem trả lời như vậy đã thỏa đáng chưa. Có thể còn lỗi trong dữ liệu hoặc phép phân tích khiến cho kết luận không đáng tin cậy. Trong trường hợp như vậy, bạn có thể thực hiện một phân tích khác trên cùng dữ liệu đó, hoặc tìm nguồn dữ liệu khác tốt hơn.

Nếu bạn tìm thấy một bài báo đã công bố và giải đáp câu hỏi của bạn rồi, thì bạn sẽ có thể lấy được dữ liệu gốc. Nhiều tác giả đã công bố dữ liệu lên mạng rồi, song với dữ liệu mang tính nhạy cảm, bạn có thể phải viết thư đến cho tác giả bài báo, cho họ biết bạn định dùng dữ liệu thế nào, và chấp thuận một số điều khoản sử dụng nhất định. Hãy kiên nhẫn! 

1.10 Thuật ngữ

chứng cứ kinh nghiệm (anecdotal evidence):
Chứng cứ, thường thuộc về cá nhân, được thu thập tự phát thay vì theo một kế hoạch được thiết kế cẩn thận.
tổng thể (population):
Nhóm được quan tâm nghiên cứu, thường là một nhóm người, nhưng thuật ngữ cũng dùng được với động vật, thực vật và khoáng chất.
nghiên cứu cắt ngang (cross-sectional study):
Nghiên cứu trong đó thu thập số liệu về một tổng thể tại một thời điểm cụ thể.
chu kì (cycle):
Trong một nghiên cứu cắt ngang, mỗi lần lặp lại nghiên cứu được gọi là một chu kì.
nghiên cứu dọc (longitudinal study):
Nghiên cứu dõi theo một tổng thể qua thời gian, thu thập số liệu về tổng thể nhiều lần.
người hồi đáp (respondent):
Người trả lời câu hỏi điều tra.
mẫu (sample):
Tập hợp con của tổng thể được dùng để thu thập số liệu.
đại biểu (representative):
Một mẫu có tính đại biểu nếu mỗi thành viên của tổng thể đều có cùng khả năng có ở trong mẫu.
lấy mẫu lặp (oversampling):
Kĩ thuật làm tăng tính đại biểu cho một tập con của tổng thể nhằm tránh lỗi gây ra do kích thước mẫu nhỏ.
bản ghi (record):
Trong một cơ sở dữ liệu, tập hợp thông tin về một cá thể được nghiên cứu.
dữ liệu gốc (raw data):
Các giá trị được thu thập và ghi lại mà không được hoặc ít được kiểm tra, tính toán hay diễn giải.
recode:
Giá trị được phát sinh bởi tính toán hoặc dùng phép logic đối với dữ liệu gốc.
làm sạch dữ liệu (data cleaning):
Các quá trình bao gồm thẩm định dữ liệu, phát hiện những sai sót, chuyển đổi giữa các dạng dữ liệu và hình thức thể hiện, v.v.

2 bình luận

Filed under Think Stats, Tin học

2 responses to “Think Stats II – chương 1

  1. Pingback: Think Stats: Phân tích dữ liệu theo hình thức khám phá bằng Python | Blog của Chiến

  2. Pingback: Think Stats II – chương 10 | Blog của Chiến

Bình luận về bài viết này