Professional Documents
Culture Documents
Kinh Tế Lượng Ứng Dụng Với R Version of 01-11-2017
Kinh Tế Lượng Ứng Dụng Với R Version of 01-11-2017
Với nhiều công cụ cho tích dữ liệu mà bạn có thể lựa chọn như Eviews, Stata, SPSS – AMOS, Excel, S-
PLUS, MATLAB thì rõ ràng câu hỏi đầu tiên là tại sao phải dùng R? Có ít nhất năm lí do để bạn lựa
chọn R.
Thứ nhất, với tư cách là một công cụ cho nghiên cứu thống kê – kinh tế lượng, năng lực phân tích của
R là không thua kém bất kì phần mềm thống kê nào hiện có, thậm chí trong nhiều tình huống còn làm
tốt hơn. Chẳng hạn, nếu phân tích dữ liệu mảng (Panel Data) thì chúng ta sẽ cân nhắc giữa Stata và
Eviews vì Stata có năng lực phân tích đa dạng và linh động hơn so với Eviews. Còn nếu bạn thực hiện
các phân tích thống kê đa biến như phân tích EFA, CFA thì bạn sẽ có xu hướng chọn Stata hoặc SPSS
– AMOS do chúng linh hoạt và tiện lợi hơn. Tuy nhiên, nếu dùng R thì bạn chẳng cần phải đắn đo về
vấn đề này: nó có thể thực hiện tất cả những phân tích mà các phần mềm thống kê thương mại trên
có thể làm và làm tốt hơn.
Thứ hai, R còn là một ngôn ngữ lập trình hoàn thiện định hướng cho tính toán thống kê, phân tích dữ
liệu. Nó cho phép bạn xây dựng những hàm, những câu lệnh chỉ để giải quyết một nhóm các nhiệm vụ
phân tích đặc thù nào đó và chia sẻ chúng trên mạng. Chẳng hạn, nếu có một kiểm định mới, một mô
hình mới về phương diện lý thuyết và được đăng trên một tạp chí chuyên nghành nào đó, bạn hoàn
toàn có thể viết một chương trình nhằm biến kiểm định mới, những mô hình mới chỉ ở dạng lý thuyết
kia thành một hàm cụ thể trong R. Nếu được kiểm tra bởi cộng đồng những người sử dụng rằng đúng
và không có lỗi, hàm mà bạn viết sẽ được thừa nhận và sử dụng rộng rãi.
Thứ ba, với tư cách là một công cụ phân tích dữ liệu nói chung, R còn là một công cụ cho Data Mining,
Big Data, Data Visualization và Machine Learning. Tôi lấy một ví dụ của Data Visualization bằng hình
ảnh ấn tượng dưới đây:
Hình ảnh này được vẽ trong R dựa trên các số liệu thu thập được về các chuyến bay của 7 hãng hàng
không lớn nhất thế giới. Dựa vào hình ảnh này các bạn có thể thấy trung tâm của cái mạng nhện này
là ở Bắc Mĩ và Châu Âu – những đầu mối nhộn nhịp nhất của vận tải hàng không. Nếu căn cứ vào màu
sắc (mỗi hãng hàng không một màu) thì bạn cũng thấy rõ ngay các thị trường chính của những hàng
không này. Suy rộng ra là, với tư cách là một nhà nghiên cứu thị trường, các xu hướng xã hội, hay buộc
dữ liệu phải lên tiếng, phải cung cấp cho ta một thông tin đáng giá nào đó thì R hoàn toàn là một công
cụ thích hợp cho bạn lựa chọn.
Một ví dụ nữa là sử dụng dữ liệu từ Google Scholar, chúng ta có thể hình ảnh hóa (Data Visualization)
về thị phần của R từ năm 1995 đến 2011 dựa trên các truy vấn tìm kiếm như sau:
Dữ liệu cần thiết đễ vẽ đồ thị trên tôi cũng gửi kèm với tài liệu này.
Thứ tư, sử dụng R trong nghiên cứu và phân tích dữ liệu là một xu hướng và ngày càng phổ biến, ít
nhất là trong nghiên cứu thống kê – kinh tế lượng. Hiện R được giảng dạy và sử dụng như một công
cụ phân tích dữ liệu ở nhiều trường đại học lớn, có uy tín trong lĩnh vực này ở Mĩ và Châu Âu. Đây
cũng là lý đo xứng đáng để bạn chọn R.
Cuối cùng, các trường đại học sớm hay muộn thì cũng không thể dùng phần mềm chùa như hiện nay
và sẽ sớm chuyển sang sử dụng các phần mềm miễn phí. Hiện nay đã có một số trường đại học sử
dụng R cho việc giảng dạy thống kê và kinh tế lượng.
Đây chắc chắn là câu hỏi mà tôi phải trả lời trước ki viết tài liệu này. Đối tượng bạn đọc mà tôi hướng
đến trước hết là các bạn học khối nghành kinh tế nói chung có nhu cầu sử dụng R như là một công cụ
nghiên cứu – thực hành thống kê cũng như kinh tế lượng. Tất nhiên bạn đọc không thuộc khối kinh
tế cũng có thể thu được nhiều lợi ích khi sử dụng tài liệu này.
Ngoài ra, nếu bạn là người phóng khoáng, ưa thích cái đẹp và sự chính xác thì chắc chắn R sẽ trở thành
người bạn đồng hành lâu dài của bạn ngay cả khi bạn chọn cho mình một nghề nghiệp mà buộc dữ
liệu phải nói điều gì đó có ích. Ví dụ, không giống như một số phần mềm thương mại khô cứng khác
(và bạn chẳng biến nó tính toán ra sao) khi thực hiện hồi quy OLS bạn cứ làm mãi mỗi một thao tác.
R thì không như vậy, cũng là hồi quy OLS nhưng bạn có thể có hàng chục cách thức khác nhau. Về sự
chính xác, theo tôi được biết thì cho đến tận phiên bản mới nhất của Stata mà tôi đang dùng (Version
14) thì khi tính R2 với dữ liệu mảng, Stata vẫn báo kết quả sai. Với R thì điều này không có. Vì bạn biết
từng bước trong tính toán nếu muốn bằng cách xem trực tiếp những dòng mã lệnh.
Trước hết cần nói rằng đây không phải là một tài liệu về kinh tế lượng. Nó là một cuốn hướng dẫn sử
dụng R với các áp dụng cho kinh tế lượng, do vậy sẽ không đề cập nhiều đến lý thuyết (mặc dù có một
số tình huống tôi cũng có nhắc lại lý thuyết). Tôi mặc định là các bạn đã có kiến thức nền tảng về thống
kê và kinh tế lượng. Ngoài ra tôi cũng khuyến cáo bạn nên sử dụng tài liệu này kèm với cuốn Giáo
Trình Kinh Tế Lượng in năm 2012 của tác giả Nguyễn Quang Dong và Nguyễn Thị Minh của Đại Học
Kinh Tế Quốc Dân (NEU) hoặc cuốn Kinh tế lượng của tác giả Nguyễn Thành Cả và Nguyễn Thị Ngọc
Miên thuộc đại học Kinh Tế Thành Phố Hồ Chí Minh (UEH).
Ngoài ra, từ chương 8 trở đi của cuốn giáo trình của NEU sử dụng nhiều dữ liệu từ cuốn sách
Introductory Econometrics: A Modern Approach của Wooldridge (2013) nên tôi cũng gửi kèm các
bạn cuốn sách này để tham khảo và đối chiếu.
Câu trả lời rất dứt khoát: không . Và tôi tin chắc là nếu bạn thành thạo R ở mức tối thiểu, bạn có xu
hướng không sử dụng các phần mềm thống kê thương mại khác. Vì sao? Vì bạn hiểu bạn đang làm gì.
Tuy nhiên là một người tự học nên tôi có một lời khuyên: R không phải là một kiểu “mì ăn liền” như
Eviews, SPSS, hay Stata – những phần mềm mà các bạn chủ yếu là kích chuột, kích chuột là có kết quả.
R có chút khắt khe hơn khi nó yêu cầu bạn hai thứ: (1) sự thận trọng trong việc gõ các câu lệnh, và (2)
tuần tự từng bước. Theo kinh nghiệm của tôi cũng như nhiều người khác, là một người mới sử dụng
R, bạn không thể nào học theo lối nhảy cóc được.
Là một tài liệu định hướng thực hành nên khía cạnh lý thuyết (nhất là các công thức, các chứng minh)
sẽ không phải là trọng tâm của tài liệu này. Trong tình huống cần tham chiếu lại lý thuyết một cách rõ
ràng tôi sẽ chỉ rõ tại số trang bao nhiêu, của cuốn sách hay nghiên cứu nào. Tất nhiên, nếu là sách
trong nước thì tôi sẽ chỉ sử để cập đến hai cuốn giáo trình kinh tế lượng của đại học Kinh Tế Quốc
Dân và Kinh Tế Thành Phố Hồ Chí Minh. Ngoài ra tôi mặc định rằng người sử dụng đã có những kiến
thức cơ bản về kinh tế lượng cũng như thống kê.
Dự kiến tôi sẽ viết tài liệu này thành hai tập. Tập một tương ứng với học phần kinh tế lượng 1 được
giảng ở NEU cũng như UEH. Tuy nhiên phần này có thêm một số nội dung mà chương trình học của
EUH không có là hồi quy phân vị, Logistic, Probit, Poisson, các mô hình có biến kiểm duyệt, mô hình
hồi quy với biến công cụ, phân tích dữ liệu bảng (hay dữ liệu tổng hợp). Tập hai tương ứng với nội
dung phân tích chuỗi dữ liệu thời gian cũng một số mô hình quen thuộc như ARCH, GARCH, VAR,
BVAR.
Một trong những nguyên tắc chủ đạo của tôi khi viết tài liệu này là sử dụng data có nguồn gốc rõ ràng
và đáng tin cậy. Điều này đảm bảo rằng các bạn có thể kiểm tra, đối chiếu các kết quả phân tích thu
được nếu cần. Một lí do nữa tôi tin rằng không thể học tốt kinh tế lượng nếu như không am hiểu ở
mức độ tối thiểu về dữ liệu mà mình đang sử dụng. Tất cả số liệu được sử dụng trong tài liệu này
các bạn có thể dễ dàng lấy trên Internet. Tuy nhiên để thuận tiện tôi gửi toàn bộ chúng cùng tài liệu
này. Cụ thể, các số liệu được sử dụng trong tài liệu này đến từ 7 nguồn chủ yếu dưới đây:
1. Các số liệu từ cuốn Giáo Trình Kinh Tế Lượng của tác giả Nguyễn Quang Dong và Nguyễn Thị
Minh của NEU ở dạng file Eviews (gửi kèm tài liệu này).
2. Các số liệu từ cuốn sách Kinh tế lượng của tác giả Nguyễn Thành Cả và Nguyễn Thị Ngọc Miên
của UEH được cung cấp tại: https://sites.google.com/site/kinhteluongttkueh/home.
3. Bộ số liệu CPS 1988 đi kèm với gói AER. Bộ số liệu engel đi kèm gói quantreg. Ngoài ra còn
có một số bộ dữ liệu khác được sử dụng và được tích hợp (có sẵn) trong một số gói phân tích
của R.
4. Một số bộ số liệu (file Stata) lấy từ cuốn Econometrics by Example in năm 2011 của Gujarati.
5. Bộ số liệu panel1.dta (file Stata) sử dụng ở chương 10 cho phân tích dữ liệu mảng lấy từ cuốn
Econometric Analysis of Panel Data in năm 2005 của Baltagi.
6. Một số bộ dữ liệu lấy từ một số giáo trình điển hình khác về kinh tế lượng như cuốn
Introductory Econometrics: A Modern Approach ấn bản năm 2013 của Wooldridge, cuốn
Applied Logistic Regression ấn bản năm 2013 của Hosmer và Lemeshow và một số sách
khác. Các dữ liệu này ở dạng file Stata.
7. Một số bộ dữ liệu từng được sử dụng trong một số nghiên cứu của nước ngoài và được sử
dụng lại bởi nhiều cuốn giáo trình kinh tế lượng trên thế giới.
Trước khi công bố tài liệu này tôi cũng gửi cho nhiều bạn đọc thẩm định trước. Ý kiến phản hồi về tài
liệu chủ yếu là ở hai khía cạnh sau.
Một là, văn phong bình dân với bằng chứng từ việc sử dụng nhiều đại từ “chúng ta”, “các bạn”. Việc
này tôi cũng có cân nhắc trước khi viết. Sự thực là thay vì viết “Chúng ta có thể tính kiểm định F trực
tiếp như sau..” bằng “Tính trực tiếp kiểm định F như sau..” là việc tôi có thể làm được. Nhưng tôi thấy
viết kiểu đó tài liệu trở nên “kém thân thiện”. Tôi hoàn toàn có thể viết tài liệu theo xung hướng trang
trọng điển hình của các sách giáo trình. Tuy nhiên, tôi thích kiểu “thân thiện” hơn nên sẽ vẫn để
nguyên phong cách ngôn ngữ như vậy. Có lẽ tôi bị ảnh hưởng từ A. Field – một trong số các tác giả
yêu thích. Chẳng hạn, một trong các cuốn sách thống kê của tác giả này có tên Discovering statistics
using SPSS: (and sex and drugs and rock 'n' roll) – dịch ra là : Khám phá thống kê sử dụng SPSS: (và
tình dục, ma túy, nhạc Rock – Roll).
Hai là, giải thích chi tiết quá. Về điểm này tôi cần giải thích như sau. Đối tượng bạn đọc của tài liệu này
có thể có mức độ học và hiểu thống kê – kinh tế lượng ở các mức độ khác nhau: từ những người được
đào tạo bài bản về thống kê – kinh tế lượng như ở khoa Toán của đại học Kinh Tế Quốc Dân cho đến
những bạn đọc không chuyên về thống kê như tôi. Nên viết chi tiết, nhất là ở khía cạnh thực hành, là
điều tôi muốn hướng tới. Điều này còn dựa trên kinh nghiệm của chính bản thân tôi khi học cách sử
dụng R: một lỗi rất nhỏ trong thao tác có thể làm cho một câu lệnh hay toàn bộ một chương trình
không vận hành. Mà có thể tìm mãi cũng không ra. Bạn đọc có thể thấy điều này về cuốn sách về R
vừa được tái bản ở Việt Nam của T.S Nguyễn Văn Tuấn (in cuối năm 2015). Rõ ràng ông có thể viết
cuốn sách ngắn cô đọng hơn. Nhưng ông không làm thế.
Dù đã rất cẩn thận và cố gắng, tôi tin chắc tài liệu này còn có thiếu sót. Do vậy tôi rất mong nhận được
bất kì phản hồi nào của các bạn về tài liệu. Dựa trên những phản hồi ấy tôi sẽ hiệu chỉnh và hoàn thiện
hơn tài liệu cho những lần đánh máy sau.
Trong tình huống các bạn gặp trục trặc (như thiếu data chẳng hạn) hay có bất kì phê phán nào đối với
tài liệu, các bạn có thể nhận được hỗ trợ và phản hồi một cách nhanh chóng nhất có thể từ tôi qua ba
cách thức sau (theo thứ tự ưu tiên và cập nhật giảm dần):
1. Website gồm các bài viết về phân tích dữ liệu nói chung và kinh tế lượng nói riêng tại:
http://rpubs.com/chidungkt. Các bài viết ở mục này sẽ có nhãn KTLR và các bạn có thể phản
hồi ngay lập tức. Tôi sẽ cố gắng cập nhật, trả lời phản hồi nhanh nhất có thể.
2. Gửi câu hỏi đến địa chỉ: https://phantichdinhluong.wordpress.com/. Đây là Blog của tôi được
thành lập để chúng ta trao đổi mọi thắc mắc về R. Do tôi chưa có kinh nghiệm dùng Blog nên
giao diện của nó còn chưa tiện dụng và xấu. Tuy nhiên cái đó không quan trọng vì chắc chắn
nó sẽ được cải thiện. Cách này được khuyến khích.
3. Tài liệu này luôn được làm mới và cập nhật cứ 2 tháng mỗi lần tại:
http://www.mediafire.com/download/3lg8bsfbu6csq8d/KinhTeLuongUngDungVoiR.rar
Lời cảm ơn
Tất nhiên, mọi thứ không thể được xây dựng từ chân không. Người viết tài liệu này được hưởng lợi
từ sự động viên, định hướng, công sức và sự nhiệt tình của nhiều người và do vậy tôi muốn nói lời
cảm ơn chân thành tới họ. Trước hết, đó là Thầy Lê Đức Hoàng (Viện Ngân Hàng – Tài Chính, đại học
Kinh Tế Quốc Dân) – người đã giúp đỡ tôi nhiều mặt (và cũng là một người bạn). Thầy đã tạo cho tôi
sự chú ý đối với R thông qua cuốn sách tuyệt vời Analysis of Financial Time Series của Ruey S. Tsay.
Ngoài ra, tôi cũng gián tiếp được hưởng lợi từ: (1) T.S Nguyễn Văn Tuấn ở viện nghiên cứu Garvan
(Australia) – người nhiệt thành cổ vũ cho việc sử dụng R trong các nghiên cứu và phân tích bằng việc
công bố tài liệu tiếng Việt đầu tiên về R qua Blog của mình vào những năm 2004, (2) T.S Daniel
Zelterman (Yale University) – người đã gửi cho tôi rất nhiều dữ liệu từ các nghiên cứu của ông cũng
như cho cuốn Applied Multivariate Statistics with R, (3) T.S Hadley Wickham (Rice University) –
người đã hào phóng gửi cho tôi bản mềm cuốn sách ggplot2 - Elegant Graphics for Data Analysis còn
đang trong quá trình in ấn của mình mà không suy nghĩ gì về vấn đề bản quyền. Nhiều kiến thức thu
được về sử dụng gói ggplot2 từ cuốn sách này được sử dụng để viết một phần chương 3 của tài liệu.
Tôi cũng muốn nói lời cảm ơn đến bố - mẹ, những bạn bè thân hữu đã cũng tạo điều kiện và giúp đỡ
tôi hoàn thành tài liệu này mặc dù họ có thể không ý thức được điều đó.
Cuối cùng, tôi cũng muốn nói lời cảm ơn đến tất cả các bạn – những người quan tâm và sử dụng tập
tài liệu này.
Mục Lục
Chương 1: R với tư cách một công cụ nghiên cứu kinh tế lượng ...................................................... 18
1.1 Tổng quan về R ............................................................................................................................................. 18
1.2 Cài đặt R, Rstudio và các Packages cần thiết ...................................................................................... 19
1.2.1 Cài đặt R cho cho Windows ...................................................................................................... 19
1.2.2 Cài đặt Rstudio ........................................................................................................................... 20
1.2.3 Cài đặt các packages.................................................................................................................. 21
1.2.4 Yêu cầu một Package cụ thể trình diện ................................................................................. 22
1.2.5 Sử dụng Rmarkdown để trao đổi, công bố kết quả trên Internet với Rpub .................. 23
1.2.6 Cập nhật các phiên bản mới hơn của R ................................................................................. 26
1.3 Trợ giúp từ R ................................................................................................................................................. 26
1.4 Xem danh sách các gói đã cài đặt cũng như số lượng các gói của R .......................................... 29
1.5 Các quy ước khi sử R cho phân tích ...................................................................................................... 29
1.6 Tổng kết chương mở đầu ......................................................................................................................... 30
Chương 2: Môi trường làm việc trong R .................................................................................................... 30
2.1 Nhập dữ liệu trực tiếp vào R.................................................................................................................... 31
2.2 Hiệu chỉnh dữ liệu ....................................................................................................................................... 31
2.3 Đọc dữ liệu từ file sẵn có ở các định dạng khác nhau, từ các nguồn bên ngoài vào R ........ 32
2.3.1 Đọc dữ liệu từ file Eviews ........................................................................................................ 33
2.3.2 Đọc dữ liệu từ Stata................................................................................................................... 34
2.3.3 Đọc dữ liệu từ SPSS ................................................................................................................... 35
2.3.4 Đọc dữ liệu của phần mềm SAS ............................................................................................... 37
2.3.5 Đọc dữ liệu từ Excel .................................................................................................................. 37
2.3.6 Đọc dữ liệu định dạng txt ......................................................................................................... 37
2.3.7 Đọc dữ liệu định dạng csv ........................................................................................................ 38
2.3.8 Đọc nhiều file dữ liệu cùng một lúc ....................................................................................... 38
2.3.9 Đọc dữ liệu được cung cấp bởi World Bank với gói WDI .................................................. 40
2.3.9.1 Giới thiệu về các số liệu được cung cấp bởi WB ............................................................. 40
2.3.9.2 Lấy các dữ liệu cung cấp bởi WB vào R với gói WDI ...................................................... 41
2.3.10 Đọc dữ liệu tài chính từ Internet với gói quantmod ........................................................ 47
2.3.11 Đọc dữ liệu kích thước lớn ................................................................................................... 52
2.4 Quản lý dữ liệu, đổi tên, hiệu chỉnh dữ liệu bằng các hàm của gói base .................................. 54
2.14 Lưu ý khi gặp tình huống cùng một tên hàm tồn tại ở hai hay nhiều gói ............................. 96
Chương 3: Các thống kê mô tả và hình hóa dữ liệu với R ..................................................................... 97
3.1 Thực hiện các thống kê mô tả trong R.................................................................................................. 97
3.1.1 Thống kê mô tả với các hàm sẵn có trong R ......................................................................... 97
3.1.2 Thống kê mô tả chi tiết với gói pastecs ................................................................................. 99
3.1.3 Thống kê mô tả chi tiết với gói stargazer ........................................................................... 100
3.1.4 Thống kê mô tả chi tiết với gói fBasics ................................................................................ 101
3.2 Tìm các giá trị thống kê và mức xác suất của phân phối N, t, F,và χ2 ...................................... 102
3.2.1 Phân phối chuẩn N .................................................................................................................. 102
3.2.2 Phân phối Student t ................................................................................................................. 104
3.2.3 Phân phối F ............................................................................................................................... 106
3.2.4 Phân phối χ2 ............................................................................................................................. 107
3.3 Vẽ các Graph và đồ thị trong R .............................................................................................................. 108
3.3.1 Các Graphs với gói mặc định graphics của R ...................................................................... 108
3.3.1.1 Vẽ Scatter Plot .................................................................................................................... 108
3.3.1.2 Histogram ........................................................................................................................... 110
3.3.1.3 Hàm mật độ xác suất Density .......................................................................................... 112
3.3.1.4 Boxplots .............................................................................................................................. 113
3.3.1.5 Biểu đồ cột .......................................................................................................................... 118
3.3.1.6 Pie Chart ............................................................................................................................. 120
3.3.1.7 Biểu đồ đường ................................................................................................................... 122
3.3.1.8 Trình bày nhiều Graphs trên cùng một cửa sổ hiển thị trong R ................................ 123
3.3.2 Các Graphs với gói ggplot2 .................................................................................................... 123
3.3.2.1 Vẽ Scatter Plot .................................................................................................................... 124
3.3.2.2 Vẽ đường hồi quy .............................................................................................................. 125
3.3.2.3 Vẽ Histogram ..................................................................................................................... 127
3.3.3.4 Boxplots .............................................................................................................................. 128
3.3.2.5 Biểu đồ cột .......................................................................................................................... 130
3.3.2.6 Vẽ các đường cong hồi quy bặc hai ................................................................................ 130
3.3.2.7 Hàm mật độ xác suất Density .......................................................................................... 138
3.3.2.8 Biểu đồ đường ................................................................................................................... 140
3.3.2.9 Pie Chart ............................................................................................................................. 142
3.3.3 Hình ảnh hóa dữ liệu (Data Visualiztion) nâng cao .......................................................... 143
3.3.3.1 Trình bày nhiều Graphs trên cùng một cửa sổ hiển thị trong R với gói grid .......... 143
3.3.3.2 Vẽ thêm Histogram cho đường hồi quy với gói ggExtra ............................................. 144
3.3.3.3 Vẽ thêm hàm mật độ xác suất cho đường hồi quy với gói gridExtra ........................ 145
3.3.3.4 Vẽ thêm Boxplot cho đường hồi quy với gói gridExtra ............................................... 146
3.3.3.5 Vẽ đồ thị thị phần của R giai đoạn 1995 - 2011 ............................................................ 147
3.3.3.6 Sử dụng gói plotly tạo ra các hình ảnh tương tác ....................................................... 148
3.3.3.7 Sử dụng gói googleVis tạo ra các hình ảnh tương tác ................................................ 152
3.4 Môt số nguyên tắc của hình ảnh hóa dữ liệu của Edward Tufte ............................................... 157
3.5 Lưu các Graphs ........................................................................................................................................... 159
3.6 Mini Projects: Hình ảnh hóa dữ liệu trong thực tế ........................................................................ 160
Chương 4: Mô hình hồi quy tuyến tính hai biến số ............................................................................... 169
4.1 Một số thống kê cơ bản về bộ dữ liệu ................................................................................................. 169
4.2 Thực hiện hồi quy và một số kiểm định thường gặp .................................................................... 171
4.2.1 Hồi quy đơn, khoảng tin cậy cho các hệ số và bảng ANOVA ............................................ 171
4.2.2 Tìm các quan sát bất thường và chẩn đoán lỗi mô hình bằng hình ảnh ....................... 175
4.2.3 Thực hiện một số kiểm định thường gặp cho mô hình hồi quy ..................................... 176
4.2.3.1 Kiểm định tính phân phối chuẩn của phần dư ............................................................. 176
4.2.3.2 Kiểm định Durbin - Watson ............................................................................................. 179
4.2.3.3 Kiểm định Wald về một giá trị cụ thể của một hệ số hồi quy ...................................... 179
4.2.3.4 Kiểm định Wald đồng thời cho nhiều hệ số hồi quy ..................................................... 180
4.3 Mô phỏng Monte Carlo kiểm tra các giả thuyết CLMR .................................................................. 180
4.4 Sử dụng kết quả hồi quy cho ước lượng ........................................................................................... 183
4.5 Một số tiêu chí thường sử dụng để đánh giá chất lượng mô hình ........................................... 186
4.5.1 Tiêu chí R2 và tương quan giữa Y và Ŷ ................................................................................ 187
4.5.2 Các tiêu chí đánh giá theo phần dư ...................................................................................... 187
4.5.3 Các tiêu chuẩn thông tin AIC, SIC, và Cp của Mallow ........................................................... 187
4.5.4 Tỉ lệ sai sót huấn luyện, sai sót kiểm định và hiện tượng quá khớp ............................. 188
4.6 Đánh giá chất lượng của mô hình bằng các phương pháp tái chọn mẫu ............................... 193
4.6.1 Phương pháp Bootstrap......................................................................................................... 194
4.6.2 Phương pháp kiểm tra chéo .................................................................................................. 200
4.6.2.1 Kiểm tra chéo LOOCV....................................................................................................... 200
4.6.2.2 Kiểm tra chéo k lớp.......................................................................................................... 202
4.6.2.3 Sự đánh đổi Bias – Variance ........................................................................................... 203
4.6.3 Giới thiệu về các phương pháp tái chọn mẫu bằng gói caret .......................................... 204
4.7 Dữ liệu thiếu và xử lý dữ liệu thiếu trong phân tích kinh tế lượng ........................................ 210
Chương 5: Mở rộng mô hình hồi quy hai biến số ................................................................................. 217
5.1 Hồi quy qua gốc tọa độ - mô hình CAPM ............................................................................................ 217
5.2 Vấn đề thay đổi đơn vị của biến ........................................................................................................... 220
5.3 Hồi quy chuẩn hóa ..................................................................................................................................... 222
5.4 Dạng hàm của mô hình hồi quy ............................................................................................................ 223
5.4.1 Mô hình logarit tuyến tính ..................................................................................................... 223
5.4.2 Mô hình bán logarit ................................................................................................................. 226
5.4.3 Mô hình xu hướng tuyến tính ............................................................................................... 229
5.4.4 Mô hình tuyến tính – logarit .................................................................................................. 230
5.4.5 Mô hình nghịch đảo ................................................................................................................. 232
5.4.6 Mô hình đa thức ....................................................................................................................... 233
Chương 6: Mô hình hồi quy bội................................................................................................................... 235
6.1 Thực hiện hồi quy bội trong R và khoảng tin cậy cho các hệ số ................................................ 235
6.2 Khoảng tin cậy cho một biểu thức của hệ số hồi quy .................................................................... 236
6.3 Kiểm định Wald về sự ràng buộc của các hệ số hồi quy............................................................... 237
6.4 Kiểm định F về việc đồng thời bằng không của nhiều hệ số hồi quy....................................... 238
6.5 Mối liên hệ hình chữ U ngược giữa giáo dục và mức lương....................................................... 240
6.6 hồi quy chuẩn hóa và vấn đề so sánh tác động của các biến độc lập ....................................... 241
6.7 Kiểm định LM, LR trong trường hợp kích cỡ mẫu là lớn ............................................................ 242
6.8 Gợi ý trả lời một sô bài tập chương 2 thuộc cuốn giáo trình của NEU.................................... 245
Chương 7: Các mô hình hồi quy biến giả ................................................................................................. 253
7.1 Bản chất của biến giả và các mô hình hồi quy ANOVA .................................................................. 253
7.1.1 mô hình ANOVA với chỉ một biến giải thích là biến giả duy nhất................................... 253
7.1.2 mô hình ANOVA với hai biến giả trở lên ............................................................................. 256
7.1.3 mô hình ANOVA có sự tương tác của các biến giả ............................................................. 257
7.2. Mô hình có chứa cả biến giả lẫn biến định lượng – mô hình ANCOVA................................... 258
7.2.1 Mô hình ANCOVA không có sự tương tác giữa các biến ..................................................... 258
7.2.2 Mô hình ANCOVA có sự tương tác giữa các biến ............................................................... 259
7.2.3 Vai trò của biến định tính và kiểm định Chow ................................................................... 259
7.2.4 Sử dụng biến định tính thay thế cho kiểm định Chow ..................................................... 260
7.3. Biến định tính có nhiều phạm trù ....................................................................................................... 263
7.4. Hồi quy riêng lẻ cho từng nhóm .......................................................................................................... 265
7.5 Vấn đề gán giá trị cho biến giả .............................................................................................................. 268
7.6 Sử dụng biến định tính cho hồi quy từng khúc và phân tích mùa vụ ...................................... 270
7.2.1 Hồi quy từng khúc .................................................................................................................... 270
6.7.1 Tính chất mùa vụ trong phân tích kinh tế sử dụng biến định tính................................... 272
Chương 8: Hiện tượng đa cộng tuyến và cách xử lý đa cộng tuyến ............................................... 275
8.1 Hiện tượng đa cộng tuyến ...................................................................................................................... 275
8.2 Một ví dụ minh họa hiện tượng đa cộng tuyến ............................................................................... 277
8.3 Xử lý hiện tượng đa cộng tuyến bằng bỏ biến số căn cứ vào tiêu chí Cp của Mallows...... 282
8.4 Xử lý hiện tượng đa cộng tuyến bằng phân tích thành phần chính PCA ................................ 289
8.5 Lựa chọn số lượng biến căn cứ vào các tiêu chuẩn thông tin BIC ........................................... 292
Chương 9: Phương sai sai số thay đổi trong mô hình hồi quy.......................................................... 296
9.1 Phương sai sai số thay đổi và hậu quả ............................................................................................... 296
9.2 Chẩn đoán phương sai sai số thay đổi................................................................................................ 297
9.2.1 Các phương pháp không chính thức.................................................................................... 297
9.2.1.1 Căn cứ vào bản chất của các biến số kinh tế ................................................................. 297
9.2.1.2 Căn cứ vào đồ thị phần dư ............................................................................................... 297
9.2.2 Căn cứ vào các bằng chứng thống kê chính thức .............................................................. 298
9.2.2.1 Kiểm định Park .................................................................................................................. 298
9.2.2.2 Kiểm định Glejser .............................................................................................................. 301
9.2.2.3 Kiểm định Goldfeld - Quandt ........................................................................................... 302
9.2.2.4 Kiểm định do Breusch – Pagan đề xuất dựa trên kiểm định F ................................... 303
9.2.2.5 Kiểm định White ................................................................................................................ 306
9.2.2.6 Kiểm định Koenker - Basett ............................................................................................. 307
9.3 Một số cách khác phục phương sai sai số thay đổi ........................................................................ 308
9.3.1 Phương pháp bình phương nhỏ nhất có trọng số và đổi biến số ................................... 308
9.3.2 Sử dụng biến đổi Box – Cox và Yeo-Johnson....................................................................... 311
Chương 10: Lỗi định dạng và lựa chọn mô hình .................................................................................... 315
10.1 Các tiêu chuẩn lựa chọn mô hình ...................................................................................................... 315
10.2 Các loại lỗi mô hình ................................................................................................................................ 315
10.3 Bỏ sót biến quan trọng .......................................................................................................................... 316
10.3.1 Các hậu quả của việc bỏ sót biến quan trọng ................................................................... 316
10.3.2 Kiểm định Wald ..................................................................................................................... 316
10.3.3 Kiểm định F ............................................................................................................................ 319
10.3.4 Kiểm định Ramsey RESET ................................................................................................... 319
12.7 Một số mô hình nâng cao cho phân tích dữ liệu mảng ............................................................... 370
12.7.1 Sử dụng biến công cụ ............................................................................................................ 370
12.7.2 Ước lượng Hausman – Taylor ............................................................................................ 375
12.7.3 Phương pháp moment tổng quát GMM............................................................................. 377
12.7.4 Ước lượng FGLS.................................................................................................................... 378
12.8 Vài kết luận cuối cùng về phân tích dữ liệu mảng ....................................................................... 379
Chương 13: Các mô hình với biến phụ thuộc là rời rạc ...................................................................... 380
13.1 Mô hình xác suất tuyến tính LPM ...................................................................................................... 380
13.2 Mô hình Logistic và một số tiêu chí đánh giá ................................................................................ 381
13.2.1 Mô hình Logistic ..................................................................................................................... 381
13.2.2 Một số tiêu chí đánh giá chất lượng của mô hình Logistic .............................................. 393
13.2.2.1 Kiểm định Hosmer-Lemeshow ...................................................................................... 393
13.2.2.2 Các tiêu chí khác đo lường khả năng phân loại của mô hình .................................. 394
13.3 Mô hình Logistic đa cấp độ .................................................................................................................. 398
13.4 Mô hình Probit ......................................................................................................................................... 402
13.5 So sánh Probit và Logistic theo tiêu chí AUC ................................................................................. 405
13.6 Một vài nhận xét về chương 10 sách giáo trình ........................................................................... 407
13.7 Ứng dụng trong nghiên cứu của mô hình Logit và Probit và một số mô hình phân loại
khác cho xếp hạng tín dụng........................................................................................................................... 409
13.8 Lựa chọn mô hình phù hợp cho bài toán phân loại – xếp hạng hồ sơ tín dụng............... 417
13.9 Mô hình cây phân loại và so sánh với mô hình Logistic ............................................................ 419
13.9.1 Giới thiệu về mô hình cây phân loại .................................................................................... 419
13.9.2 So sánh mô hình cây phân loại và Logistic dựa trên hậu quả kinh tế của việc sử dụng
.............................................................................................................................................................. 422
Chương 14: Mô hình có biến bị kiểm duyệt: Tobit và hồi quy Poisson ......................................... 431
14.1 Mô hình Tobit ........................................................................................................................................... 431
14.2 Hồi quy Poisson ....................................................................................................................................... 433
Chương 15: Phân tích nhân tố khám phá EFA ........................................................................................ 436
15.1 Mô tả số liệu và các gói cần thiết cho phân tích ............................................................................ 436
15.2 Các phân tích sơ bộ cần thiết .............................................................................................................. 437
15.2.1 Phân tích tương quan ........................................................................................................... 437
15.2.2 Phân tích một số thống kê khác về các câu hỏi .................................................................. 438
15.3 Kiểm định KMO và Bartlett.................................................................................................................. 439
15.3.1 Kiểm định KMO ....................................................................................................................... 439
Chương này chúng ta sẽ tìm hiểu về R với tư cách là một phần mềm tính toán thống kê – kinh tế lượng
kiêm ngôn ngữ lập trình cũng như cách cài đặt R và một số Packages (gói) cần thiết cho nghiên cứu
thống kê – kinh tế lượng.
Khoảng năm 2004, TS Nguyễn Văn Tuấn có lẽ là người Việt Nam đầu tiên viết về R khi giới thiệu tập
tài liệu về R (hồi đó là hơn 100 trang) qua blog của mình. Hiện tài liệu này đã trở thành một cuốn sách
dày hơn 500 trang được in bởi nhà xuất bản thành phố Hồ Chính Minh (cuối năm 2015). Tuy nhiên,
tác giả là một nhà nghiên cứu Y Học nên cuốn sách này là thuộc Biostatistics (thống kê Y – Sinh) nên
có thể chưa phù hợp lắm nhu cầu của người học và nghiên cứu các vấn đề kinh tế.
Với mục đích nghiên cứu thống kê – kinh tế lượng, R có thể thực hiện được tất cả các phân tích mà
các phần mềm thống kê thương mại như Eviews, SPSS – AMOS, STATA, SAS có thể làm. Và trong nhiều
tình huống còn làm tốt hơn. Chẳng hạn, nếu phân tích dữ liệu mảng thì Eviews có khả năng hạn chế
và kém hơn so với Stata. Nhưng nếu là nghiên cứu dùng đến thống kê đa biến, thống kê nhiều chiều
như phân tích nhân tố khám phá EFA, CFA, phân tích đường dẫn (Path Analysis)… thì bạn có xu hướng
dùng SPSS – AMOS hay Stata vì nó phù hợp hơn. Nhưng với R bạn chẳng cần lựa chọn gì cả. Nó thực
hiện được tất cả các phân tích đó, kể các các phân tích phức tạp cho dữ liệu chéo, dữ liệu mảng, đến
dữ liệu chuỗi thời gian và dữ liệu tần số cao (High Frequency Data) vốn phổ biến trong nghiên cứu
tài chính.
Ngoài ra, với tư cách là một ngôn ngữ lập trình hoàn thiện, R cho phép bạn xử lý những phân tích một
cách linh hoạt hoặc thiết kê những hàm, những chương trình cho phép bạn xử lí một vấn đề phân tích
cụ thể nào đó và có thể chia sẻ với người khác.
Việc học và làm chủ được một công cụ phân tích số liệu mạnh như R cho thống kê – kinh tế lượng là
một công việc không hề khó. Điều này tôi có thể khẳng định chắc chắn. Thứ bạn cần là sự đều đặn
trong thực hành (thường không quá 1 tháng với mỗi ngày học 60 phút). Một khi đã thành thao R ở
một mức độ tối thiểu nào đó chắc chắn bạn chỉ muốn học thêm nhiều về R.
https://cran.r-project.org/bin/windows/base/R-3.3.2-win.exe
Sau khi cài đặt (cả cài và download chưa đến 10 phút), R có giao diện như sau (trích một phần):
Nếu dùng Mac bạn cần cài đặt R cho phiên bản Mac ở mục Download R for (Mac) OS X tại:
https://cran.r-project.org/
Đến đây chúng ta có thể sử dụng trực tiếp R. Chẳng hạn chúng ta thực hiện phép tính 2+2 rồi enter
kết quả là (trích một phần):
Tuy nhiên cách thực thực hiện các phân tích, tính toán trực tiếp trong R như trên là không khuyến
khích. Thay vì sử dụng R trực tiếp chúng ta sẽ sử dụng R thông qua Rstudio – một giao diện thân thiện
và có nhiều hỗ trợ hơn. Chúng ta tìm hiểu vấn đề này ở mục ngay sau đây.
Rstudio có hai phiên bản, trong đó có một phiên bản miễn phí dành cho các máy tính cá nhân. Tuy
thuộc vào dòng máy (dùng Windows hay máy Mac) mà bạn cần cài Rstudio tại:
https://www.rstudio.com/products/rstudio/download/
Khi kích vào link trên bạn nhớ chọn cho mình phiên bản Rstudio phù hợp dưới đây:
Sau khi load và cài đặt (tầm 5 phút) khởi động Rstudio chúng ta có giao diện như sau:
Giao diện của nó được chia thành 4 phần và phần dưới cùng bên trái chính là nơi chúng ta sẽ gõ các
dòng lệnh. Đến đây bạn có thể trải nghiệm những khả năng của Rstudio. Lúc này các dòng lệnh sẽ là
màu xanh và kết quả hiện lên có chữ màu đen. Hình ảnh (nếu có) sẽ được hiện ở khu vực phía dưới
bên phải của màn hình. Chẳng hạn để tính 2+2 tại cửa sổ lệnh của Rstudio (bên dưới góc trái màn
hình) các bạn gõ 2+2 rồi enter.
Tất nhiên các bạn gõ lệnh trong R và Rstudio thì kết quả luôn luôn như nhau. Nhớ rằng Rstudio là thư
hỗ trợ chúng ta sử dụng R thuận tiện hơn. Ngoài ra Rstudio còn có thể “biến” các phân tích của bạn
thành một bài trên web site. Ví dụ:
http://rpubs.com/chidungkt/185954
Như đã nói, Rstudio là một kiểu môi trường, một kiểu giao diện giúp chúng ta thuận tiện hơn trong
việc sử dụng R. Do vậy, tất cả các phân tích mà chúng ta thực hiện trong tài liệu này sẽ được thực hiện
trong Rstudio. Tất nhiên nếu bạn muốn, bạn có thể sử dụng trực tiếp R. Các bạn cũng cần chú ý rằng
trong tài liệu này, cụm từ “tại cửa sổ lệnh của R” thì hoàn toàn tương đương với cụm từ “tại cửa sổ
lệnh của Rstudio”.
Cho đến thời điểm tài liệu này được viết đã có hơn 9000 gói được viết cho R bởi một cộng đồng rộng
lớn thuộc giới phân tích dữ liệu – bao gồm cả các nhà thống kê, kinh tế lượng và giới phân tích dữ liệu
chuyên nghiệp. Chúng ta tạm hiểu một Package của R là một tập hợp các chương trình, hàm được viết
sẵn để xử lý một nhóm các phân tích hay một nhóm các bài toán nào đó. Trong nhiều trường hợp, các
Packages này có thể bao gồm cả dữ liệu đi kèm. Ví dụ gói AER – một gói trong số các gói mà chúng sử
dụng trong tập tài liệu này có chứa bộ dữ liệu CPS1988 – một bộ dữ liệu tương tự như VHLSS của Việt
Nam.
Đối với nghiên cứu thống kê – kinh tế lượng, dưới đây là một số gói quan trọng mà chúng ta cần đến:
foreign Đọc data đuôi .sav (file SPSS), .dta (file Stata)
AER Gói thực hiện nhiều phân tích kinh tế lượng cơ bản
Để cài đặt một gói nào đó, ví dụ gói gdata chẳng hạn, các bạn làm như sau. Tại cửa sổ lệnh của R các
bạn gõ:
install.packages("gdata")
Tuy nhiên cách cài đặt như các bạn vừa thực hiện ở trên là không khuyến khích. Nguyên nhân là một
số gói của R để sử dụng được còn phụ thuộc vào một hoặc một số gói khác. Do vậy an toàn nhất là cài
đặt với lựa chọn dependencies = TRUE với hàm ý rằng chúng ta sẽ cài đặt luôn tất cả các gói phụ
thuộc:
Kể từ đây, khi cài đặt bất kì gói nào chúng ta đều nên có lựa chọn thêm là dependencies = TRUE dù
rằng có thể có gói nào đó không phụ thuộc vào bất kì gói nào. Nghĩa là chúng ta đang thực hiện một
chiến thuật kiểu “Giết nhầm còn hơn bỏ sót”.
Khi nó rằng “một số gói quan trọng” nghĩa là vẫn còn một số gói “râu ria” nữa. Đương nhiên sau một
thời gian thực hành các bạn sẽ thành thạo việc xác định gói nào cần và tự biết cách tự cài đặt cũng
như sử dụng chúng. Trước mắt, các bạn nên cài đặt tất cả các gói mà tôi liệt kê ở trên.
Cách thức cài đặt một gói như trên chỉ áp dụng cho những gói có trên CRAN – tạm hiểu là một “kho
chứa” các gói của R và được lưu ở một máy chủ nào đó. Có một số gói đang được phát triển hoặc đã
viết xong rồi nhưng tác giả chưa “công bố” chính thức trên CRAN mà lại lưu tại tài khoản của cá nhân
họ trên github (một loại tài khoản lưu trữ tài liệu và chương trình) thì cách cài đặt sẽ khác bằng lệnh
install_github() như ở mục 8.4 mà chúng ta sẽ nghiên cứu cách cài đặt sau.
Lí do là vì ggplot là một hàm (lệnh) thuộc gói ggplot2 – một gói mà bạn đã cài đặt nhưng bạn quên
yêu cầu gói này trình diện. Để gọi gói này trình diện, bạn thực hiện theo câu lệnh sau:
library(ggplot2)
Các bạn thực hiện theo cú pháp này: tên gói bạn muốn gọi luôn để trong dấu ( ) của câu lệnh trên.
Điều này áp dụng cho mọi gói trong R. Do vậy khi yêu cầu một gói trình diện theo cú pháp trên mà
gặp thông báo kiểu như sau:
Thì có nghĩa là bạn chưa cài đặt gói XXX này. Lúc đó, quay trở lại mục 1.2.3 để xem lại cách cài đặt gói
có tên XXX.
1.2.5 Sử dụng Rmarkdown để trao đổi, công bố kết quả trên Internet với Rpub
Rstudio hỗ trợ chúng ta công bố các phân tích trên mạng Internet. Đây là một ví dụ của việc công bố
các phân tích trên mạng: http://rpubs.com/chidungkt/215596 .
Việc công bố trên mạng như trên sẽ tạo thuận lợi cho việc trao đổi học hỏi lẫn nhau. Để sử dụng chức
năng này chúng ta sử dụng một ứng dụng của Rstudio thường gọi là Rmarkdown. Rmarkdown là một
hỗ trợ rất mạnh của R. Nó cho phép chúng ta xuất kết quả phân tích, code hoặc cả hai ra ít nhất 4 định
dạng: (1) website để công bố trên mạng Internet, (2) định dạng word, (3) định dạng pdf, và (4) mẫu
trình bày (template) của hầu hết các tạp chí có trên ScienceDirect.
Đây là hai gói đặc biệt vì khi cần sử dụng nó không cần phải gõ lệnh library() như thường thấy. Sau
khi cài đặt xong, để công bố code cũng như kết quả phân tích ta làm theo các bước sau:
Sau khi chọn R Markdown.. (khoanh vùng viền đỏ) chúng ta có giao diện kiểu như sau (chú ý rằng
giao diện của bạn có thể không hoàn toàn giống như vậy ở một số chi tiết phụ):
Đây là mẫu cơ bản. Chúng ta có thể hiệu chỉnh mẫu theo ý muốn của chúng ta dựa trên mẫu cơ bản
này. Chẳng hạn xóa hoàn toàn khu vực có chữ tiếng Anh và thay bằng câu “Rmarkdown là một ứng
dụng cho phép công bố phân tích trên mạng.” .Hãy quan sát thật kĩ sự khác biệt giữa mẫu cơ bản và
hiệu chỉnh (do chúng ta xóa một số lệnh cũng như tùy chỉnh, gõ mới một số lệnh) dưới đây:
Ở đây khu vực A là khu vực bạn có thể chính sửa. Các khu vực C và D gọi là code chunk – nơi chúng
ta gõ các lệnh của R. Cụ thể ở code chunk C chúng ta đã gõ hai lệnh và data(iris) và summary(iris) còn
code chunk D chỉ có một lệnh là hist(iris$Sepal.Length).
Như vậy phân tích của bạn chỉ có 3 câu lệnh mà thôi. Để xuất kết quả của ba câu lệnh này lên mạng
chúng ta kích vào Knit HTML ↦ Knit to HTML như dưới đây:
Đến bước này R sẽ hỏi lưu một cái gì đó. Bạn cứ lưu đi. Lưu và ấn OK được sản phẩm trung gian như
sau:
Đến đây bạn muốn công bố kết quả phân tích lên mạng Internet thì kích vào cửa sổ Publish ở góc trên
bên phải. Rstudio có thể yêu cầu bạn đăng kí một tài khoản ở bước cuối cùng này. Nếu bạn làm đúng
(có thể cần một chút thời gian thử - sai ) thì bạn sẽ có sản phẩm tương tự như sau:
http://rpubs.com/chidungkt/228157
Thay vì kích Knit to HTML, nếu bạn muốn xuất ra file word thì kích vào Knit to Word. Thực tế tài
liệu này được viết gần như hoàn toàn trong Rmarkdown.
library(installr)
setInternet2(TRUE) # Câu lệnh này dành cho mục đích cài các biên bản thấp hơn
3.3.0 của R.Cao hơn thì không cần
installr::updateR() # Cập nhật (cài đặt) phiên bản mới nhất của R.
Trước khi cài đặt (cập nhật) mới các bạn cũng nên xem R bạn đang sử dụng thuộc phiên bản gì bằng
cách gõ version tại cửa sổ của Rstudio. Cá nhân tôi không hứng thú việc cập nhật mới vì nguyên nhân
sau: có nhiều gói vốn sử dụng được ở phiên bản cũ nhưng sẽ không tương thích với phiên bản mới và
do đó bạn cần cài đặt lại – một việc rất tốn thời gian còn hơn cả cài đặt R.
library(lmtest)
help(package = lmtest)
Lúc này chúng ta nhận được các mô tả về các hàm của gói này (trích) xuất hiện góc phải phía dưới
giao diện của Rstudio :
Các gói thường luôn đi kèm với một số bộ dữ liệu nào đó để minh họa các lệnh (hay các hàm của gói).
Để xác định một gói cụ thể, chẳng hạn lmtest, có đi kèm với những bộ số liệu nào các bạn gõ:
data(package = "lmtest")
Sau khi thực hiện câu lệnh này các bạn sẽ thấy góc trái phía trên của Rstudio báo cáo như sau (trích
một phần):
Với vốn tiếng Anh cơ bản các bạn có thể đoán bộ dữ liệu có tên bondyield (thứ 4 từ trên xuống) có
thể là lãi suất của trái phiếu. Để biết nhiều thông tin hơn nữa về bộ dữ liệu này các bạn gõ:
Lúc này góc phải phía dưới của Rstudio hiển thị các thông tin về bộ dữ liệu này như sau (trích một
phần):
Các bạn có thể thấy đây là một chuỗi thời gian đa biến (nhiều biến số) từ quý 1 năm 1961 tới quý 4
năm 1975. Mô tả chi tiết về các biến cũng đi kèm.
Bất kể khi nào bạn gặp thông báo như trên thì có nghĩa là hầu hết các bạn quên gọi một gói tương ứng
để thực hiện một lệnh (hàm) nào đó. Nếu chúng ta biết rằng lệnh ggplot này thuộc gói ggplot2 thì đến
đây bạn có thể xử một số trở ngại điển hình (chỉ dành cho người học R giai đoạn đầu) thường gặp
bằng cách cài đặt gói ggplot2 như sau (nếu bạn chưa cài đặt):
library(ggplot2)
Khi sử dụng một lệnh nếu chúng ta chưa hiểu rõ lệnh đó có tác dụng gì và áp dụng ra sao, ví dụ với
lệnh tính trung bình cộng (lệnh mean()) chúng ta làm như sau:
?mean()
Lúc này chúng ta sẽ biết rất nhiều thông tin về hàm này kể cả cách sử dụng cũng như ví dụ:
Trong tình huống chúng ta không nhớ cụ thể một hàm nào đó và chỉ biết rằng, chẳng hạn, hàm đó có
cụm kí tự test. Lúc này chúng ta có thể liệt kê tất cả các hàm có cụm kí tự này (trích một phần):
apropos("test")
Tình huống nếu chúng ta muốn tra cứ chi tiết hơn nữa cách sử dụng, thậm chí là một bài báo nào đó
về sử dụng một hàm cụ thể, chẳng hạn, với lệnh ggplot():
help.search("ggplot")
?mean()
Lúc này bạn có thể: (1) xem mã nguồn của nó, (2) tải bản PDF về sử dụng lệnh này – cụ thể là hướng
dẫn vẽ biểu đồ Venn, hoặc (3) vào một số link trên Internet có bài viết về sử dụng lệnh này.
Một tình huống khác bạn hay gặp (thường là các sách..dày cả ngàn trang về R): bạn gõ chính xác tất
cả các câu lệnh nhưng R lại không cho ra kết quả như kì vọng. Trong tình huống này bạn nên rà soát
xem có gói nào bạn chưa cài đặt và yêu cầu R sử dụng hay không.
1.4 Xem danh sách các gói đã cài đặt cũng như số lượng các gói của R
Trong nhiều tình huống số lượng các gói mà chúng ta cài đặt là rất nhiều. Lệnh dưới đây cho biết
những gói nào được chúng ta cài đặt (user-installed R packages) – tức là không tính các gói mặc định
được cài đặt kèm khi cài đặt R lần đầu. Trong R chúng ta gõ các lệnh sau (với chú ý chữ viết sau dấu
# là lời giải thích cho lệnh được gõ vào) :
Để biết hiện có bao nhiêu gói mà chúng ta có thể cài đặt trực tiếp từ CRAN:
Như vậy hiện có 9334 gói mà chúng ta có thể cài đặt. Tất nhiên KHÔNG MỘT AI thành thạo và cần
phải sử dụng đến 9334 gói này. Lưu ý rằng con số này chưa dừng lại và sẽ tăng hàng ngày chứ không
phải hàng tuần. Nên lúc bạn thực hiện các lệnh trên, con số thu được sẽ khác.
1. Để tất các file dữ liệu vào thư mục KTLR (xem kĩ mục 2.3 của chương 2 về cách tạo thư mục
này).
2. Luôn gõ lệnh setwd("D:/KTLR") sau khi khởi động R để chỉ thị cho R làm việc với thư mục
KTLR.
3. Giải thích cho ý nghĩa dòng lệnh (nếu có) được đặt sau dấu #. Dòng giải thích có thể được đặt
trước hoặc sau một dòng lệnh cụ thể. Dưới đây là một ví dụ về dòng giải thích đặt sau dòng
lệnh:
.
Ở đây head(dung) là lệnh của R còn giải thích cho dòng lệnh này đặt sau dấu # và là “Xem 6
quan sát đầu tiên”.
4. Các bạn có bản mềm của tài liệu này trong tay và điều này có nghĩa là về cơ bản, các bạn có
thể copy lệnh từ tài liệu rồi paste vào R. Trong hầu hết các tình huống R sẽ cho ra kết quả như
mong muốn. Tuy nhiên tôi khuyến cáo không làm thế vì ít nhất hai lí do: (1) một số tình huống,
thao tác copy – paste này không có tác dụng vì phạm một lỗi gọi là typos, và (2) các bạn chẳng
học sử dụng R một cách hiệu quả bằng cách copy – paste như vậy.
5. Các câu lệnh (hay hàm), tên các gói nếu xuất hiện lần đầu sẽ được in đậm. Ví dụ: lệnh library(),
gói ggplot2. Các cụm từ, khái niệm quan trọng, tên các nghiên cứu được in đậm và nghiêng.
Thứ nhất là cài đặt R/Rstudio và các hỗ trợ cần thiết, đặc biệt là cài đặt các gói (packages) cũng như
chỉ thị cho R gọi một gói cụ thể nào đó để sử dụng bằng lệnh library().
Thứ hai là sử dụng Rpub để trao đổi cũng như công bố các phân tích lên Internet.
Cuối cùng, những địa chỉ sau đây được sử dụng để trợ giúp các bạn bằng cách trả lời những thắc mắc
và lỗi (nếu có) của tài liệu:
1. https://www.facebook.com/Econometrics-and-Quantitative-Analysis-
1429972370648696/
2. http://rpubs.com/chidungkt
3. Cứ 6 tháng một lần tài liệu được cập nhật tại địa chỉ:
http://www.mediafire.com/file/3lg8bsfbu6csq8d/KinhTeLuongUngDungVoiR.rar
Đây là chương mở đầu và là chương tạo những nền tảng đầu tiên cơ bản cho bạn sử dụng R một cách
thành thạo không chỉ cho nghiên cứu kinh tế lượng nói riêng mà còn phân tích dữ liệu nói chung.
Chương này giới thiệu những kĩ năng cốt lõi nhất của việc đọc dữ liệu từ các định dạng khác nhau
(Eviews, SPSS, Stata, Excel), nhập dữ liệu trực tiếp vào R cũng như các cấu trúc dữ liệu data frame và
data_frame. Những kĩ năng biến đổi và quản lí số liệu (gọi chung là Data Manipulation) là trọng tâm
của chương này. Là một chuơng khá dài và bạn nên đầu tư một cách thích đáng.
X2 X3 Y
STT
(Lương) (TN khác) (Chi tiêu)
1 20 16 24.4
2 30 10 31.2
3 28 2 29.2
4 24 0 23.6
5 32 18 36.0
6 36 10 31.4
7 32 16 32.6
8 34 24 36.8
9 24 28 32.8
10 22 20 29.8
11 28 8 30.2
12 30 4 26.8
luong <- c(20, 30, 28, 24, 32, 36, 32, 34, 24, 22, 28, 30)
thunhapkhac <- c(16, 10, 2, 0, 18, 10, 16, 24, 28, 20, 8, 4)
chitieu <- c(24.4, 31.2, 29.2, 23.6, 36, 31.4, 32.6, 36.8, 32.8, 29.8, 30.2,
26.8)
Ở trên, dấu <- được gọi là dấu gán. Trong Rstudio, để có dấu này gõ tổ hợp phím Alt và – (phím có
dấu trừ). Sau khi nhập bộ dữ liệu này các bạn có thể xem lại, chẳng hạn biến có tên luong trong R:
luong
## [1] 20 30 28 24 42 36 32 34 24 22 28 30
R sẽ ra cửa sổ sau:
Lúc này bạn có thể di chuyển con trỏ đến vị trí 30 cuối cùng và chỉnh thành 32.
Một điểm cần chú ý là các dấu = như các bạn đã sử dụng ở trên có thể thay bằng dấu <- quen thuộc.
Ví dụ, thay vì gõ luong = edit(luong) như trên các bạn có thể thay bằng luong <- edit(luong). Tuy
nhiên dùng đấu = có thể gây một số lỗi khi thực hiện một số lệnh và hàm nên dù tiết kiệm thời gian
thì chúng ta cũng không nên sử dụng kí hiệu này. Trong tài liệu này các bạn sẽ thấy dấu = xuất hiện
khá nhiều. Đây là một thói quen xấu của tôi và do vậy không khuyến khích các bạn học theo.
2.3 Đọc dữ liệu từ file sẵn có ở các định dạng khác nhau, từ các nguồn bên ngoài vào R
R cũng cho phép bạn đọc dữ liệu ở một loạt các định dạng khác nhau từ dữ liệu dạng số đến dữ liệu
văn bản (text) hay thậm chí dữ liệu hình ảnh, từ Internet. Với phạm vi hẹp là nghiên cứu kinh tế lượng,
chúng ta chỉ xem xét cách thực hành để R đọc dữ liệu từ một file sẵn có ở một số định dạng phổ biến
là Excel, Stata, Eviews, SPSS. Mục này cũng trình bày cách thu thập dữ liệu kinh tế vĩ mô cung cấp bởi
World Bank và dữ liệu tài chính trực tiếp trên Internet.
Tại mỗi thời điểm R mặc định chỉ làm việc với một thư mục và luôn mặc định là thư mục Documents.
Chúng ta có thể kiểm tra lại như sau:
getwd()
## [1] "C:/Users/admin/Documents"
Ở đây lệnh getwd() chỉ ra đường dẫn của thư mục hiện thời (là Documents) mà R đang làm việc. Để
thuận lợi trong quản lí và tạo sự thống nhất, chúng ta sẽ chỉ định cho R làm việc với thư mục có tên là
KTLR ở ổ D của máy tính và chúng ta sẽ để toàn bộ các số liệu được sử dụng trong tài liệu này ở thư
mục trên. Có hai cách để tạo ra thư mục này. Một là vào ổ D, dùng con chuột kích chuột phải rồi chọn
New ↦ Folder rồi đặt tên cho thư mục là KTLR. Cách thứ hai (chúng ta sẽ sử dụng cách này trong tài
liệu này) là chúng ta tạo ra thư mục này từ R như sau:
dir.create("D:/KTLR")
Với lệnh này các bạn tạo một folder có tên KTLR ở ổ D. Kế tiếp, bạn chỉ thị cho R làm việc chỉ với foder
này bằng lệnh:
setwd("D:/KTLR")
Chú ý rằng cách thức thiết lập đường dẫn có thể khác so với những gì được trình bày nếu bạn sử dụng
Mac.
R sẽ thông báo một số cảnh báo (warnings) nhưng chúng ta chưa cần quan tâm và tìm hiểu về các
cảnh báo này. Sau khi thực hiện chính xác ba câu lệnh trên, bạn có thể xem qua số liệu này (10 quan
sát đầu tiên):
dung
Đối với dữ liệu hàng chục ngàn (thậm chí hàng trăm ngàn) quan sát với hàng chục biến số thì bạn nên
sử dụng một trong bốn câu lệnh sau:
## [1] 33 7
Với lệnh đầu tiên bạn thấy có 33 quan sát và 7 biến số trong bộ dữ liệu này. Còn lệnh thứ hai liệt kê
chỉ một số quan sát đầu tiên. Lệnh thứ ba miêu tả chi tiết hơn các biến số có trong bộ số liệu.
Chúng ta cũng có thể xem chi tiết các biến số theo cách thức tương tự như của Excel:
View(dung)
Chú ý rằng câu lệnh đọc file dữ liệu vào R có thể được gõ dài dòng như sau:
Tất nhiên cách gõ lệnh dài dòng như vậy là không cần thiết vì chúng ta đã chỉ định cho R làm việc với
thư mục KTLR rồi nên câu lệnh có thể gõ ngắn lại như bạn có thể thấy.
library(foreign)
aoe <- read.dta("Panel1.dta")
Chú ý rằng không cần dùng lệnh setwd("D:/KTLR") nữa vì đã làm điều này ở mục 2.3.1 (mà nếu có
dùng lại cũng không sao). Các bạn có thể kiểm tra file dữ liệu này:
## i t C Q PF LF
## 1 1 1 1140640 0.952757 106650 0.534487
## 2 1 2 1215690 0.986757 110307 0.532328
## 3 1 3 1309570 1.091980 110574 0.547736
## 4 1 4 1511530 1.175780 121974 0.540846
## 5 1 5 1676730 1.160170 196606 0.591167
## 6 1 6 1823740 1.173760 265609 0.575417
Với gói foreign, R cũng có thể đọc dữ liệu nếu nó lưu ở một website nào đó. Chẳng hạn, bộ dữ liệu có
tên crime.dta của trung tâm tính toán thống kê IDRE thuộc UCLA (University of California, Los
Angeles) có thể được đọc vào R ở dạng data.frame với tên gọi greek:
Lệnh read.dta() ở trên chỉ đọc được các file của Stata từ phiên bản 12 trở xuống. Muốn đọc được các
file Stata phiên bản 13 hoặc 14 (khi tài liệu này được viết thì Stata mới dừng ở phiên bản 14) cần sử
dụng một gói khác là readstata13 (mặc định là bạn đã cài đặt gói này). Dưới đây là R code để đọc bộ
dữ liệu của Stata 13 có tên dung_stata13.dta với lệnh read.stata13():
library(readstata13)
doc_stata13 <- read.dta13("dung_stata13.dta")
library(haven)
dung_haven <- read_stata("dung_stata13.dta")
Điểm khác biệt ở đây chính là tốc độ. Gói have có tốc độ đọc dữ liệu nhanh và nó hỗ trợ các tính toán
hiệu tốc độ cao. Điều này thực sự ý nghĩa nếu dữ liệu nguyên thủy cần đọc có kích thước lớn.
Điểm khác biệt đáng chú ý ở đây là nếu dùng lệnh read.sps() thì các biến định tính (GROUP) được giữ
nguyên dạng kí tự (thuật ngữ của R gọi là factor):
aoe1
Trong khi đó, nếu dùng gói haven thì biến có bản chất định tính được chuyển thành số. Cụ thể 1 ứng
với Manic Psychosis còn 2 ứng với Sussex Lecturers:
aoe2
## # A tibble: 20 × 3
## GROUP QUALITY QUANTITY
## <dbl+lbl> <dbl> <dbl>
## 1 1 5 4
## 2 1 5 9
## 3 1 6 10
## 4 1 7 11
## 5 1 7 12
## 6 1 7 13
## 7 1 7 13
## 8 1 7 13
## 9 1 8 16
## 10 1 8 20
## 11 2 2 2
## 12 2 4 7
## 13 2 5 8
## 14 2 7 9
## 15 2 8 10
## 16 2 10 13
## 17 2 10 13
## 18 2 10 14
## 19 2 10 14
## 20 2 10 17
Cần lưu ý sự khác biệt này khi thực hiện phân tích.
## # A tibble: 6 x 13
## BAD LOAN MORTDUE VALUE REASON JOB YOJ DEROG DELINQ CLAGE
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 1 1100 25860 39025 HomeImp Other 10.5 0 0 94.36667
## 2 1 1300 70053 68400 HomeImp Other 7.0 0 2 121.83333
## 3 1 1500 13500 16700 HomeImp Other 4.0 0 0 149.46667
## 4 1 1500 NA NA NA NA NA NA
## 5 0 1700 97800 112000 HomeImp Office 3.0 0 0 93.33333
## 6 1 1700 30548 40320 HomeImp Other 9.0 0 0 101.46600
## # ... with 3 more variables: NINQ <dbl>, CLNO <dbl>, DEBTINC <dbl>
library(gdata)
doc_file_xls <- read.xls("Table2_8.xls") # Đọc dữ liệu có tên Table2_8.xls.
Riêng gói readxl có thể đọc cả định dạng xlsx lẫn xls:
library(readxl)
# Đọc xls
doc_xls <- read_excel("Table2_8.xls")
# Đọc xlsx
doc_xlsx <- read_excel("luong.xlsx", sheet = 1)
Lợi thế của sử dụng gói readxl là tốc độ đọc dữ liệu nhanh gấp 10 lần. Các file xlsx có thể có nhiều
bảng (sheet) và do đó muốn chỉ thị R đọc chính xác sheet nào thì cần chỉ thị rõ. Trong trường hợp
trên, sheet = 1 có nghĩa là sheet 1 thuộc file có tên luong.xlsx.
Nếu file đuôi csv có kích thước lớn, sử dụng lệnh read_csv() của gói readr có thể tăng tốc độ đọc dữ
liệu lên chừng 10 lần:
library(readr)
hello <- read_csv("scholarly_impact_2012.4.9.csv")
Chú ý rằng nếu sử dụng lệnh read_csv thì ta không cần sử dụng lựa chọn header=TRUE. Với các dữ
liệu có kích thước rất lớn chúng ta nên sử dụng lệnh fread() như được trình bày ở mục 2.3.11.
Download hai file dữ liệu về AAA và AAM và để chúng vào một folder có tên cophieu chứa trong folder
KTLR mà chúng ta đã biết. Dưới đây là R code để đọc hai file dữ liệu tài chính về AAA và AAM đồng
thời:
## List of 2
## $ :'data.frame': 1569 obs. of 14 variables:
## ..$ X.Ticker. : Factor w/ 1 level "AAA": 1 1 1 1 1 1 1 1 1 1 ...
Ở đây có một điểm cần chú ý là lúc này data không phải data frame quen thuộc mà nó là một list (thể
hiện bằng dòng chữ List of 2 ) chứa cả hai data frame. Data frame thứ nhất ứng với AAA còn data
frame thứ hai ứng với AAM. Nếu cần phân tích riêng cho từng mã cổ phiếu có thể tách các data frame
này ra như sau:
Đương nhiên hai data frame này có biến số trùng nhau (hiển thị một phần):
names(aaa)
Nếu muốn hợp nhất hai data frame ứng với hai cổ phiếu ở trên thành một data frame duy nhất với
tên là love3 nhưng đồng thời chỉ chọn ra các biến là mã cổ phiếu, giá mở cửa và giá cao nhất:
## [1] 3265 3
Có 3265 quan sát ở love3 và chúng chính là tổng của 1569 và 1696 – số lượng các quan sát ứng với
mã AAA và AAM tính đến thời điểm tài liệu này được viết:
table(love3$X.Ticker.)
##
## AAA AAM
## 1569 1696
Tên biến nên được đổi lại cho dễ hiểu với người đọc phổ thông như sau:
Có thể áp dụng cách thức tương tự cho việc đọc nhiều file dữ liệu cùng một lúc thuộc các đinh dạng
khác. Ví dụ, nếu chúng ta có 1000 file Stata 13 và tất cả có đuôi là .dta thì trước hết chúng ta cần gọi
gói readsata13 bằng lệnh library(readstata13) đồng thời thay read.csv bằng read.dta13 ở câu lệnh
data <- lapply(path, read.csv).
Trong trường hợp chúng ta muốn lấy tất cả các cột biến thì làm như sau:
## [1] 3265 3
Có thể thực hiện việc đổi tên cho cột biến tương tự như trên cho data frame có tên love4 hoặc theo
một số cách khác được trình bày ở mục 2.4 hoặc 2.4.
2.3.9 Đọc dữ liệu được cung cấp bởi World Bank với gói WDI
R có một lợi thế nữa là nó có thể trực tiếp thu thập dữ liệu được cung cấp bởi nhiều tổ chức, các cơ
quan thống kê hay các tổ chức chuyên cung cấp số liệu từ Internet. Mục này chỉ giới thiệu một trong
số các khả năng đó của R là thu thập dữ liệu kinh tế - xã hội từ ngân hàng thế giới WB (World Bank).
(Nguồn: http://datacatalog.worldbank.org )
Sở dĩ có 20 nhóm dữ liệu này nhưng lại có tới 16000 chuỗi dữ liệu khác nhau là bởi vì mỗi một nhóm
này lại được phân thành các nhóm nhỏ hơn (gọi là SubTopic). Ví dụ, chúng ta xét 7 chuỗi dầu tiên:
(Nguồn: http://data.worldbank.org/sites/default/files/WDI_April2013_CETS.xls)
Ở đây các bạn cần chú ý đến mã của chuỗi dữ liệu ở cột có tên Series Code. Ví dụ mã AG.AGR.TRAC.NO
có nghĩa là số đầu máy kéo nông nghiệp. Các bạn cũng có thể thấy rằng 7 chuỗi chỉ số này đều thuộc
nhóm Environment nên nó có cùng cụm kí tự AG ở đầu. Việc tìm hiểu chi tiết các thức WB kí hiệu cho
các chuỗi chỉ số các bạn có thể tham khảo tại:
https://datahelpdesk.worldbank.org/knowledgebase/articles/201175-how-does-the-world-bank-
code-its-indicators
Để lấy chính xác các dữ liệu cho các nghiên cứu vĩ mô chúng ta trước hết cần lấy chính xác các mã số
liệu. Ngoài ra chúng ta cũng cần biết chính xác mã ISO-2 của các quốc gia được cung cấp ở cột A2 dưới
đây (trích):
(Nguồn: http://www.vas.com/Tnotes/Country%20Codes.htm)
Để lấy được một (hay một nhóm) các chỉ số cho một (hay một nhóm) các quốc gia thì chúng ta cần
hiểu rõ cách tra chỉ số cần lấy cũng như mã ISO-2 của từng nước. Với R chúng ta có thể dễ dàng lấy
những số liệu từ WB cũng như thực hiện nhiều phân tích khác nhau với sự trợ giúp của gói WDI được
viết bởi Vincent Arel-Bundock (University of Michigan).
2.3.9.2 Lấy các dữ liệu cung cấp bởi WB vào R với gói WDI
Chúng ta cần tìm hiểu các chỉ số (kí hiệu cũng như miêu tả) có thể lấy bằng lệnh WDIcache():
Ở đây d1 là danh sách (mà thực chất là một data frame – một khái niệm mà chúng ta sẽ biết rõ hơn ở
các mục sau) các chỉ số có thể lấy và có hai cột chúng ta cần chú ý. Cột thứ nhất là kí hiệu các chỉ số
(cột indicator). Cột thứ hai là miêu tả ngắn về chỉ số đó (cột name). Chúng ta có thể thấy điều này
bằng xem 6 quan sát đầu tiên trong danh sách (trích một phần):
head(d1)
## indicator
## 1 ZINC
## 2 XGDP.56.FSGOV.FDINSTADM.FFD
## 3 XGDP.23.FSGOV.FDINSTADM.FFD
## 4 WP15187.1
## 5 WP15186.1
## 6 WP15185.1
## [1] 16038 5
nrow(d1)
## [1] 16038
Danh sách d2 là các thông tin về những quốc gia mà chúng ta có thể lấy số liệu cho nó. Có ba cột thông
tin đáng quan tâm là: (1) country - tên của quốc gia, (2) iso2c - mã quốc gia, và (3) income - nhóm thu
nhập của quốc gia theo cách phân loại của WB:
# Số lượng các quốc gia có trong kho dữ liệu của ngân hàng thế giới:
dim(d2)
## [1] 304 9
Tất nhiên chúng ta có thể xem qua phân bố các quốc gia theo nhóm thu nhập:
# Số lượng các quốc gia theo từng nhóm thu nhập:
table(d2$income)
##
## Aggregates High income Low income
## 86 79 31
Với 304 quốc gia và vùng lãnh thổ thì tìm mã iso2c cho, chẳng hạn, cho Việt Nam là một công việc khá
chán nếu dò từng dòng bằng mắt. Chúng ta nên sử dụng lệnh filter() của gói dplyr thuộc hệ sinh thái
tidyverse để tìm:
library(tidyverse)
filter(d2, country == "Vietnam")
Mã quốc gia của Việt Nam là VN thuộc khu vực Đông Á - Thái Bình Dương với thủ đô là Hà Nội có kinh
độ 105.825 và vĩ độ là 21.0069 và nằm trong nhóm thu nhập Lower middle income.
Ở bước này tôi tin là nhiều bạn khi gõ lệnh library(tidyverse)sẽ thấy báo lỗi và 90% trong số
này có nguyên nhân từ việc chưa cài đặt tidyverse. Hãy xem lại mục 1.2.3 về cài đặt các gói.
Với hơn 16000 chỉ số tì tìm kiếm một chỉ số nào đó trong kho là một việc rất mất thời gian nếu chúng
ta cứ tra từng dòng một. Dưới đây là cách tìm kiếm một chỉ số nhanh chóng hơn với lệnh
WDIsearch(). Chẳng hạn chúng ta cần tìm các chỉ số có chữ GDP (chú ý không phân biệt chữ hoa –
chữ thường) trong phần miêu tả về chỉ số đó ở cột name:
# Các chỉ số có chữ gdp:
df1 <- WDIsearch("gdp", cache = d)
dim(df1) # Có 369 chỉ số có chữ gdp
## [1] 369 2
## indicator
## [1,] "XGDP.56.FSGOV.FDINSTADM.FFD"
## [2,] "XGDP.23.FSGOV.FDINSTADM.FFD"
## [3,] "UIS.XUNIT.GDPCAP.4.FSGOV"
## [4,] "UIS.XUNIT.GDPCAP.3.FSGOV"
## [5,] "UIS.XUNIT.GDPCAP.2.FSGOV"
## [6,] "UIS.XGDP.FSGOV.FDINSTADM.FFD"
Có thể xem các chỉ số có ba kí tự GDP (không hiển thị kết quả):
View(df1)
Chúng ta có thể thu hẹp phạm vi tìm kiếm hơn nữa với điều kiện là chỉ số đó có: (1) có cụm gdp, (2)
capita, và (3) current:
# Các chỉ số có ba nhóm chữ gdp, capita và current:
df2 <- WDIsearch("gdp.*capita.*current", cache = d)
dim(df2)
## [1] 3 2
df2
## indicator name
## [1,] "NY.GDP.PCAP.PP.CD" "GDP per capita, PPP (current international $)"
## [2,] "NY.GDP.PCAP.CN" "GDP per capita (current LCU)"
## [3,] "NY.GDP.PCAP.CD" "GDP per capita (current US$)"
Như vậy có 3 chỉ số thỏa mãn các điều kiện tìm kiếm ở trên.
Khi đã biết rõ mã của chỉ số tương tứng với quốc gia cần lấy chúng ta có thể sử dụng lệnh WDI() để
thu thập dữ liệu. Dưới đây minh họa cho việc thu thập dữ liệu về tăng trưởng của GDP đầu người của
Việt Nam (mã là NY.GDP.PCAP.KD.ZG và được mô tả bằng tiếng Anh là “GDP per capita growth (annual
%)” từ năm 1980 đến 2015:
dat <- WDI(indicator = c("NY.GDP.PCAP.KD.ZG"),
country = c("VN"),
start = 1980,
end = 2015)
Chú ý rằng không phải quốc gia nào cũng có số liệu từ năm 1980. Việt Nam có lẽ cũng không ngoại
lệ. Có thể tìm số lượng những năm không có số liệu về chỉ số này như sau:
sum(is.na(dat$NY.GDP.PCAP.KD.ZG))
## [1] 5
Như vậy có 5 năm trong khoảng thời gian trên Việt Nam không có số liệu. Chúng ta có thể thấy rõ
điều này:
dat
Các dữ liệu trống có lẽ không cần thiết nên ta có thể bỏ bằng lệnh na.omit() – tức là chỉ lấy dữ liệu từ
1985. Có ít nhất ba cách khác nhau để làm việc này:
# Cách 1:
c1 <- na.omit(dat)
c1
# Cách 3:
c3 <- filter(dat, year >= 1985)
Có thể hình ảnh hóa dữ liệu (Data Visualization) nhằm mô tả tăng trưởng GDP đầu người của Việt
Nam bằng hình ảnh sau:
library(ggplot2)
library(ggthemes)
k <- ggplot(c3, aes(year, NY.GDP.PCAP.KD.ZG)) +
geom_line() +
geom_point(col = "red") +
labs(x = NULL,
y = NULL,
title = "Vietnam's Economic Growth: 1985 - 2015",
subtitle = "Unit: Percentage",
caption = "Data Source: The World Bank") +
theme_economist()
k
Chúng ta sẽ tìm hiểu kĩ hơn về Data Visualization ở chương 3. Sau khi học xong chương 3 các bạn có
thể trở lại để tìm hiểu những dòng lệnh trên.
Chúng ta cũng có thể lấy nhiều chỉ số cùng một lúc cho nhiều quốc gia. Dưới đây là minh họa việc lấy
cả NY.GDP.PCAP.KD.ZG và SP.DYN.LE00.IN (tuổi thọ bình quân) cho 6 nước là Lào, Campuchia, Việt
Nam, Miến Điện, Philippine và Indonesia:
dung <- WDI(country = c("LA","KH","VN","MY","PH","ID"),
indicator = c("NY.GDP.PCAP.KD.ZG","SP.DYN.LE00.IN"),
start = 1986,
end = 2014,
extra = TRUE,
cache = NULL)
Giả sử chúng ta chỉ quan tâm đến xu hướng về tuổi thọ của các quốc gia mà thôi thì chúng ta có thể
tách từ ra biến SP.DYN.LE00.IN và year mà thôi:
trang <- select(dung, country, year, SP.DYN.LE00.IN)
a + labs(x = NULL,
y = NULL,
title = "The average life expectancy in some countries: 1986 - 2014",
subtitle = "Unit: Year",
caption = "Data Source: The World Bank")
Tất nhiên chúng ta có thể khai thác những dữ liệu thu được từ WB cho nhiều mục đích khác nhau.
Chẳng hạn như thực hiện các mô hình phân tích thống kê – kinh tế lượng hay kết hợp với các nguồn
dữ liệu khác để thực hiện nghiên cứu.
Trong lĩnh vực tài chính, các chuỗi dữ liệu thời gian thường là giá của các tài sản như kim loại quý,
các hàng hóa chiến lược như dầu thô, giá của các chứng khoán phái sinh hay một chỉ số chứng khoán
như S&P 500 hoặc VNDIRECT và thường được gọi tắt là dữ liệu tài chính (Financial Data) hay gọi theo
tên đầy đủ là chuỗi dữ liệu tài chính theo thời gian FTS (Financial Time Series). Trong tài liệu này, các
thuật ngữ này được sử dụng thay thế cho nhau mà không có khác biệt nào về ý nghĩa.
Để phân tích dữ liệu tài chính tất nhiên thứ đầu tiên cần có là dữ liệu. Với vai trò là công cụ thu thập
dữ liệu thì chắc chắn R tỏ ra vượt trội so với các phần mềm khác: nó có thể thu thập các dữ liệu tài
chính một cách trực tiếp từ từ Internet ở nhiều định dạng khác nhau.
Gói quantmod của R có thể download tầm 40.000 chuỗi dữ liệu thời gian từ nhiều nguồn khác nhau
(Yahoo Finance, Google, FRED - Federal Reserve Economic Data). Dưới đây là một minh họa đơn giản
sử dụng gói này với điều kiện máy của bạn được kết nối với mạng Internet.
Dưới đây là R code để lấy dữ liệu tài chính của công ti Apple (mã AAPL) từ 2007-01-03 đến thời điểm
mà tài liệu này đang được đánh máy (ngày 05/08/2016) được cung cấp bởi Yahoo Finance:
## [1] "AAPL"
## [1] "2016-05-18"
Lệnh trên nếu không có lựa chọn src = "yahoo" thì R vẫn sẽ mặc định nguồn lấy là Yahoo Finance.
Với data trên có thể thực hiện một số phân tích kĩ thuật dựa trên hình ảnh:
Nếu không có lựa chọn theme="white" thì chúng ta có đồ thị trên nền đen. Cũng có thể lựa chọn
khoảng thời gian khác cho đồ thị:
Dưới đây là R code để thu thập dữ liệu tài chính của AAPL với một khoảng thời gian nhất định và tạo
ra các hình ảnh cần thiết cho phân tích kĩ thuật:
Thêm chỉ số MACD (Moving Average Convergence Divergence indicator) cho đồ thị:
addMACD()
addBBands()
Tất nhiên khả năng của quantmod không chỉ đơn giản là lấy dữ liệu mà chức năng chính của nó là
phân tích kĩ thuật và thực hiện nhiều phân tích khác. Tuy nhiên các chủ đề này vượt qua giới hạn của
tài liệu này nên chúng không được trình bày ở đây.
Chúng ta cũng có thể lấy dữ liệu một cách đồng thời cho nhiều mã cổ phiếu, tài sản tài chính cũng như
tài sản thực (kim loại quý, các hàng hóa chiến lược như dầu thô) từ nhiều nguồn khác nhau:
## [1] "YHOO"
## [1] "EURUSD"
## [1] "XAUUSD"
Thậm chí chúng ta cũng có thể lấy các báo cáo tài chính của, chẳng hạn, Apple trong 3 năm liên tiếp
(mặc định):
getFinancials("AAPL")
## [1] "AAPL.f"
## 2016-09-24 2015-09-26
## Cash & Equivalents 11883.00 9731.00
## Short Term Investments 46671.00 20481.00
## Cash and Short Term Investments 67155.00 41601.00
## Accounts Receivable - Trade, Net 15754.00 16849.00
## Receivables - Other NA NA
## Total Receivables, Net 29299.00 30343.00
## Total Inventory 2132.00 2349.00
Trong câu lệnh trên thì lựa chọn type = "BS" có nghĩa là xem bảng cân đối kế toán (viết tắt của
Balance Sheet) còn period = "A" nghĩa là xem theo năm (Annual). Có thể thay BS bằng CF để xem
dòng tiền, hay IS để xem báo cáo doanh thu (Income Statement). Thay A bằng Q để xem các thông tin
báo cáo tài chính theo quý. Tất nhiên gói quantmod cũng được sử dụng để phân tích các báo cáo tài
chính (Financial Statement Analysis).
Mục này chỉ trình bày một cách giản lược và cơ bản về sử dụng gói quantmod như là một công cụ thu
thập dữ liệu. Chi tiết hơn có thể xem ở nhiều tài liệu khác nhau. Ví dụ:
http://www.quantmod.com/download/
Các dữ liệu tài chính được cung cấp bởi các nguồn từ Việt Nam thường không tuân theo một số định
dạng tiêu chuẩn nên để sử dụng được tất cả các tính năng của gói quantmod, trước hết cần thực hiện
một số điều chỉnh nhỏ. Vấn đề này sẽ đươc trình bày trong môt tài liệu chuyên khảo khác.
flights.csv với 227496 quan sát và 21 biến số (thực tế tôi từng gặp bộ số liệu lớn hơn nhiều: xấp xỉ
200 biến số và gần 2 triệu quan sát). Trước hết chúng ta so sánh thời gian đọc dữ liệu bằng lệnh
read.csv() mặc định của R và fread() của gói này:
setwd("D:/KTLR")
system.time(trang <- read.csv("flights.csv"))
Mất 3.01 giây để đọc bộ dữ liệu này. Tất nhiên máy của bạn có thể ra con số khác tùy vào cấu hình
máy và mỗi lần thực hiện, các con số cũng có thể khác nhau trên cùng một máy tính. Chúng ta sử dụng
lệnh fread() để đọc dữ liệu:
library(data.table)
system.time(trangyeu <- fread("flights.csv"))
Có thể thấy thời gian đọc dữ liệu của lệnh này nhanh gấp 8 lần so với lệnh read.csv(). Chúng ta có thể
kiểm chứng rằng có sự khác biệt về thời gian đọc dữ liệu giữa hai lệnh với sự trợ giúp của gói
microbenchmark. Dưới đây chúng ta sẽ viết lần lượt hai hàm đọc bộ dữ liệu flights.csv (có tên là
love và you) sau đó sử dụng hàm microbenchmark để chỉ thị đọc bộ dữ liệu 100 lần rồi tính toán các
thống kê về thời gian đọc. Kế đến sử dụng các thông tin có được thực hiện kiểm định t để chỉ ra rằng
có sự khác biệt về thời gian đọc dữ liệu ứng với hai lệnh:
Thời gian trung bình (đơn vị là Miliseconds – mili giây) của hai lệnh này là chênh lệch nhau cỡ 8 lần
(3019 so với 414). Chúng ta có thể sử dụng kiểm định t để chỉ ra rằng khác biệt này có ý nghĩa thống
kê. Trước hết chúng ta chuyển loveyou về dạng data frame như sau:
Do giá trị p-value là bằng 0 nên chúng ta có thể kết luận rằng sự khác biệt về thời gian để đọc bộ dữ
liệu là có ý nghĩa thống kê.
R có thể đọc dữ liệu với kích thước rất lớn nhưng để đảm bảo máy tính không bị đơ, chỉ nên đọc vào
R bộ dữ liệu tối đa chỉ chừng 50% đến 60% dung lượng của RAM. Do vậy, nếu máy tính của bạn có 4
Gi RAM thì chỉ nên đọc những bộ dữ liệu tối đa là 2.4 Gi. Chúng ta có thể đo kích thước của bộ dữ liệu
được đọc vào R như sau với hàm object_size() của gói pryr:
library(pryr)
object_size(trang)
## 20.2 MB
Trong tình huống nếu bộ dữ liệu cần xử lí mà lớn hơn RAM của máy tính thì chúng ta cần đến một số
giải pháp chuyên cho dữ liệu lớn (Big Data). Đây là chủ đề nằm ngoài phạm vi của tài liệu này nên sẽ
không được trình bày ở đây.
2.4 Quản lý dữ liệu, đổi tên, hiệu chỉnh dữ liệu bằng các hàm của gói base
Mục này chúng ta sẽ thực hành một số hàm quản lí dữ liệu, đổi tên và hiệu chỉnh dữ liệu (thuật ngữ
tiếng Anh là Data Manipulation hay Data Wrangling) với gói base – vốn là một gói cơ sở của R và sẽ
tự động xuất hiện khi khởi động R. Đây là những kĩ năng cần thành thạo.
Tất nhiên có data.frame này chúng ta thực tế là làm qua hai bước như đã biết. Bước 1 là khởi tạc các
biến luong, thunhapkkhac và chitieu. Bước 2 là sử dụng lệnh data.frame() để hợp nhất các biến này.
Chúng ta có thể nhập trực tiếp một bảng số liệu vào R thành một data.frame theo cách thức khác.
X2 X3 X4
10 50 52
15 75 75
18 90 97
24 120 129
30 150 152
Chúng ta có thể nhập bộ dữ liệu này vào R dưới dạng một data.frame với tên gọi ct:
ct
## x2 x3 x4
## 1 10 50 52
## 2 15 75 75
## 3 18 90 97
## 4 24 120 129
## 5 30 150 152
Chúng ta cũng có thể nhập bảng dữ liệu trên ở dạng một data.frame với tên gọi khác là yamato theo
một cách thức mà bạn rất quen thuộc:
Nếu file có tên yamato trong R mà bạn nhập sai một quan sát nào đó, bạn có thể sửa lại trong R như
sau:
Chúng ta cũng có thể sử dụng lệnh edit để thay đổi cả giá trị ở các cột (nếu chúng ta nhập sai dữ liệu)
cũng như tên của các cột đối với data frame có tên ct ở trên bằng cách gõ:
ct <- edit(ct)
Chúng ta cũng có thể thực hiện, chẳng hạn, việc đổi tên cho cột thứ 3 từ x4 thành y theo một cách khác
mà không dùng lệnh edit:
Đổi tên biến là một công việc hữu ích trong nhiều trường hợp. Chẳng hạn, các dữ liệu thu thập từ
World Bank ở các phần sau có các kí hiệu rất lạ, dài, và khó hiểu với đa số công chúng phổ thông. Để
trình bày các kết quả của phân tích số liệu thì rõ ràng việc mà chúng ta nên làm là đổi tên gọi cho
chúng.
2.4.2 Dán lại nhãn cho các quan sát thuộc bộ số liệu từ dạng số thành ki tự hoặc factor
Để minh họa, chúng ta đọc bộ dữ liệu ch4bt8.wf1 vào R với tên gọi mới là hello. Trong bộ dữ liệu này
có biến URBAN có hai giá trị 0 và 1 với ý nghĩa URBAN = 1 cho quan sát thuộc khu vực thành thị, = 0
nếu thuộc khu vực nông thôn. Thực chất biến URBAN là biến định tính (hay còn gọi là biến giả) và do
đó sẽ tiện lợi hơn nếu ta thay cách kí hiệu để làm nổi bật rằng URBAN là biến định tính trong đó
URBAN = 1 tương ứng với Dothi và URBAN = 0 ứng với Nongthon:
library(hexView)
hello <- readEViews("ch4bt8.wf1", as.data.frame = TRUE)
hello$khuvuc[hello$URBAN == 1] <- "Dothi"
hello$khuvuc[hello$URBAN == 0] <- "Nongthon"
Kết quả là data.frame có tên hello sẽ được thêm một cột biến mới như sau (trích một số quan sát):
hello[1:6, ]
Lúc này biến số mới khuvuc được tạo ra và nó mang ý nghĩa hoàn toàn trùng khớp với ý nghĩa của
biến URBAN. Điều này cũng có nghĩa là, việc tạo thêm một cột biến cũ URBAN là không cần thiết nên
ta có thể xóa cột biến này:
Việc dán lại nhãn theo cách thức vừa thực hiện thực chất là chúng ta tạo ra một cột biến mới có tên
Khuvuc có cùng ý nghĩa (tức mang nội dung thông tin) không khác so với URBAN do đó chúng ta cần
xóa đi cột biến cũ URBAN. Trong tình huống chúng ta muốn vẫn giữ lại cột biến URBAN với nội dung
thông tin như cũ nhưng chỉ khác biệt ở cách dán nhãn cho quan sát thì:
Cách thức này không tạo ra cột biến mới Khuvuc và do vậy chúng ta không cần phải xóa đi một cột
biến có nội dung thông tin trùng nhau như ở trên.
Cách dán lại nhãn cho các quan sát như trên thì cột biến khuvuc sẽ có dạng kí tự (string) và có bản
chất là biến định tính. Trong nhiều tình huống chúng ta muốn nhấn mạnh “chất” định tính này của
những biến số bằng một định dạng khác mà thuật ngữ của những người sử dụng R gọi kiểu định dạng
này là factor. Ví dụ, với bốn biến có bản chất định tính của bộ số liệu chúng ta có thể dán lại nhãn ở
dạng factor theo cách thức như sau:
head(hello)
Một cách thức dán nhãn khác cho các quan sát được sử dụng thường xuyên là, chẳng hạn, phân loại
nhóm thu nhập (theo một tiêu chuẩn nào đó) cho các quan sát. Giả sử tiêu chuẩn đó là ngưỡng thu
nhập thấp hơn hoặc bằng 3200 thì thuộc nhóm thu nhập thấp, từ 3200 đến nhỏ hơn hoặc bằng 3500
là nhóm thu nhập trung bình còn lớn hơn 3500 là nhóm thu nhập khá. Để thực hiện dán nhãn nhóm
thu nhập chúng ta sử dụng lệnh ifelse():
hello$Class <- ifelse(hello$WAGE <= 3200, "Thap",
ifelse(hello$WAGE > 3200 & hello$WAGE <= 3500, "Trungbi
nh",
##
## Kha Thap Trungbinh
## 352 269 314
2.4.3 Dán lại nhãn cho các quan sát từ dạng kí tự thành dạng số
Đây là cách thức biến đổi ngược so vơí cách biến đổi ở mục 2.4.2. Nếu muốn trở lại cách biểu diễn cũ
cho biến URBAN trong đó quan sát có nhãn Dothi ứng với 1 và Nongthon ứng với 0 thì:
Cách dán nhãn lại cho các quan sát kiểu này vốn là cách làm truyền thống kể từ khi có R và bất tiện,
khó nhớ. Ở các mục sau chúng ta sẽ nghiên cứu một cách tiếp cận mới với gói tidyverse trong đó cac
câu lệnh được thiết kế linh hoạt và dễ nhớ (vì nó gần với ngôn ngữ người) đồng thời tăng tốc độ xử
lí và tính toán.
Trở lại với data frame có tên trangxinh ở mục 2.4. Giả sử chúng ta có thêm hai quan sát nữa và cần
nhập số liệu cho 2 quan sát này với trangxinh đã có. Trước hết:
## 13 31 7 23.0
## 14 30 10 28.0
Như vậy với lệnh rbind() chúng ta đã nghép hai bộ dữ liệu này theo “chiều thẳng đứng”. Chú ý rằng
để nghép hai bộ dữ liệu theo cách này, thì love phải có cùng tên biến như trangxinh.
Nếu 14 quan sát ở trên có 8 quan sát đầu thuộc khu vực thành thị (kí hiệu TT) và 6 quan sát sau thuộc
khu vực nông thôn (kí hiệu NT). Tạo một cột biến định tính mới với tên gọi khuvuc rồi gán biến này
vào trangxinh bằng lệnh cbind() như sau:
Như vậy với lệnh cbind() chúng ta đã cộng thêm một cột biến mới vào bộ dữ liệu sẵn có. Đây là kiểu
ghép dữ liệu “theo chiều ngang”. Chú ý rằng cột dữ liệu mới này phải có cùng số quan sát là 14 như
bộ dữ liệu ban đầu.
Ở đây lệnh rep(“TT”, 8) có nghĩa là lặp lại nhãn TT 8 lần cho biến định tính khuvuc.
Một cách thức nghép các data frame lại với nhau thường sử dụng là lệnh merge(). Để mình họa, hãy
xem xét hai bộ dữ liệu được tạo ra như sau:
Hai bộ dữ liệu này có cùng: (1) cột biến tên là Name, và (2) thứ tự các quan sát ở cột biến này (thực
chất đây là hai data frame lưu các thông tin về một lớp học giả định có ba học sinh). Có thể hợp nhất
hai data frame trên thành một bộ dữ liệu duy nhất:
R cũng mặc định sẽ gép các data frame lại căn cứ vào cột biến chung (miễn là các quan sát có cùng
thứ tự) do đó co thể làm ngắn gọn hơn như sau:
## EXPER FEDUC
## 1 8 1.2e+01
## 2 11 5.0e+00
## 3 18 1.0e-37
## 4 9 1.1e+01
## 5 11 1.3e+01
## 6 10 1.0e-37
Cũng có thể lấy ra hello2 bằng cách chỉ thị cụ thể tên biến:
df1 <- hello[c(1, 99, 200), ] # lấy quan sát ở dòng 1, 99 và 200
df2 <- hello[c(1:3, 100, 500), ] # lấy quan sát từ 1 đến 3, 100 và 500
Cách thức trích dữ liệu con (hay lấy mẫu theo dòng) như trên thường chỉ có tác dụng kiểm tra một số
quan sát cụ thể nào đó và do vậy nó không hữu ích bằng việc lấy mẫu ngẫu nhiên mà ta sẽ nghiên cứu
ở mục sau.
## EXPER FEDUC
## 1 8 1.2e+01
## 3 18 1.0e-37
## 5 11 1.3e+01
Ở đây df3 (là một data frame) được trích xuất ra từ hello bằng cách lấy các quan sát ở dòng 1, 3 và 5
nhưng chỉ lấy các biến ở cột 4 và 5 từ data frame gốc hello ban đầu.
2.4.6 Trích dữ liệu từ một data frame có sẵn bằng lệnh subset()
Trong nhiều tình huống, các bạn cần tách dữ liệu cho các quan sát theo một tiêu chí nào đó. Chẳng
hạn, các từ hello các bạn muốn lọc ra tất cả các quan sát ứng với URBAN = 1 mà thôi với tên gọi là
dothi chẳng hạn:
Lúc này, 671 quan sát khu vực thành thị sẽ được tách ra như các bạn có thể thấy:
dim(dothi)
## [1] 671 16
Bạn cũng có thể tách từ data.frame có tên hello các quan sát mà: (1) ứng với URBAN =1, và (2) có IQ
≥ 110 với tên gọi là thongminh:
Với câu lệnh này, sẽ có 216 quan sát thỏa mãn hai tính chất trên. Chú ý rằng data.frame dothi ở trên
có thể được tách theo một cách thức khác như sau:
## Name Age
## 1 Nam 19
## 2 Linh 22
## 3 An 21
## 4 Trang 23
Để chọn ra ngẫu nhiên 2 người trong số 4 người này làm cán bộ lớp:
## Name Age
## 4 Trang 23
## 2 Linh 22
Ở đây (nrow(myclass) là số học sinh của lớp và chính là 4. Chú ý rằng mỗi lần các bạn thực hiện
câu lệnh trên thì chúng ta sẽ có một df1 khác nhau và kết quả của bạn có thể khác kết quả trên. Vì số
lượng các df1 khác nhau có thể lấy chính là tổ hợp chập 2 của 4 nên để cố định kết quả chúng ta cần
có một thao tác gọi là “gieo hạt” bằng lệnh set.seed() trước khi lấy ngẫu nhiên 2 trong số 4 quan sát:
set.seed(29)
df1 <- myclass[sample(nrow(myclass), 2), ]
df1
## Name Age
## 1 Nam 19
## 4 Trang 23
Con số 29 tôi chọn là ngày sinh nhật của tôi 02/ 09. Tất nhiên các bạn có thể chọn một con số bất kì
khác. Nếu chọn một con số khác 29 thì đương nhiên các bạn lại có một df1 khác.
Các thức chọn mẫu như trên là chọn mẫu không hoàn lại. Tức là nếu một bạn đã được chọn làm lớp
trưởng rồi thì sẽ không được chọn làm lớp phó nữa. Nói cách khác, cách thức chọn mẫu này sẽ không
bao giờ xẩy ra tình huống một quan sát được chọn hai lần. Ngược lại chúng ta có kiểu chọn mẫu có
hoàn lại – tức là một quan sát có thể được lấy nhiều hơn một lần như sau:
2.5 Quản lý dữ liệu, hiệu chỉnh dữ liệu bằng các hàm của gói tidyverse
Các hàm của gói base mà chúng ta sử dụng ở mục 2.4 cho Data Manipulation xuất hiện vào khoảng
thời điểm khi R xuất hiện vào năm 1995 nhưng cú phát của nhiều hàm thuộc gói base là không nhất
quán và khó nhớ, đặc biệt là cho một nhóm công việc đặc biệt tốn thời gian đó là biến đổi số liệu (Data
Manipulation). Gói tidyverse ra đời nhằm đáp ứng các nhu cầu ngày càng tăng của việc biến đổi và
làm sạch dữ liệu (Data Cleaning). Gói tidyverse (nói cho đúng là hệ sinh thái tidyverse vì nó là tập hợp
của những gói mạnh nhất chuyên cho công việc làm sạch và biến đổi số liệu) được khuyến khích sử
dụng vì ít nhất các lí do sau:
Trước hết chúng ta xem xét một dạng tổ chức dữ liệu gọi là tibble (còn gọi là data_frame) – một dạng
tổ chức dữ liệu thay thế cho data frame truyền thống.
## a b c
## 1 1 2.0 3.0
## 2 2 3.0 5.0
## 3 3 4.1 7.1
Với lệnh str (viết tắt của structure) chúng ta biết những thông tin cơ bản sau:
Đây chính là kiểu cấu trúc dữ liệu truyền thống có từ khi R xuất hiện. Nhưng nhược điểm của kiểu cấu
trúc dữ liệu này là các tính toán sẽ trở nên chậm (đặc biệt là với dữ liệu kích thước lên đến hàng Gi)
và không hỗ trợ nhiều cho Data Manipulation.
Nhằm đáp ứng các nhu cầu về tốc độ tính toán cũng như xử lí dữ liệu kích thước lớn, một kiểu cấu
trúc dữ liệu khác được tạo ra trong R là tibble (hay còn gọi là data_frame) bằng gói tidyverse. Cấu
trúc dữ liệu dạng tibble và data frame chính là một ngoại trừ một số khác biệt nhỏ về trình bày hiển
thị. Chúng ta có thể tạo một tibble theo hai cách thức sau:
# Cách 1
df_tb_c1 <- data_frame(a = 1:3, b = c(2, 3, 4.1), c = c(3, 5, 7.1))
df_tb_c1
## # A tibble: 3 × 3
## a b c
## <int> <dbl> <dbl>
## 1 1 2.0 3.0
## 2 2 3.0 5.0
## 3 3 4.1 7.1
str(df_tb_c1)
# Cách 2
df_tb_c2 <- tibble(a = 1:3, b = c(2, 3, 4.1), c = c(3, 5, 7.1))
df_tb_c2
## # A tibble: 3 × 3
## a b c
## <int> <dbl> <dbl>
## 1 1 2.0 3.0
## 2 2 3.0 5.0
## 3 3 4.1 7.1
str(df_tb_c2)
Khi gọi gói tidyverse thì bạn nhận được một loạt thông báo theo đó, gói đầu tiên được gọi là ggplot2
và cuối cùng là dplyr. Như đã nói, một tibble chính là một data frame nhưng: (1) hỗ trợ tính toán và
biến đổi số liệu, (2) có một số khác biệt về trình bày và hiển thị. Cụ thể là:
Khi gõ df_tb_c1 thì ngoài các thông tin như đã thấy còn có các chữ int và dbl để trong dấu
< > với hàm ý chỉ số nguyên và số thông thường (dbl là viết tắt của double và int là viết tắt
của interger).
Cấu trúc của dữ liệu được hiển thị ở dòng Classes 'tbl_df', 'tbl' and 'data.frame'
khi sử dụng lệnh str(df_tb_c2) .
Đương nhiên, chúng ta cũng có thể chuyển hóa một bộ dữ liệu ở dạng data frame về tibble. Lấy ví dụ
với bộ dữ liệu df ở trên:
# Cách 1
df_c1 <- as_tibble(df)
# Cách 2
df_c2 <- tbl_df(df)
# Xem kết quả của chuyển đổi từ data frame sang tibble
df_c1
## # A tibble: 3 × 3
## a b c
## <int> <dbl> <dbl>
## 1 1 2.0 3.0
## 2 2 3.0 5.0
## 3 3 4.1 7.1
df_c2
## # A tibble: 3 × 3
## a b c
## <int> <dbl> <dbl>
## 1 1 2.0 3.0
## 2 2 3.0 5.0
## 3 3 4.1 7.1
Đến đây các bạn đã hiểu cách tạo ra một tibble và chuyển hóa từ data frame sang tibble và ngược lại.
Các bạn nên chuyển hóa cấu trúc dữ liệu từ data frame sang tibble, đặc biệt là trong các tình huống
bộ dữ liệu rất lớn. Nói như thế không có nghĩa là kiểu dữ liệu truyền thống kiểu data frame không
còn được sử dụng trong tài liệu này.
Với mục đích minh họa, các mục kế tiếp chúng ta sẽ thực hành bộ dữ liệu CPS1988 có trong gói AER.
Bộ dữ liệu này là thông tin về mức lương (wage), trình độ học vấn (education), kinh nghiệm
(experience) cũng như một số biến định tính khác (ví dụ: parttime – làm thêm hay không) của 28.155
cá nhân được thu thập bởi bộ thống kê Hoa Kì (US Census Bureau) vào năm 1988 và sau đó được sử
dụng trong một loạt các nghiên cứu khác nhau.
library(AER)
data("CPS1988")
help("CPS1988")
Để biêt bộ dữ liệu có bao nhiêu quan sát cũng như số lượng các biến:
dim(CPS1988)
Để biết các biến số thuộc kiểu gì (định lượng hay định tính chẳng hạn) chúng ta gõ:
str(CPS1988)
Như đã biết, những biến là số nguyên sẽ có kí hiệu int (chẳng hạn education), những biến là số thực
thì có kí hiệu num (chẳng hạn wage) và cấu trúc dữ liệu của nó là ở dạng data frame. Các biến còn lại
là biến định tính với kí hiệu factor. Cụ thể hơn nữa, biến định tính parttime chỉ có hai nhóm là yes
hoặc no nên sẽ được hiển thị chi tiết hơn thành factor w/2 levels “no”, “yes”.
Lọc ra các quan sát có education lớn hơn 12 và biến định tính smsa nhận giá trị “no”:
Lọc ra các quan sát đến khu vực miền nam và tây. Có ba cách thức:
# Cách 1
df2 <- filter(CPS1988, region == "south" | region == "west")
# Cách 2
df3 <- filter(CPS1988, region %in% c("south", "west"))
# Cách 3
df4 <- filter(CPS1988, region != "northeast" & region != "midwest")
Chú ý rằng lệnh filter , nếu gặp dữ liệu trống, nó sẽ tự động loại bỏ những dữ liệu này.
Nếu muốn chuyển hai biến là smsa và region lên vị trí thứ nhất và hai những giữ nguyên các biến còn
lại:
Lệnh select cũng có thể được sử dụng để đổi tên biến nhưng nó sẽ xóa tất cả các biến không được
chọn còn lại:
Chính vì lí do này, chúng ta nên sử dụng lệnh rename nếu muốn giữ lại các biến khác.
Theo cách thức này, các biến khác không được lựa chọn để đổi tên vẫn được giữ lại.
2.5.5 Sắp xếp lại theo giá trị tăng dần hay giảm dần với lệnh arrange
Nếu muốn sắp xếp lại bộ số liệu theo thứ tự giảm dần của mức lương:
Nếu có dữ liệu trống thì các giá trị trống sẽ được xếp ở dưới cùng. Nếu không có desc(wage)thì bộ
số liệu được sắp xếp theo chiều tăng của wage.
Bằng cách này chúng ta tạo ra biến mới có tên wage_100 và sẽ được thêm vào cột cuối cùng của bộ số
liệu gốc.
Tương tự, chúng ta có thể cho rằng tuổi của người lao động bằng năm đi học cộng với năm kinh nghiệp
và cộng thêm 6 (giả thiết dân Mĩ đi học lớp 1 từ lúc 6 tuổi) :
Nếu chúng ta muốn tạo biến mới dựa trên các biến cũ nhưng muốn tách hẳn chúng ra để thành tibble
mới thì sử dụng lệnh transmute:
2.5.7 Lấy ra ngẫu nhiên một số quan sát với lệnh sample_n và sample_frac
Để lấy ra 5 quan sát ngẫu nhiên từ bộ dữ liệu gốc:
Hoặc theo một cách thức khác – lấy theo tỉ lệ so với bộ dữ liệu gốc:
set.seed(222)
# Lấy ra ngẫu nhiên 1% các quan sát từ bộ số liệu gốc
df20 <- sample_frac(CPS1988, 0.01)
2.5.8 Lấy ra không ngẫu nhiên một số quan sát với lệnh slice
Nếu muốn lấy một cách không ngẫu nhiên các quan sát theo vị trí của dòng trong bộ dữ liệu gốc
chúng ta sử dụng lệnh slice:
Cũng có thể sử dụng lệnh slice để loại bỏ một số quan sát theo vị trí dòng:
Có thể thấy quan sát ở dòng 2 và 6 là trùng nhau và chúng ta muốn loại bỏ các quan sát trùng theo
dòng:
## # A tibble: 5 × 3
## x y z
## <dbl> <dbl> <dbl>
## 1 1 3 4
## 2 2 2 2
## 3 5 7 3
## 4 1 3 5
## 5 1 6 2
Kể từ đây, để không cần gõ df1 mà vẫn muốn hiển thị được hiệu ứng của một lệnh, ta dùng dấu () như
sau:
## # A tibble: 5 × 3
## x y z
## <dbl> <dbl> <dbl>
## 1 1 3 4
## 2 2 2 2
## 3 5 7 3
## 4 1 3 5
## 5 1 6 2
Nếu muốn, xóa các dòng trùng căn cứ theo, chẳng hạn, biến y thì:
## # A tibble: 4 × 3
## x y z
## <dbl> <dbl> <dbl>
## 1 1 3 4
## 2 2 2 2
## 3 5 7 3
## 4 1 6 2
Rõ ràng cả ba tibbles này có : (1) cùng số biến số, (2) cùng tên biến số, và (3) cùng thứ tự biến số. Hợp
nhất cả ba tibbles này như sau:
Lệnh bind_rows() ở trên tương đương với lệnh rbind() mà chúng ta đã biết.
Giả sử chúng ta có tibble tên là d chứa hai biến là uni (biến định tính cho biết có bằng đại học hay
không) và biến child (cho biết số con của người lao động):
Rõ ràng a và d có cùng số quan sát và giả sử chúng ta muốn ghép hai bộ dữ liệu trên thành một bộ duy
nhất thì có hai cách làm, hoặc là a trước d sau, hoặc là ngược lại:
## # A tibble: 3 × 9
## uni chil wage education experience ethnicity smsa region
## <chr> <dbl> <dbl> <int> <int> <fctr> <fctr> <fctr>
## 1 yes 1 354.94 7 45 cauc yes northeast
## 2 no 2 123.46 12 1 cauc yes northeast
## 3 no 4 370.37 9 9 cauc yes northeast
## # ... with 1 more variables: parttime <fctr>
Lệnh bind_cols() tương đương với lệnh merge() của gói base.
Có thể coi hai bộ dữ liệu này là mang cùng một thông tin. Nhưng với R chúng sẽ hiểu đây là hai tibbles
khác nhau vì thứ tự của các biến là khác.
Tất nhiên chức năng quản trị dữ liệu (Data Manupulation) của hệ sinh thái tidyverse rất phong phú
và rộng lớn chứ không chỉ giới hạn ở một số hàm cơ bản trên (lưu ý rằng các hàm này mới chỉ là các
hàm thuộc gói dplyr – một trong 6 gói của hệ sinh thái tidyverse). Chúng ta sẽ thấy sức mạnh của việc
sử dụng hệ sinh thái này (thực ra, nói cho đúng là mới chỉ sử dụng dplyr) cho Data Manipulation nói
chung và phân tích thống kê nói riêng ở mục 2.7. Tuy nhiên, để tiến đến mục 2.7 chúng ta cần hiểu rõ
vai trò của toán tử pipe ở mục 2.6 trước.
2.5.11 Dán lại nhãn cho các quan sát với hàm recode() hoặc recode_factor()
Trở lại với bộ dữ liệu ch4bt8.wf1 đã biết ở mục trước:
library(hexView)
hello <- readEViews("ch4bt8.wf1", as.data.frame = TRUE)
Có thể dán lại nhãn cho các quan sát theo một cách thức khác với hàm recode() của gói dplyr:
str(hello)
Sử dụng lệnh recode() nhưng lại phải gõ thêm dplyr::là bởi vì hàm có tên recode() cũng là một hàm
của gói car nên để tránh tình trạng nhầm lẫn và gây ra lỗi, chúng ta cần chỉ định đính danh là sử dụng
hàm của gói dplyr (là một gói thuộc hệ sinh thái tidyverse) chứ không phải của gói car. Tổng quát là
trong những tình huống mà có nhiều hơn hai gói có cùng một tên hàm, thì để tránh tình huông mắc
lỗi (do R không biết cần phải sử dụng hàm nào) chúng ta cần chỉ thị rõ cho R biêt như trên.
Cách thức dán lại nhãn như trên thì biến BLACK lúc này sẽ là biến kí tự (character). Muốn dán nhãn
lại cho quan sát nhưng chuyển hóa luôn về dạng factor thì làm như sau (lấy biến URBAN làm ví dụ):
Cần cẩn trọng khi dán lại nhãn cho quan sát. Ví dụ, với bộ data có tên all ở mục 2.5.10 thì thực hiện
lệnh như sau:
Thì R sẽ báo lỗi. Nguyên nhân là bởi vì biến smsa của all là biến factor chứ không phải character như
hello:
str(all)
2.5.12 Dán lại nhãn cho các quan sát với hàm if_else hoặc case_when
Trở lại với bài toán dán lại nhãn cho các quan sát thành các nhóm thu nhập ở mục 2.4.2, chúng ta
cũng có thể sử dụng hàm if_else() hoặc case_when() kết hợp vói hàm mutate() đã biết để dán nhãn
thành các nhóm thu nhập cho các quan sát như sau:
##
## Kha TB Thap
## 352 314 269
# Cách 2:
d <- mutate(d, Class = case_when(d$WAGE <= 3200 ~ "Thap",
d$WAGE > 3200 & d$WAGE <= 3500 ~ "TB",
d$WAGE > 3500 ~ "Kha"))
table(d$Class)
##
## Kha TB Thap
## 352 314 269
Đến đây cũng là cơ hội để các bạn so sánh tốc độ xử lí và tính toán khi sử dụng hệ sinh thái tidyverse
và các hàm của gói base. Trước hết chúng ta tạo ra một mẫu gồm 10 triệu quan sát có mức thu nhập
nằm trong khoảng từ 2615 đến 5578 (đúng bằng khoảng lương trong mẫu 935 quan sát) bằng hàm
runif() sau đó so sánh thời gian cần thiết để máy tính xử lí công việc được giao:
# Tạo ra một data_frame tên là dt chỉ có mỗi một cột biến với 10 triệu quan
sát:
dt <- data_frame(WAGE = c(runif(10000000, 2615, 5578)))
Có thể thấy thời gian xử lí bài toán dán nhãn này là chênh nhau xấp xỉ 10 lần (12.7 so với 1.23). Lưu
ý rằng, dữ liệu của chúng ta chỉ mới có 1 cột biến và chưa thực hiện nhiều tính toán phức tạp. Việc sử
dụng hệ sinh thái tidyverse và cấu trúc dữ liệu kiểu data_frame ít nhất sẽ tạo ra hiệu quả về mặt tính
toán.
2.5.13 Chuyển từ dạng wide sang long cho các nghiên cứu dữ liệu bảng với lệnh gather
Trước hết chúng ta hãy xem xét một data frame chứa thông tin về giá trị của ba công ti A, B và C có
định dạng như sau:
## Year A B C
## 1 2015 300 100 46
## 2 2014 250 120 55
## 3 2013 270 134 43
Nhưng trong nhiều tình huống nghiên cứu (điển hình là những nghiên cứu về dữ liệu bảng – Panel
Data) thì định dạng dữ liệu này (gọi là wide form) là không thích hợp và ta cần biến đổi chúng về
long form như sau:
long1
long2
Cả long1 và long2 đều chứa các thông tin như nhau. Điểm khác biệt duy nhất giữa chúng đó là với
long2 thì cột biến Firm ở dạng factor chứ không phải character:
str(long1)
str(long2)
Đương nhiên chúng ta có thể biến đổi ngược lại từ long form về wide form:
## Year A B C
## 1 2013 270 134 43
## 2 2014 250 120 55
## 3 2015 300 100 46
wide2
## Year A B C
## 1 2013 270 134 43
## 2 2014 250 120 55
## 3 2015 300 100 46
Biến đổi dữ liệu kiểu này được gọi là tái định hình dữ liệu (Reshaping Data) và là một kĩ năng quan
trọng không chỉ cho phân tích dữ liệu bảng mà còn cho nhiều công việc khác, điển hình là Data
Visualization.
2.5.14 Hợp nhất có điều kiện theo cột cho các bộ dữ liệu
Ở mục 2.5.10 chúng ta đã thực hiện hợp nhất các dữ liệu nhưng đó là kiểu hợp nhất không có điều
kiện. Để minh họa chúng ta xét một tình huống thường xuyên gặp trong thực tế dưới đây:
## # A tibble: 6 x 2
## StudentCode Department
## <int> <chr>
## 1 1 Finance
## 2 2 Finance
## 3 3 Finance
## 4 4 Accounting
## 5 5 Accounting
## 6 6 Accounting
df2
## # A tibble: 3 x 2
## StudentCode Origin
## <dbl> <chr>
## 1 2 Ha Noi
## 2 4 Ha Noi
## 3 6 Nghe An
Bộ dữ liệu df1 là thông tin về nghành học và mã sinh viên của 6 sinh viên. Còn df2 là thông tin về quê
quán của 3 trong số 6 sinh viên có ở danh sách df1. Giả sử chúng ta muốn ghép thêm cột chứa thông
tin về quê quán của các sinh viên này căn cứ vào mã sinh viên của họ. Nghĩa là điều kiện ở đây là
quét sự trùng hay không về mã sinh viên ở hai bộ số liệu. Hãy quan sát hiệu ứng của các lệnh sau:
# inner joint:
inner_join(df1, df2, by = "StudentCode")
## # A tibble: 3 x 3
## StudentCode Department Origin
## <dbl> <chr> <chr>
## 1 2 Finance Ha Noi
## 2 4 Accounting Ha Noi
## 3 6 Accounting Nghe An
## # A tibble: 3 x 3
## StudentCode Origin Department
# left outer:
left_join(df1, df2, by = "StudentCode")
## # A tibble: 6 x 3
## StudentCode Department Origin
## <dbl> <chr> <chr>
## 1 1 Finance <NA>
## 2 2 Finance Ha Noi
## 3 3 Finance <NA>
## 4 4 Accounting Ha Noi
## 5 5 Accounting <NA>
## 6 6 Accounting Nghe An
## # A tibble: 3 x 3
## StudentCode Origin Department
## <dbl> <chr> <chr>
## 1 2 Ha Noi Finance
## 2 4 Ha Noi Accounting
## 3 6 Nghe An Accounting
# right outer:
right_join(df1, df2, by = "StudentCode")
## # A tibble: 3 x 3
## StudentCode Department Origin
## <dbl> <chr> <chr>
## 1 2 Finance Ha Noi
## 2 4 Accounting Ha Noi
## 3 6 Accounting Nghe An
## # A tibble: 6 x 3
## StudentCode Origin Department
## <dbl> <chr> <chr>
## 1 1 <NA> Finance
## 2 2 Ha Noi Finance
## 3 3 <NA> Finance
## 4 4 Ha Noi Accounting
## 5 5 <NA> Accounting
## 6 6 Nghe An Accounting
# full join:
full_join(df1, df2)
## # A tibble: 6 x 3
## StudentCode Department Origin
## <dbl> <chr> <chr>
## 1 1 Finance <NA>
## 2 2 Finance Ha Noi
## 3 3 Finance <NA>
## 4 4 Accounting Ha Noi
## 5 5 Accounting <NA>
## 6 6 Accounting Nghe An
full_join(df2, df1)
## # A tibble: 6 x 3
## StudentCode Origin Department
## <dbl> <chr> <chr>
## 1 2 Ha Noi Finance
## 2 4 Ha Noi Accounting
## 3 6 Nghe An Accounting
## 4 1 <NA> Finance
## 5 3 <NA> Finance
## 6 5 <NA> Accounting
# semi join:
semi_join(df1, df2)
## # A tibble: 3 x 2
## StudentCode Department
## <int> <chr>
## 1 2 Finance
## 2 4 Accounting
## 3 6 Accounting
semi_join(df2, df1)
## # A tibble: 3 x 2
## StudentCode Origin
## <dbl> <chr>
## 1 2 Ha Noi
## 2 4 Ha Noi
## 3 6 Nghe An
# anti joint:
anti_join(df1, df2)
## # A tibble: 3 x 2
## StudentCode Department
## <int> <chr>
## 1 1 Finance
## 2 3 Finance
## 3 5 Accounting
anti_join(df2, df1)
## # A tibble: 0 x 2
## # ... with 2 variables: StudentCode <dbl>, Origin <chr>
Gói base cũng có lệnh nhằm xử lí các tình huốn công việc tương tự là merge.
Giả sử với bộ dữ liệu CPS1988, chúng ta cần chỉ ra 5 quan sát có mức lương lớn nhất và những quan
sát này phải thỏa mãn các điều kiện sau: (1) có năm kinh nghiệm lớn hơn 10, (2) đến từ miền tây
nước Mĩ. Thông thường chúng ta giải quyết bài toán này theo ba bước như sau:
# Bước 1
df1 <- filter(CPS1988, experience > 10 & region == "west")
# Bước 2
df2 <- arrange(df1, desc(wage))
# Bước 3
slice(df2, 1:5)
Nghĩa là để có kết quả cuối cùng, bạn phải gõ ba dòng lệnh khác nhau và tạo ra hai đối tượng (gọi là
object) trung gian là df1 và df2. Cụ thể, bằng lệnh filter bạn tạo ra df1 là một tibble gồm các quan sát
có nhiều hơn 10 năm kinh nghiệm và đến từ miền tây nước Mĩ. Kế tiếp, bạn sử dụng lệnh arrange để
“xử lí” df1 nhằm tạo ra df2 (cũng là một tibble) với các quan sát được sắp xếp theo mức lương giảm
dần. Cuối cùng, bạn sử dụng lệnh slice để “xử lí” df2 nhằm có câu trả lời cuối cùng cho bài toán.
Có hai object trung gian được tạo ra theo cách làm này. Bạn hãy nhớ kĩ điều này. Bạn có thể đo kích
thước của, chẳng hạn, object có tên df1 bằng lệnh object_size() như sau:
pryr::object_size(df1)
## 132 kB
Kích thước của df1 là 132 kB. Đây cũng là dung lượng mà bộ nhớ trong của máy tính phải phân bổ để
“chứa” object này.
Tất nhiên, trong tình huống của chúng ta, kích thước này là không lớn và để đạt kết quả cuối cùng các
bạn cũng chỉ tạo ra hai object trung gian mà thôi. Nhưng cách thức làm như trên sẽ thực sự tạo ra
một vấn đề nếu kích thước các object trung gian tạo ra là rất lớn và tạo ra nhiều object trung gian để
có kết quả cuối cùng. Để tránh tạo ra nhiều object trung gian chiếm bộ nhớ (mục đích chính) và làm
tiết kiệm thời gian gõ phím (mục đích phụ) chúng ta sử dụng toán tử %>% (còn gọi là pipe) để có
cùng kết quả trên như sau với chỉ một dòng lệnh:
CPS1988 %>%
filter(experience > 10 & region == "west") %>%
arrange(desc(wage)) %>%
slice(1:5)
Kí kiệu %>% nên được dịch ra tiếng Việt thành “kế đến là”. Do đó, ý nghĩa của dòng lệnh trên được
diễn giải dễ hiểu như sau. Lấy CPS1988 làm nguyên liệu đầu vào, kế đến là dùng lệnh filter để lọc, kế
đến là dùng lệnh arrange để sắp xếp các quan sát, kế đến là dùng lệnh slice để chọn ra 5 quan sát có
mức lương lớn nhất.
Chú ý rằng hệ sinh thái tidyverse đã tích hợp toán tử pipe nên khi sử dụng toán tử này chúng ta không
cần phải gọi gói magrittr. Trong các tình huống khác, để sử dụng được toán tử pipe (coi như là một
hàm) thì chúng ta phải gọi gói magrittr trước với lệnh library(margrittr).
Không phải ngẫu nhiên mà toán tử %>% có tên là pipe – nghĩa là cái tẩu thuốc. Có lẽ, cách hay để các
bạn hiểu toán tử này là gắn nó với hình ảnh của một hệ thống đường ống xử lí nước, theo đó, CPS1988
là “nước” cần xử lí (nguyên liệu đầu vào) và cứ sau mỗi dấu %>% tương ứng với một lệnh của R là
một khâu xử lí nước.
Với Rstudio, để có kí hiệu %>% các bạn gõ tổ hợp ba phím là Ctrl + Shift + M.
Tất nhiên, để có kết quả như trên các bạn có thể sử dụng toán tử pipe theo cách thức đơn sơ như sau:
# Bước 1
df1 <- CPS1988 %>% filter(experience > 10 & region == "west")
# Bước 2
df2 <- df1 %>% arrange(desc(wage))
# Bước 3
df2 %>% slice(1:5)
Nếu đến đây các bạn thấy quá tải thì nên quay trở lại , nếu không là tất cả được, thì nên ứng dụng toán
tử này ở bất cứ dòng lệnh nào có thể được. Ví dụ, với df18 ở mục 2.5.6 có thể thay bằng:
df18 <- CPS1988 %>% transmute(luong = wage / 1000, age = education + experien
ce + 6, khuvuc = region)
Bằng cách này các bạn sẽ dần quen với toán tử pipe. Và chỉ có cách này mà thôi: thực hành đủ nhiều.
2.7 Tính các thống kê cơ bản với bộ số liệu PISA sử dụng gói dplyr
Cuối năm 2016 tổ chức PISA (http://www.oecd.org/pisa/) công bố một kết quả gây sock và tạo ra
nhiều tranh luận nảy lửa về chất lượng giáo dục của Việt Nam. Theo đó, học sinh Việt Nam có thứ
hạng cao ở cả ba môn được khảo sát là Toán, Đọc Hiểu, và Khoa Học và có vị trí cao hơn cả Hoa Kì, Úc
– là những quốc gia có mức GDP và chất lượng giáo dục cao.
Bỏ qua vấn đề chọn mẫu khảo sách cho các thí sinh đến từ Việt Nam có hợp lí hay không, chúng ta có
thể sử dụng bộ số liệu PISA1.csv để tạo ra những kết quả mà tổ chức này công bố và được các báo
Việt Nam trích dẫn lại. Cụ thể các kết quả cần có, tính theo các quốc gia, là: (1) điểm trung bình, (2)
độ lệch chuẩn , (3) điểm nhỏ nhất – lớn nhất, và (4) số lượng học sinh được khảo sát.
Bộ số liệu này có rất nhiều biến, trong đó các biến mà chung ta quan tâm là CNT (tên các quốc gia),
MATH (điểm toán), SCIE (điểm khoa học) và READ (điểm đọc hiểu).
Những gì bạn sắp đối mặt có thể là một thử thách nhỏ và tôi hi vọng bạn có thể vượt qua. Các tính
toán dưới đây có sử dụng toán tử pipe với lưu ý rằng khi sử dụng hệ sinh thái tidyverse thì toán tử
này (vốn thuộc gói magrittr) sẽ tự động được triệu hồi và do đó chúng ta không cần thực hiện lệnh
library(magrittr) như thường thấy. Trước hết chúng ta tính các thống kê trên cho môn toán:
## # A tibble: 5 × 6
## CNT mean max min sd n
## <chr> <dbl> <dbl> <dbl> <dbl> <int>
## 1 Singapore 568.3597 910.742 191.0030 104.71272 5546
## 2 Viet Nam 510.5900 824.747 204.3230 83.52549 4959
## 3 Australia 492.8429 848.972 59.6744 98.53494 14481
## 4 USA 481.0325 822.021 174.0220 89.18490 4978
## 5 Thailand 441.1471 769.520 107.6570 91.86163 6606
Ý nghĩa các (thực sự chúng là một chuỗi dòng lệnh) ở đây là:
group_by(CNT) ngụ ý rằng các tính toán sau đó được thực hiện theo từng quốc gia.
summarise_each(funs(mean, max, min, sd, n()), MATH) lần lược áp dụng các hàm
tính trung bình (mean), lớn nhất (max), nhỏ nhất (min), độ lệch chuẩn (sd) và đếm (n()) cho
biến MATH.
arrange(desc(mean)) sắp xếp kết quả theo thứ tự giảm dần của trung bình.
Nếu muốn chúng ta có thể đặt tên cho kết quả cuối cùng thu được (theo kiểu viết tắt cho bạn đọc
không biết tiếng Anh) như sau:
arrange(desc(TB))
# Xem kết quả
df2
## # A tibble: 5 × 6
## CNT TB LN NN LC N
## <chr> <dbl> <dbl> <dbl> <dbl> <int>
## 1 Singapore 568.3597 910.742 191.0030 104.71272 5546
## 2 Viet Nam 510.5900 824.747 204.3230 83.52549 4959
## 3 Australia 492.8429 848.972 59.6744 98.53494 14481
## 4 USA 481.0325 822.021 174.0220 89.18490 4978
## 5 Thailand 441.1471 769.520 107.6570 91.86163 6606
## # A tibble: 5 × 6
## Country TB LN NN LC N
## <chr> <dbl> <dbl> <dbl> <dbl> <int>
## 1 Singapore 568.3597 910.742 191.0030 104.71272 5546
## 2 Viet Nam 510.5900 824.747 204.3230 83.52549 4959
## 3 Australia 492.8429 848.972 59.6744 98.53494 14481
## 4 USA 481.0325 822.021 174.0220 89.18490 4978
## 5 Thailand 441.1471 769.520 107.6570 91.86163 6606
Dù sao kết quả trên cũng thực sự xấu. Chúng ta nên làm đẹp kết quả bằng làm tròn các kết quả thành
0 chữ số sau dấu chấm bằng hàm round(). Nhưng tibble df3 lại chứa biến định tính Country mà hàm
round() thì không áp dụng cho biến định tính. Nên chiến lược được chấp nhận ở đây là tách (hay xóa)
biến định tính Country ra, rồi gán lại cuối cùng là sắp xếp lại:
## # A tibble: 5 × 6
## Country TB LN NN LC N
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Singapore 568 911 191 105 5546
## 2 Viet Nam 511 825 204 84 4959
## 3 Australia 493 849 60 99 14481
## 4 USA 481 822 174 89 4978
## 5 Thailand 441 770 108 92 6606
Còn một cách làm ngắn gọn, nhưng đòi hỏi các bạn cần biết viết hàm (hay lập trình hàm – funcional
programming) như sau:
## # A tibble: 5 × 6
## Country TB LN NN LC N
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Singapore 568 911 191 105 5546
## 2 Viet Nam 511 825 204 84 4959
## 3 Australia 493 849 60 99 14481
## 4 USA 481 822 174 89 4978
## 5 Thailand 441 770 108 92 6606
Ví dụ này cũng cho thấy sức mạnh và sự linh hoạt của kĩ năng lập trình đối khi thực hiện công việc
phân tích dữ liệu.
Với tibble có tên toan (hoặc df3) ở trên chúng ta có thể tạo ra một báo cáo đẹp với gói DT:
library(DT)
datatable(toan, rownames = FALSE, colnames = c("Quốc Gia",
"Trung Bình",
"Nhỏ Nhất",
"Lớn Nhất",
"Độ Lệch Chuẩn",
"Số Lượng HS"),
caption = "Bảng 1: Kết quả khảo sát môn Toán")
Tất nhiên chúng ta có thể lặp lại quá trình trên cho điểm đọc hiểu và khoa học. Nhưng đó không phải
là một chiến lược hiệu quả. Nên làm như sau (không hiển thị kết quả):
names(all)
View(all)
Dựa trên những gì quan sát được chúng ta có cách thức tách ra từng bộ dữ liệu tính các thống kê cho
toán, đọc, và khoa học như sau với lệnh select nhưng có thêm lựa chọn contains:
Ở đây, ngoài chọn biến CNT với lựa chọn contains("MATH") chẳng hạn có nghĩa là chúng ta chọn
các biến có chứa kí tự MATH.
Với các tiêu chí thống kê cho môn toán chẳng hạn chúng ta có thể làm đẹp hơn:
Thậm chí còn đẹp hơn nữa (không hiển thị kết quả):
math
Ở trên các bạn đã sử dụng một hàm là summarise_each(). Hàm này áp dụng một , thậm chí một loạt
hàm cho một hoặc thậm chí nhiều biến số như các bạn đã thấy. Có tác dụng tương tự là hàm
summarise():
Như các bạn có thể thấy trong tình huống bài toán của chúng ta thì lệnh này không hiệu quả bằng sử
dụng lệnh summarise_each().
Nhưng trong bất cứ trường hợp nào, nếu thực hiện những đòi hỏi tính toán như mô tả ở trên, nếu sử
dụng SPSS, STATA , Eviews, thậm chí là Excel thì chắc chắn không thể nhanh hơn sử dụng R (về thời
gian cần thao tác lẫn tốc độ). Nếu bộ dữ liệu mà hàng triệu hay hàng chục triệu quan sát thì bạn sẽ
thấy ngay lập tức hiệu ứng tốc độ và nhanh gọn khi sử dụng R cho những thống kê đơn giản này.
Bằng cách này chúng ta đã lưu file dữ liệu với tên diem_ba_mon.rda. Đây là file dữ liệu mà R có thể
đọc trực tiếp. Để biết file được lưu ở đâu các bạn cần biết đường dẫn hiện thời của R bằng cách gõ:
getwd()
Trong tình huống này file diem_ba_mon.rda được lưu ở folder có tên KTLR ở ổ D với đường dẫn
miêu tả như trên. Giả sử bạn đã thoát khỏi R. Để R tải lại file dữ liệu này:
setwd("D:/KTLR")
load("trangxinh.rda")
Bằng lệnh này, bạn lại trở lại làm việc với tibble có tên diem_ba_mon.rda.
Câu lệnh mà bạn vừa thực hiện ở trên đã lưu file all thành file có tên diem_ba_mon.rda và chỉ sử
dụng được trong R. Trong nhiều tình huống chúng ta cần lưu file này ở các định dạng khác nhau. Một
nguyên tắc chung cần tuân thủ là: nếu bạn sử dụng gói xlsx để đọc một file ở dạng Excel vào R thì khi
muốn lưu một data.frame sẵn có trong R thành một file Excel, công việc đầu tiên là bạn phải gọi gói
xlsx. Trong tình huống của chúng ta, vì đã gọi gói xlsx rồi nên chúng ta không cần thiết phải thực hiện
lệnh gọi gói xlsx. Giả sử với data.frame có tên dung ở mục 2.2.1 chúng ta muốn lưu file này ở dạng
Excel hoặc Stata với tên mới bất kì nào đó chúng ta làm như sau.
write.xlsx(dung, "adam.xlsx")
Lúc này sẽ có một file Excel có tên adam.xlsx lưu ở thư mục hiện thời mà R làm việc, tức KTLR.
write.dta(dung, "hehe.dta")
Bằng cách này chúng ta lưu file dung thành file Stata có tên hehe.dta.
Tuy nhiên tôi khuyến cáo là lưu các dữ liệu ở dạng .csv – một định dạng mà R đọc nhanh hơn:
write.csv(dung, "trangyeu.csv")
Còn nhiều câu lệnh để lưu một data frame sẵn có thành nhiều đinh dạng khác nhau. Nhưng điều này
thực sự không cần thiết vì hầu hết các phần mềm thống kê đều đọc được lẫn nhau. Ví dụ SPSS có thể
đọc được file Stata (và ngược lại). Còn đối với file Excel thì tất cả các phần mềm thống kê thường sử
dụng như Eviews, SPSS, Stata.. đều có thể đọc được. Nên các câu lệnh kia là không cần thiết. Bạn chỉ
cần chuyển một data frame trong R ra một file Excel – một định dạng mà hầu hết các phần mềm khác
đều sử dụng được.
2.9 Lưu các kết quả, các lệnh đã thực hiện cũng như các Objects để sử dụng cho lần sau
R là một ngôn ngữ lập trình hướng đối tượng (Object-oriented programming). Vậy như thế nào là
một đối tượng (Object) trong R? Nói cho dễ hiểu, một đối tượng trong R là bất cứ thứ gì được tạo ra
bởi phép gán <- (hoặc dấu = ). Và đương nhiên đối tượng phải được đặt tên.
Trở lại với mục 2.1 để minh họa khái niệm này. Ở đây chúng ta tạo ra ba biến số - hay ba đối tượng có
tên luong, thunhapkhac và chitieu. Mặt khác, lệnh trangxinh <- data.frame(luong, thunhapkhac,
chitieu) tạo ta một đối tượng thứ cấp có tên là trangxinh (gọi là thứ cấp vì nó được tạo ra từ ba đối
tượng đã có).
Một đối tượng cũng có thế là kết quả của một phân tích phức tạp nào đó, chẳng hạn, của phân tích hồi
quy OLS. Ở mục 2.8 chúng ta đã biết các lưu data_frame có tên all (là một object có cấu trúc tibble)
thành file có tên diem_ba_mon.rda. Tuy nhiên trong nhiều tình huống, chúng ta muốn không chỉ lưu
lại data frame này mà còn là tất cả các objects khác như sau:
Với lệnh này chúng ta sẽ lưu lại tất cả các objects vào file có tên tatcaobjects.Rdata. Tất nhiên file
này được lưu ở thư mục hiện thời là KTLR thuộc ổ D của máy tính. Nếu muốn sử dụng tất cả các
objects này cho các lần phân tích sau:
load("tatcaobjects.RData")
Để biết hiện R đang quản lý những object nào chúng ta dùng lệnh:
ls()
Trong một số tình huống, chúng ta cũng còn cần quét sạch (loại bỏ) tất cả các object như sau:
rm(list = ls())
Duới đây là hai câu lệnh hiển thị 25 dòng cũng như tất cả các câu lệnh lệnh vừa thực hiện:
Dưới đây là những lệnh để lưu lại tất cả dòng lệnh với một file có tên là caclenh.Rhistory cũng như
tải lại các dòng lệnh được lưu trong file này:
Lưu lại tất cả các object cũng như lệnh là một lợi thế của R so với nhiều phần mềm thống kê – kinh tế
lượng khác. Điều này đặc biệt hữu ích nếu những phân tích của chúng ta kéo dài trong nhiều ngày,
thậm chí nhiều tuần.
2.10 Thực hiện các tính toán thông thường, đại số tuyến tính
R cũng có thể thực hiện mọi chức năng tính toán số học thông thường và cả các phép tính phức tạp
như tìm ma trận nghịch đảo, ma trận chuyển vị, nhân ma trận.. đến tính tích phân. Tuy nhiên, trong
mục này chúng ta chỉ xem xét những chức năng tính toán cơ bản nhất trong R. Dưới đây là một số câu
lệnh mà các bạn nên thực hiện để tự tìm hiểu các chức năng tính toán của R:
3 + 4
## [1] 7
3*4
## [1] 12
3 / 4
## [1] 0.75
2^3
## [1] 8
Các bạn cũng có thể thấy R là một ngôn ngữ hướng đối tượng. Ví dụ trong chuỗi câu lệnh dưới đây
tạo tạo một đối tượng (Object) có tên bankinh và gán cho nó giá trị 2 rồi thực hiện các tính toán bình
thường:
bankinh <- 2
chuvi=2*pi*bankinh
chuvi
## [1] 12.56637
abs(-2)
## [1] 2
sqrt(9)
## [1] 3
Với biến số luong chúng ta có thể thực hiện một số tính toán sau:
luong*luong
## [1] 400 900 784 576 1764 1296 1024 1156 576 484 784 900
1 / luong
mean(luong)
## [1] 29.16667
luong / 4
## [1] 5.0 7.5 7.0 6.0 10.5 9.0 8.0 8.5 6.0 5.5 7.0 7.5
Tất nhiên chức năng tính toán của R không chỉ giới hạn như như vậy. Chúng ta sẽ quen dần với các
tính toán phức tạp hơn của R trong các chương sau.
R cũng có thể thực hiện tất cả các tính toán của đại số tuyến tính. Giả sử chúng ta có ma trận A như
sau:
2 5 2
𝐴=[ ]
6 1 4
Tạo ma trận này trong R:
## [1] 2 3
At <- t(A)
At
## [,1] [,2]
## [1,] 2 6
## [2,] 5 1
## [3,] 2 4
Chú ý điểm khác biệt giữa các lệnh trong việc tạo ma trận mà chúng ta vừa sử dụng với:
1 0 0
𝐼 = [0 1 0 ]
0 0 1
I <- diag(3) # Tạo ma trận đơn vị kích thước 3
I
A*A # Chú ý kiểu nhân này vì nó khác với ma trận nhân ma trận.
Giả sử chúng ta cần thực hiện phép trừ hai ma trận sau:
2 6 −2 8.1
[5 1] − [ 3 8.2 ]
2 4 6 −9.8
m <- matrix(c(2, 5, 2, 6, 1, 4), nrow = 3)
m
## [,1] [,2]
## [1,] 2 6
## [2,] 5 1
## [3,] 2 4
## [,1] [,2]
## [1,] -2 8.1
## [2,] 3 8.2
## [3,] 6 -9.8
m-n
## [,1] [,2]
## [1,] 4 -2.1
## [2,] 2 -7.2
## [3,] -4 13.8
3 −3
2 5 2
[ ] . [−1 1]
6 1 4
1 5
Thực hiện trong R:
## [,1] [,2]
## [1,] 3 -3
## [2,] -1 1
## [3,] 1 5
## [,1] [,2]
## [1,] 3 9
## [2,] 21 3
B%*%A # Kiểm tra tính chất của nhân ma trận: AB thường là khác BA.
3 1
[ ]
4 2
A <- matrix(c(3, 4, 1, 2), nrow = 2)
A
## [,1] [,2]
## [1,] 3 1
## [2,] 4 2
## [,1] [,2]
## [1,] 1 -0.5
## [2,] -2 1.5
## [,1] [,2]
## [1,] 1 0
## [2,] 0 1
𝑥1 + 𝑥2 = 2
−𝑥1 + 𝑥2 = 4
Hệ này được viết theo ngôn ngữ ma trận là:
1 1 𝑥1 2
( ) (𝑥 )=( )
−1 1 2 4
Giả hệ này trong R như sau:
## [,1]
## [1,] -1
## [2,] 3
solve(a, b) # Cách 1
## [,1]
## [1,] -1
## [2,] 3
Kết quả này nghĩa là x1 = -1 và x2 = 3 như chúng ta đã biết trong quy ước của đại số tuyến tính.
R còn có thể thực hiện nhiều tính toán phức tạp khác không chỉ cho đại số tuyến tính mà còn là giải
tích, tối ưu hóa hay xây dựng các mô hình xác suất, các mô hình thống kê. Trên đây chỉ minh họa
những tính năng cơ bản (nhưng thiết yếu cho kinh tế lượng). Những tính toán phức tạp và chuyên
sâu hơn với R các bạn có thể tìm thấy ở nhiều tài liệu khác nhau.
cạnh lý thuyết của các mô hình cũng như các phương pháp thống kê. Đặc biệt quan trọng là mô phỏng
Monte Carlo – vốn phát sinh từ nỗ lực chế tạo quả bom nguyên tử đầu tiên thuộc dự án tối mật
Manhattan cuối những năm thế chiến thứ hai. Tuy nhiên, trong chương này chúng ta không đi sâu
vào các mô phỏng phức tạp mà chỉ chỉ quan tâm đến một số chức năng mô phỏng đơn giản của R cho
một số phân phối mà chúng ta hay sử dụng được cho ở bảng sau:
Student rt(n,df=m)
F rf(n,df1=a,df2=b)
Ví dụ, chúng ta có thể tạo 100 quan sát ngẫu nhiên với trung bình là 50 và sai số chuẩn là 10:
Chú ý rằng các con số mà bạn thu được là không giống của tôi. Và mỗi khi thực hiện lại chính câu lệnh
trên thì kết quả lại khác. Ngoài ra mean và sd ứng với các quan sát thu được cũng không nhất thiết
bằng 50 và 10. Để cố định các kết quả trước khi thực hiện lệnh trên chúng ta thực hiện lệnh “gieo hạt”
như đã biết:
set.seed(29)
Để thuận tiện chúng ta nên gán 100 quan sát này thành một vector (hiểu như là một object, biến số
trong R) với tên là x chẳng hạn:
## [1] 48.8063
sd(x)
## [1] 10.0689
Các bạn có thể thấy rằng trung bình là 48.86 và độ lệch chuẩn là 10.07 chứ không chính xác bằng 50
và 10. Nếu bạn thực hiện khoảng 1 tỉ lần tạo mẫu ngẫu nhiên và bạn có 1 tỉ cặp giá trị trung bình cũng
như độ lệch chuẩn rồi lấy trung bình cho chúng thì kết quả sẽ tiến sát đến 50, 10. Về lý thuyết, nếu
bạn thực hiện qúa trình này vô cùng lần thì các trung bình lần lượt chính xác bằng 50 và 10.
Tương tự chúng ta cũng có thể tạo ra 100 quan sát với bậc tự do df = 3 có phân phối t:
y <- rt(100, df = 3)
y
Chúng ta có thể thực hiện các phân tích hình ảnh với mẫu ngẫu nhiên y:
par(mfrow = c(1, 1)) # Trở lại chế độ hiển thị mặc định
Tất nhiên chúng ta có thể thực hiện nhiều phân tích với các dữ liệu mô phỏng thu được như phân tích
hồi quy y theo x:
summary(lm(y ~ x))
## Call:
## lm(formula = y ~ x)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.8723 -0.7264 0.0295 0.9023 3.5094
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.677736 0.706838 -0.959 0.340
## x 0.007291 0.014187 0.514 0.608
##
## Residual standard error: 1.421 on 98 degrees of freedom
Khả năng mô phỏng của R chúng ta sẽ dần tìm hiểu trong các chương sau của tài liệu.
5. Sau các phép toán cộng, trừ, nhân, chia, dấu gán, dấu phẩy thì dấu cách phải được sử dụng.
Chính vì thế mà cách thức viết code sau là sai:
x<-c(1, 2, 3)
y <- c(1,2,3)
6. Ngoại lệ cho sử dụng dấu cách là trường hợp của dâu hai chấm. Cách viết đúng trong trường
hợp có sử dụng dấu hai chấm là:
z <- 1:10
7. Nếu một project được tiến hành qua nhiều công đoạn (block) nhỏ thì mỗi một block nên có
một tiêu đề để giải thích bằng sử dụng nhiều dấu # theo cách thức như sau:
##########################################################
### Dưới đây là phân tích hình ảnh cho bộ dữ liệu iris ###
##########################################################
par(mfrow = c(2,2))
par(bg = "grey98")
for (i in 1:4) {
boxplot(iris[, i] ~ iris$Species,
main = names(iris)[i],
col = rainbow(3))
}
8. Dấu # cũng được sử dụng để giải thích cho các dòng lệnh theo một trong hai cách thức sau:
##--------------
## Cách 1
##--------------
##-------------
## Cách 2
##-------------
set.seed(1) # Cố định kết quả.
rnorm(10) # Tạo ra 10 quan sát ngẫu nhiên có phân phối chuẩn hóa
9. Với các lệnh phức tạp có nhiều options thì chúng cũng nên được giải thích bằng cách sử dụng
hai dấu ## liên tiếp như sau (không hiển thị kết quả):
ggplot(data = mpg) +
geom_point(aes(x = displ, y = hwy, color = class)) +
## Đặt tiêu đề cho graph:
ggtitle("Vi du ve giai thich cho cau lenh")+
## Đặt tên cho trục X:
xlab("Day la truc X")
Các quy ước về cách viết code như trên là một quy ước được thừa nhận rộng rãi không chỉ trong giới
sử dụng R mà còn ở nhiều ngôn ngữ lập trình khác.
Trước đây tôi không được biết đến những nguyên tắc này (và việc không nên sử dụng dấu = thay cho
<- khi thực hiện phép gán) vì thế viết R code vô nguyên tắc và tạo thành một thói quen rất khó sửa.
Vì lí do này, các bạn có thể phát hiện ở đâu đó tôi vi phạm những nguyên tắc trên trong tài liệu này
dù đã rất cố gắng sửa một lỗi đã ăn vào máu.
Hi vọng các bạn không lặp lại sai lầm (và phải sửa sai) như tôi đã mắc.
Giải thích kĩ nguyên nhân của việc không sử dụng lệnh attach có lẽ cần một chút kiến thức của
Computer Science và sẽ không được trình bày ở đây. Bạn nào quan tâm có thể tham khảo cuốn Hands-
on Programming with R đã đề cập ở trên.
Một số tài liệu các bạn có thể thấy dấu = có thể được sử dụng thay cho dấu <- khi thực hiện phép gán.
Nghĩa là, thay vì gõ:
y <- c(1, 2, 3)
Tuy nhiên trong tài liệu này tôi sẽ không sử dụng dấu = thay cho <- khi thực hiện phép gán. Chi tiết
nhỏ này có thể làm hỏng một chương trình lớn hơn nhiều lần. Tôi đã từng viết một chương trình phân
tích rất dài (chừng 500 dòng lệnh) nhưng nó không hoạt động. Dù rằng cú pháp và mọi thứ khác đều
đúng. Tìm tòi hai ngày cũng không phát hiện ra lỗi nên đành phải gửi cho một chuyên gia về sử dụng
R thẩm định. Câu trả lời vô cùng đơn giản: tôi đã sử dụng không chỉ một, mà tới hai dấu = ở một khâu
then chốt của chương trình.
Một dự án phân tích có thể rất dài và việc viết sai lệnh là điều thường thấy và dễ dàng tìm ra sai ở
dòng lệnh nào. Tuy nhiên nếu sử dụng dấu = thì R sẽ không coi đây là một lỗi sai về cú pháp nhưng
chính dấu = này lại là nguyên nhân làm cho toàn bộ chương trình không hoạt động.
Vì lí do này, dấu = sẽ không được sử dụng để thực hiện phép gán trong tài liệu này.
2.14 Lưu ý khi gặp tình huống cùng một tên hàm tồn tại ở hai hay nhiều gói
Khi gọi nhiều gói khác nhau có thể xẩy ra tình huống sau: có hai gói cùng có một hàm trùng nhau về
tên (dù rằng hai hàm này có thể có thực hiện những công việc khác nhau hoàn toàn). Ví dụ, hàm
filter() là một hàm thuộc gói dplyr (thuộc hệ sinh thái tidyverse mà chúng ta đã biết) nhưng nó cũng
là một hàm của gói stats (luôn mặc định xuất hiện khi khởi động R). Trong tình huống này, chúng ta
nên chỉ thị cụ thể cho R hiểu là chúng ta muốn sử dụng hàm, chẳng hạn filter() của gói nào theo cách
thức đặc biệt sau:
library(tidyverse)
dplyr::filter(iris, Sepal.Length > 7.3)
Ở đây chúng ta sử dụng lệnh filter() để lọc ra các quan sát mà Sepal.Length lớn hơn 7.3 còn kí hiệu
dplyr:: xuất hiện ngay trước lệnh này có nghĩa là chỉ thị cụ thể cho R rằng sử dụng lệnh filter() của
gói dplyr chứ không phải của gói stats.
Một điểm nữa cần lưu ý là trong tình huống hai (hay nhiều) gói có chứa cùng một hàm thì hàm thuộc
về gói được gọi sau cùng sẽ được ưu tiên sử dụng nếu chúng ta không tuyên bố rõ ràng về gói được
sử dụng để thực thi hàm đó.
Chương này chúng ta sẽ thực hành tìm các thống kê mô tả cho các biến số cũng như tìm các giá trị thống
kê phổ biến thường sử dụng trong nghiên cứu thống kê – kinh tế lượng như phân phối chuẩn N, phân
phối Student t, phân phối F, và phân phối khi bình phương χ2. Chương này cũng trình bày môt số kĩ
thuật cũng như một số nguyên tắc cơ bản của hình ảnh hóa dữ liệu (Data Visualization).
Để minh họa ý nghĩa của các hàm này, lấy ví dụ với bộ số liệu ch2_health.WF1:
library(hexView)
dung <- readEViews("ch2_health.WF1", as.data.frame = TRUE)
summary(dung) # Xem các thống kê cơ bản của tất cả các biến
cor(dung)
Nếu chỉ quan tâm đến các thống kê cơ bản, hay một thống kê cụ thể nào đó cho biến INCOME mà thôi:
Ở đây lần đầu tiên các bạn sử dụng một kí hiệu đặc biệt: dấu $ (kí hiệu của đồng Dollar). Lưu ý rằng
dung (là một object trong R dạng data frame ) chứa các biến số HEALTH, INCOME, và POP. Do đó, để
chỉ thị R, chẳng hạn, áp dụng lệnh summary() cho biến INCOME thì chúng ta phải chỉ thị một cách rõ
ràng là summary(dung$INCOME) .
Còn một lí do phải sử dụng kí hiệu $. Giả sử còn một data frame nữa có tên là trang cũng chứa biến
INCOME. Lúc đó, nếu gõ lệnh summary(INCOME) thì R sẽ không hiểu là áp dụng hàm summary() cho
biến INCOME thuộc dung hay trang. Vì lí do này, nếu muốn chỉ thị cho R “làm việc” với INCOME thuộc
trang thì phải gõ summary(trang$INCOME).
Nếu muốn biết, chẳng hạn, ngũ phân vị cho tất cả các biến số:
sapply(dung, quantile)
Ở đây có thể nói chúng ta sử dụng “song song” hai lệnh cùng một lúc. Cụ thể, khi ta sử dụng lệnh
sapply() như trên thì R sẽ hiểu là áp dụng lệnh quantile() cho tất cả các côt biến có trong data frame
tên dung.
Nếu sử dụng toán tử pipe thì tất cả những kết quả trên có thể thu được bằng những dòng lệnh sau
(theo thứ tự xuất hiện):
library(magrittr)
dung %>% summary()
dung %>% cor()
dung %>% summary(.$INCOME)
dung %>% quantile(.$INCOME, probs = seq(0, 1, 0.25))
Một ngoại lệ khi áp dụng toán tử pipe với hàm tính ngũ phân vị là ta phải tuyên bố rõ các mức xác
suất từ 0, 0.25, 0.50, 0.75 và 1.00 một cách rõ ràng:
Đương nhiên câu lệnh này hoàn toàn tương đương với một trong hai câu lệnh sau:
quantile(dung$INCOME)
quantile(dung$INCOME, probs = seq(0, 1, 0.25))
Để biết ý nghĩa của lựa chọn probs = seq(0, 1, 0.25) thực hiện các lệnh sau:
Đây cũng chính là cách thức mà các bạn nên làm quen để sử dụng R thành thạo: tỉ mỉ xem xét từng
lựa chọn của một dòng lệnh rất dài có nhiều lựa chọn khác nhau.
# Hiển thị các kết quả chính xác đến 4 chữ số sau dấu phẩy
options(digits = 4)
options(digits = 10)
library(pastecs)
stat.desc(dung)
Qua kết quả này các bạn có thể thấy ngoài các thống kê thông thường còn có các thống kê chi tiết hơn.
Ví dụ, quãng đáng tin 95% của HEALTH nằm trong khoảng từ 19929 – 6216 đến 19929 + 6216. Còn
giá trị coef.var = 1.109 chính là thương số của std.dev chia cho mean. Giá trị CI.mean.0.95 là khoảng
tin cậy 95% cho các biến số (CI là viết tắt của chữ Confidence Interval ). Có thể thu gọn kết quả trên
như sau:
stat.desc(dung, desc = F)
library(stargazer)
stargazer(dung, type = "text", title = "Cac Thong Ke Mo Ta", digits = 3)
## Cac Thong Ke Mo Ta
## ===================================================
## Statistic N Mean St. Dev. Min Max
## ---------------------------------------------------
## HEALTH 51 19,929.000 22,102.000 1,407 110,057
## INCOME 51 144,153.000 169,140.000 11,700 920,500
## POP 51 5,299.000 5,917.000 480 32,683
## ---------------------------------------------------
Đây cũng là các thống kê tiêu chuẩn thường được trình bày trong các báo cáo và nghiên cứu khoa học.
Thực ra ứng dụng lớn nhất của gói này là trình bày các kết quả nghiên cứu ở dạng một cách đẹp mắt
tương tự như gói outreg2 trong Stata chứ không đơn giản là chụp lại màn hình để trình bày kết quả
(vì thực tế là, R đưa ra các trình bày kết quả không được đẹp mắt như một số phần mềm khác). Tất
nhiên việc sử dụng chi tiết gói này còn liên quan mật thiết với việc sử dụng LaTex. Điều này vượt quá
khuôn khổ của cuốn sách này nên tôi không trình bày ở đây.
Đây là một ví dụ về ứng dụng của gói này: các bạn có thể xuất ra một file dữ liệu ở dạng file Word với
tên ketqua.doc ở thư mục hiện thời của R:
Có thể suy luận trước rằng kết quả này được lưu ở thư mục KTLR thuộc ổ D của máy tính.
library(fBasics)
basicStats(dung)
Hoặc chỉ quan tâm đến các thống kê cho biến INCOME mà thôi (không hiển thị kết quả):
basicStats(dung$INCOME)
So sánh cách thức R hiển thị kết quả với cặp dòng lệnh sau (không hiển thị kết quả):
options(digits = 3)
basicStats(dung)
3.2 Tìm các giá trị thống kê và mức xác suất của phân phối N, t, F,và χ2
Khi nghiên cứu thống kê – kinh tế lượng thông thường chúng ta cần biết một số thống kê của các phân
phối chuẩn (N), thống kê Student (t), thống kê F, và thống kê khi bình phương (χ2). Truyền thống thì
chúng ta tra các bảng thống kê được in ở những trang cuối cùng của các sách về thống kê và kinh tế
lượng. Trong R (cũng như các phần mềm khác) cho phép chúng ta tìm các thống kê này mà không cần
tra bảng – một việc thường gây nhầm lẫn và nhàm chán.
1 1 𝑥−𝜇 2
𝑒 2 𝜎 )
− (
𝑓(𝑥) = −∞<𝑥 < ∞
𝜎√2𝜋
Với phân phối chuẩn N chúng ta thường làm hai bài toán ngược nhau: (1) tìm xác suất – hay diện tích
giới hạn bởi hàm mật độ xác suất với các đường x1 = a, x2 = b, và (2) tìm giá trị ZA.
Giả sử chúng ta cần tính P(x ≤ 1100) với một phân phối chuẩn có trung bình 1000 và sai số chuẩn là
100. Trong R ta làm như sau:
## [1] 0.8413447
## [1] 0.1586553
Hoặc chúng ta có thể gõ cách khác trong R để tra kết quả như trên:
## [1] 0.1586553
Tất nhiên, với phân phối chuẩn hóa thì μ = 0 và σ = 1 nhưng cách thức thực hiện không khác. Chúng
ta xét ba ví dụ dưới đây (nhìn hình trang kế tiếp):
Chúng ta có thể tìm ra các kết quả như trên mà không cần tra bảng:
pnorm(-0.71, 0, 1)
## [1] 0.2388521
pnorm(0.92, 0, 1)
## [1] 0.8212136
pnorm(0.92, 0, 1) - pnorm(-0.71, 0, 1)
## [1] 0.5823616
Tuy nhiên, đã là phân phối chuẩn hóa thì R cho phép ta làm nhanh hơn như sau mà không cần gõ mãi
hai số 0 và 1:
pnorm(-0.71)
## [1] 0.2388521
pnorm(0.92)
## [1] 0.8212136
pnorm(0.92) - pnorm(-0.71)
## [1] 0.5823616
Ngược lại với bài toán tìm xác suất ở trên chúng ta có bài toán tìm giá trị ZA:
Bài toán ở đây là nếu biết diện tích A =0.025 chẳng hạn, thì ZA là bao nhiêu? Trong R hàm qnorm(1-A,
μ, σ) sẽ tìm ra giá trị ZA này. Ví dụ, nếu một phân phối chuẩn có trung bình là 1000, sai số chuẩn 100,
A = 0.1586 thì chúng ta có thể tính ZA trong R như sau:
## [1] 1100.023
Các sách thường cho các bảng tra ZA kiểu như sau:
Với phân phối chuẩn hóa, chúng ta không cần gõ 0,1 ở các câu lệnh mà chỉ cần gõ :
qnorm(0.95)
## [1] 1.644854
Nghĩa là chúng ta không cần tra bảng để tìm ra giá trị ZA =0.5(1.64+1.65) = 1.645 (nếu làm tròn tới 3
chữ số).
Bậc tự do v càng lớn thì phân phối t càng tiến về phân phối chuẩn. Trong thực hành thì v ≥ 200 có thể
coi phân phối t là phân phối chuẩn. Với phân phối t chúng ta thường phải tìm tA,v sao cho P(t>tA,v) = A:
Trong cách sách về thống kê – kinh tế lượng người ta thường cho các giá trị tA,v dưới dạng bảng như
sau:
Chúng ta có thể tìm các giá trị này trong R theo cú pháp qt(1-A,df=v) mà không cần tra bảng:
qt(0.9, df = 3)
## [1] 1.637744
qt(0.975, df = 3)
## [1] 3.182446
qt(0.95, df = 35)
## [1] 1.689572
qt(0.99, df = 35)
## [1] 2.437723
Tất nhiên chúng ta cũng có thể giải bài toán ngược (tìm xác suất) như sau trong R:
pt(1.638, df = 3)
## [1] 0.9000262
pt(1.689, df = 35)
## [1] 0.9499447
Trong nhiều tình huống chúng ta có thể phải thực hiện kiểm định hai phía. Các bạn thử suy nghĩ về ý
nghĩa của hai câu lệnh sau cho phân phối t và N:
qnorm(c(0.025, 0.975))
Với A = 0.05, trong các sách thống kê – kinh tế lượng các giá trị của thống kê F thường được cho ở
dạng bảng như sau:
Chúng ta có thể tính một số giá trị này trong R mà không cần tra bảng:
## [1] 6.944272
## [1] 8.8123
Với v1=9, v2=3 chúng ta có thể tìm đồng thời cả F0.05 và F0.95 như sau:
Trong các sách thống kê – kinh tế lượng các giá trị của thống kê χ2 thường được cho ở dạng bảng như
sau:
Chúng ta có thể tính một số giá trị này trong R mà không cần tra bảng:
qchisq(0.025, df = 3)
## [1] 0.2157953
qchisq(0.99, df = 2)
## [1] 9.21034
Các bạn thử suy nghĩ mối liên hệ giữa kết quả của ba câu lệnh sau:
qchisq(c(0.025, 0.975), df = 3)
pchisq(0.2158, df = 3)
## [1] 0.02500078
pchisq(9.3483, df = 3)
## [1] 0.9749988
Vai trò của sử dụng hình ảnh hay hình ảnh hóa dữ liệu (Data Visualization) quan trọng đến mức mà
nhà thống kê học John Tukey đã phát biểu rằng “Hình ảnh, dù đơn giản, cũng mang lại nhiều thông
tin cho người phân tích (số liệu) hơn bất cứ phương tiện nào”.
Trong phần này chúng ta sẽ thực hành các vẽ các Graph, đồ thị thường gặp khi nghiên cứu thống kê
– kinh tế lượng với hai gói basic graphics và ggplot2 (dù rằng R còn nhiều gói khác hỗ trợ đồ họa).
Gói base graphics là gói mặc định xuất hiện trong trong R và do đó chúng ta không cần thực hiện lệnh
gọi gói này. Chất lượng hình ảnh tạo ra bởi gói này không tốt (nhưng thừa đủ để thực hiện tất cả các
chức năng vẽ như bất kì phần mềm nào khác). Gói ggplot2 được ra đời nhằm đáp ứng cho các yêu cầu
về chất lượng hình ảnh cũng như các Graphs có mức độ phức tạp cao. Tất nhiên sử dụng gói này cũng
phức tạp hơn. Dưới đây chúng ta chỉ thực hành một số lệnh đơn giản nhất (nhưng đủ dùng) cho mục
đích phân tích số liệu sơ bộ và cơ bản. Vì nếu nghiên cứu tính năng này của R một cách chi tiết có lẽ
cần một tài liệu rất dài.
Với mục đích minh họa, phần này chúng ta sẽ nghiên cứu bộ dữ liệu CPS1988 có trong gói AER mà
chúng ta đã biết ở chương 2
Bạn có thể thay "blue" bằng "pink" nếu thích màu hồng. Thậm chí là bỏ hẳn cả cụm col = "blue"
trong dòng lệnh trên.
Giả sử chúng ta cần vẽ đường hồi quy cho mô hình ln(wage) = β + β2education trên cùng với Scatter
Plot ở trên:
Chúng ta có thể thay đổi: (1) hình dạng của điểm, (2) kích thước của đường, và (3) kiểu đường trong
R. Trước hết chúng ta chia màn hình hiển thị của R thành 1 hàng và 2 cột (tức có thể hiển thị 2 hình
ảnh cùng lúc) bằng lệnh par(mfrow = c(1,2)). Để minh họa chúng ta sử dụng bộ số liệu
ch2_health.wf1 về chi cho y tế (HEALTH) và thu ngân sách (INCOME) của 51 bang tại Mĩ:
setwd("D:/KTLR")
library(hexView)
dung<-readEViews("ch2_health.wf1",as.data.frame=TRUE)
head(dung)
par(mfrow = c(1, 2)) # Đặt cửa sổ hiển thị thành 1 hàng và 2 cột.
plot(HEALTH ~ INCOME, data = dung, col = "blue", pch = 17)
abline(lm(data = dung, HEALTH ~ INCOME), col = "red", lwd = 2, lty = 5)
plot(HEALTH ~ INCOME, data = dung, pch = 4)
abline(lm(data = dung, HEALTH ~ INCOME), col = "green", lty = 6)
par(mfrow = c(1, 1)) # Đặt lại chế độ hiển thị mặc định.
Ở đây lwd = 2 là độ dày của đường (mặc định là 1) còn lty = 5 là kiểu đường thẳng được hiển thị, pch
= 17 là kiểu hình dạng của điểm. Cụ thể, kiểu hình dạng được cho ở bảng sau:
3.3.1.2 Histogram
Chúng ta có thể vẽ Histogram cho ln(wage) theo 6 cách thức khác nhau (chú ý hiệu ứng của những
câu lệnh này):
Chúng ta cũng có thể tạo ra Histogram và tần suất tuyệt đối của mỗi class:
Các câu lệnh trên sẽ tạo ra một histogram với số quãng (intervals) mặc định tính theo công thức sau
của Sturges:
R sẽ vẽ Histogram theo công thức này. Tuy nhiên nếu muốn, chúng ta có thể hiệu chỉnh số class nếu
muốn. Ngoài ra, chúng ta cũng có thể vẽ đường thẳng đứng biểu thị giá trị trung bình của log(wage):
par(mfrow=c(1, 2))
hist(log(CPS1988$wage), col = "pink", nclass = 35, main = "")
hist(log(CPS1988$wage), col = "pink", nclass = 35, main = "")
abline(v = mean(log(CPS1988$wage)), col = "blue", lwd = 2)
par(mfrow=c(1, 1))
par(mfrow=c(1, 2))
d <- density(log(wage))
plot(d, main = "")
plot(d, main = "", frame = FALSE)
polygon(d, col = "steelblue")
par(mfrow = c(1, 1))
Chúng ta cũng có thể kết hợp vẽ hàm mật độ xác suất và histogram:
3.3.1.4 Boxplots
Chúng ta có thể tạo các Boxplots cho ln(wage) đồng thời cho cả 4 vùng địa lý khác nhau:
boxplot(log(CPS1988$wage) ~ CPS1988$region)
boxplot(log(CPS1988$wage) ~ CPS1988$region,
col = c("blue", "sienna", "palevioletred1", "green"))
Boxplots cung cấp rất nhiều thông tin giá trị về mẫu nghiên cứu (đáng tiếc là các sách viết về chúng
chưa kĩ ở mức độ tối thiểu mà một người học thống kê – kinh tế lượng cần có). Ví dụ, chúng ta có thể
thấy rằng: (1) mức lương trung bình của lao động vùng northeast là cao nhất còn vùng south là thấp
nhất, (2) mức lương của cả 4 vùng bị méo về phía dương (positive skewness) và méo mạnh nhất là
vùng midwest, và (3) các điểm dữ liệu nằng ngoài phạm vi râu trên và râu dưới chính là các outliers
– những quan sát bất thường (Keller, 2004). Nhắc lại ý nghĩa của boxplot như sau:
Nghĩa là chúng ta sẽ có 50% số quan sát nằm trong khoảng từ phân vị thứ nhất Q1 đến phân vị thứ
ba Q3 . Còn Q2 chính là trung vị (median). Nếu Q2 – Q1 > Q3 – Q2 thì phân phối sẽ méo về phía dương
(positive skewness) và ngược lại. Nếu Q2 nằm chính giữa thì chúng ta có phân phối chuẩn. Ngoài ra,
bất kì giá trị nào thỏa mãn một trong hai điều kiện sau thì được gọi là các bất thường: (1) bé hơn [Q1
– 1.5⨉(Q3-Q1)] , hoặc (2) lớn hơn [Q3 + 1.5⨉(Q3-Q1)]. Nhìn chung, các thông tin mang lại từ boxplot
là tương tự như histogram nhưng cụ thể hơn. Để minh họa chúng ta nghiên cứu cụ thể boxplot cho
log(wage) cho toàn bộ mẫu nghiên cứu:
boxplot(log(CPS1988$wage))
Chúng ta có thể thấy rằng Q2 – Q1 > Q3 – Q2 nên phân phối của log(wage) là méo về phía dương
(chúng ta có thể thấy từ mục 3.3.1.3 hoặc 3.3.1.4). Chúng ta có thể xác nhận một lần nữa nhận định
của chúng ta như sau:
quantile(log(CPS1988$wage))
6.258280-5.732176
## [1] 0.526104
6.663746-6.258280
## [1] 0.405466
Chúng ta có thể thấy rằng Q2 – Q1 = 0.526 > Q3 – Q2 = 0.405 nên chúng ta có thể thấy phân phối của
log(wage) là méo về phía dương. Chúng ta cũng có thể tính cận trên và dưới cho râu:
## [1] 4.334821
ct
## [1] 8.061101
Thay vì tính thủ công như trên chúng ta có thể làm nhanh hơn như sau:
boxplot(log(CPS1988$wage))$stats[c(1, 5), ]
Chúng ta có thể nhận diện một số quan sát là outlier như sau (trích một số quan sát):
boxplot.stats(log(CPS1988$wage))$out
## [1] 439
Chúng ta cũng có thể tính số % các outlier này so với toàn bộ mẫu nghiên cứu:
length(boxplot.stats(log(CPS1988$wage))$out) / length(CPS1988$wage)
## [1] 0.01559226
Có nghĩa là có tầm 1.56% lao động hoặc là có thu nhập quá thấp, hoặc là quá cao.
Ở trên các bạn tô màu cho bốn box plot bằng cách gõ tên của bốn màu. Rõ ràng cách tô màu này là kô
ng tiện dụng, đặc biệt là trong tình huống có nhiều boxplot. Để thuận lợi chúng ta có thể tô màu với s
ự trợ giúp của gói RcolorBrewer. Trước hết chúng ta liệt kê tất cả các màu cung cấp bởi gói này:
library(RColorBrewer)
display.brewer.all() # Hiển thị tất cả các màu sắc.
Hoặc chúng ta muốn hiển thị tất cả 8 màu của dải màu có tên Dark2:
display.brewer.pal(n = 8, name = "Dark2") # Hiển thị 8 màu của dải màu có tên
Dark2.
R quy định rằng mỗi một màu sắc có thể được chỉ định bằng một trong hai cách thức sau: (1) tên cụ
thể (như red, yellow), hoặc (2) mã màu. Chúng ta có thể hiển thị mã màu cho 8 màu sắc ứng với dải
màu Dark2:
Điều này có nghĩa là, chẳng hạn, màu xanh đầu tiên trong dải có mã là #1B9E77. Chúng ta có thể tô
màu tự động mà không cần gõ tên màu một cách thủ công như vừa làm. Hãy so sánh kĩ hiệu ứng của
những dòng lệnh sau:
par(mfrow=c(1, 2))
# Dùng 4 màu đầu tiên của dải màu Dark2
boxplot(log(CPS1988$wage) ~ CPS1988$region, col = kihieu[1:4])
# Câu lệnh kiểu khác nhưng tương đương
boxplot(log(CPS1988$wage) ~ CPS1988$region, col = kihieu)
Dưới đây là câu lệnh vẽ bốn boxplot trên nhưng sử dụng 4 màu sắc cuối cùng của dải màu theo hai
cách khác nhau nhưng tạo ra cùng một hiệu ứng:
par(mfrow=c(1, 2))
boxplot(log(CPS1988$wage) ~ CPS1988$region,
col =c("#66A61E", "#E6AB02", "#A6761D", "#666666"))
boxplot(log(CPS1988$wage) ~ CPS1988$region,
col = c(kihieu[5:6],"#A6761D", "#666666"))
Việc tô màu tự động cũng có thể được thực hiện theo một cách khác là sử dụng hàm rainbow() – mô
phỏng màu sắc của dải cầu vồng. Hãy chú ý sự khác biệt của hai câu lệnh sau:
par(mfrow=c(1, 2))
boxplot(log(CPS1988$wage) ~ CPS1988$region,
col = rainbow(4))
boxplot(log(CPS1988$wage) ~ CPS1988$region,
col = c(kihieu[5:6], "pink", "yellow"))
par(mfrow=c(1,1))
Ở đây các bạn có thể ở nhóm boxpot thứ hai chúng ta chọn 2 màu theo ý muốn (là pink và yellow)
cộng với với hai mã của màu thứ 5 và 6 trong dải màu Dark2.
Tương tự, chúng ta cũng có thể sử dụng hàm qualiPalette() của gói fBasics để chọn màu tự động.
Đáng chú ý là hàm này sử dụng các dải màu được cung cấp bởi gói RcolorBrewer:
library(fBasics)
mausac <- qualiPalette(12, "Set3") # Chọn dải màu có tên Set3.
boxplot(log(CPS1988$wage) ~ CPS1988$region, col = mausac)
Với các thức tô màu tự động như trên chúng ta không cần phải tô màu bằng gõ tên của các màu.
Hoặc theo cả khu vực địa lý và sống ở khu vực đô thị hay phi đô thị:
Chú ý một lần nữa lệnh chọn màu tự động mausac <- qualiPalette(2,"Set3"). Nếu không có lệnh này,
bar plot của bạn sẽ có thể gây hiểu nhầm. Chúng ta có thể diễn giải với các con số:
addmargins(prop.table(trang, 2))
## region
## smsa northeast midwest south west Sum
## no 0.1535476 0.3022002 0.2837900 0.2748317 1.0143695
## yes 0.8464524 0.6977998 0.7162100 0.7251683 2.9856305
## Sum 1.0000000 1.0000000 1.0000000 1.0000000 4.0000000
Lệnh trên cho thấy ở vùng Northeast có 15.35 % dân cư ở khu vực phi đô thị và 84.64% còn lại ở khu
vực thành thị.
Chúng ta cũng có thể khai khác thông tin từ nhiều các khác bằng các lệnh hữu ích sau:
addmargins(prop.table(trang, 1))
## region
## smsa northeast midwest south west Sum
## no 0.1369237 0.2871383 0.3441783 0.2317597 1.0000000
## yes 0.2604624 0.2287885 0.2997325 0.2110166 1.0000000
## Sum 0.3973862 0.5159268 0.6439108 0.4427763 2.0000000
addmargins(trang, 1)
## region
## smsa northeast midwest south west
## no 989 2074 2486 1674
## yes 5452 4789 6274 4417
## Sum 6441 6863 8760 6091
addmargins(trang, 2)
## region
## smsa northeast midwest south west Sum
## no 989 2074 2486 1674 7223
## yes 5452 4789 6274 4417 20932
Tương tự chúng ta có thể vẽ Pie Chart cho 2 nhóm ứng với làm thêm hay không với tỉ lệ % tương ứng
cho mỗi nhóm. Trước hết chúng ta tìm số người không làm thêm và làm thêm:
table(CPS1988$parttime)
## parttime
## no yes
## 25631 2524
Từ đây chúng ta xác định được cụ thể số người không làm thêm và làm thêm. Kế tiếp chúng ta thực
hiện các lệnh sau:
Nếu Pie Chart không cần biểu thị tỉ lệ % tương ứng thì chỉ cần gõ:
Trình bày các thông tin của dữ liệu bằng Pie Chart bị chỉ trích mạnh mẽ bởi giới phân tích số liệu và
thống kê. Theo Edward Tufte – một bậc thầy về hình ảnh hóa dữ liệu và cũng là một nhà thống kê ở
đại học Yale thì có ít nhất ba lí do không nên sử dụng Pie Chart: (1) kích thước tương đối của những
lát bánh là khó so sánh và diễn dịch, (2) chỉ cung cấp rất ít thông tin về dữ liệu nhưng lại chiếm rất
nhiều không gian trình bày, (3) có nhiều các thức hiệu quả hơn nhằm biểu diễn thông tin của dữ liệu,
chẳng hạn sử dụng biểu đồ hình cột.
library(foreign)
dung <- read.dta("D:/KTLR/Table13_1.dta")
plot(dung$ex, type = "l", col = "blue", xlab = "",
ylab = "Ti Gia", main = "Ti Gia Hoi Doai USD/EUR")
Chúng ta có thể hiệu chính hình ảnh này đẹp hơn bằng cách đặt nền màu xám đồng thời vẽ những
đường thẳng thẳng đứng với giả thiết rằng một năm có 340 phiên giao dịch nhằm tìm hiểu xu hướng
biến động của tỉ giá theo từng năm một với giả sử 1 năm có 360 ngày:
Từ đây chúng ta có thể thấy rõ hơn xu hướng biến động của tỉ giá theo từng khoảng thời gian nghiên
cứu.
Hiện tại hệ điều hành Window chưa hỗ trợ tiếng Việt cho R nên ở trên chúng ta gõ chữ không dấu.
Nếu máy tính của bạn là Mac hay sử dụng hệ điều hành Linux, Ubuntu thì có thể sử dụng tiếng Việt.
3.3.1.8 Trình bày nhiều Graphs trên cùng một cửa sổ hiển thị trong R
Trong nhiều tình huống có thể chúng ta cần trình bày nhiều Graphs trên cùng một cửa sổ hiển thị.
Chẳng hạn để trình bày boxplots và pie chart trên cùng một cửa sổ hiển thị:
Ở đây câu lệnh đầu tiên chi cửa sổ hiển thị của R thành 2 dòng và một cột. Các Graphs sẽ xuất hiện
theo thứ tự gõ các câu lệnh. Nếu thay mfrow = c(2, 1) bằng mfrow = c(2, 2) thì chúng ta có thể hiển
thị 2*2 = 4 Graphs trong cùng một cửa sổ lệnh. Sau khi thực hiện xong việc “ghép” 2 Graphs chúng ta
chỉ định cửa sổ đồ họa ở chế độ mặc định bằng cách gõ:
Về cơ bản, mỗi lệnh trong gói ggplot2 có ba thành phần chủ yếu sau:
Chúng ta nghiên cứu một số ví dụ ngay sau đây để làm sáng tỏ dần cấu trúc cú pháp của gói ggplot2.
library(ggplot2)
ggplot(hello, aes(x = EDUC, y = WAGE)) + geom_point()
Hiệu ứng hình ảnh này là tương đương với các câu lệnh sau:
Hoặc:
Qua một loạt các câu lệnh “khác nhau” nhưng lại tạo ra hiệu ứng hình ảnh như nhau các đã có thể cảm
nhận được cách sử dụng gói ggplot cũng như sử dụng toán tử pipe. Dưới đây là những lệnh phức tạp
tăng dần.
Hay “gộp” cả 2 Scatter Plot trên vào cùng một cửa sổ hiển thị:
Bổ sung thêm chỉ dẫn cho trục cũng như tiêu đề đồng thời đổi theme:
Có thể vẽ đường hồi quy có quãng đáng tin 95% với câu lệnh sau (không hiển thị hình ảnh):
Do số lượng điểm dữ liệu là rất nhiều nên các bạn chưa thấy sự khác biệt và ý nghĩa của câu lệnh trên.
Các bạn nên thử với những file dữ liệu kích mẫu thước bé. Chú ý rằng nếu các bạn thay đổi thứ tự của
geom_poin() và geom_smooth(method = ”lm”) thì hiệu ứng hình ảnh sẽ khác.
Chúng ta cũng có thể vẽ 2 đường hồi quy ứng với 2 nhóm lao động riêng biệt và hiển thị ở cùng một
cửa sổ:
Kĩ thuật vẽ đường hồi quy (hoặc các đường cong hồi quy) như vậy rất có ích trong việc nghiên cứu
các mô hình hồi quy có biến định tính (biến giả) như ta có thể thấy ở chương 7 sau này.
3.3.2.3 Vẽ Histogram
Vẽ Histogram cho biến IQ (chỉ số thông minh IQ) riêng biệt cho hai nhóm giới tính:
Cho toàn bộ các quan sát trong mẫu và không sử dụng màu sắc (không hiển thị hình ảnh):
Nếu muốn chúng ta có thể làm cho histogram này đẹp hơn theo một cách thức khác:
3.3.3.4 Boxplots
Box plot cho IQ theo hai nhóm giới tính:
Hình ảnh này nói một câu chuyện thú vị (và cũng gây tranh cãi) về trí thông minh của hai giới. Hầu
hết các lý thuyết đều cho rằng không có sự khác biệt nào về trí thông minh giữa các giới tính (thậm
chí là chủng tộc) nhưng box plot này cho thấy nam giới có IQ cao hơn nữ rất rõ. Tất nhiên, chúng ta
có thể thực hiện kiểm định t về sự khác biệt này cho chỉ số IQ của hai giới để có kết luận chính thức.
Hoặc có thể vẽ box plot cho IQ theo cả hai biến định tính là giới tính và chủng tộc:
Nếu chúng ta không cần trình bày màu sắc (không hiển thị hình ảnh):
Hoặc có thể đổi chiều cho các box plot và không sử dụng màu sắc:
Hoặc vẽ box plot cho tất cả các quan sát không phân biệt theo bất kì biến định tính nào:
library(AER)
data("CPS1988")
library(tidyverse)
#--------------------------------------
# Số lao động theo khu vực địa lí:
#--------------------------------------
# Kiểu 1:
k1 <- CPS1988 %>%
group_by(region) %>% count() %>%
ggplot(aes(region, n)) + geom_col() + theme_minimal()
k1
# Kiểu 2:
k2 <- CPS1988 %>%
group_by(region) %>% count() %>%
ggplot(aes(region, n, fill = region)) +
geom_col() + theme_minimal()
k2
# Cố định theme là theme_minimal chứ không phải là theme nền xám như thường t
hấy:
theme_set(theme_minimal())
# Kiểu 3:
k3 <- CPS1988 %>%
group_by(region) %>% count() %>%
ggplot(aes(reorder(region, n), n, fill = region)) +
geom_col(show.legend = FALSE)
k3
#-----------------------------------------------
# Số lao động theo khu vực địa lí và chủng tộc:
#-----------------------------------------------
# Kiểu 1:
k8 <- CPS1988 %>% group_by(region, ethnicity) %>% count() %>%
ggplot(aes(region, n)) + geom_col() +
facet_wrap(~ ethnicity, scales = "free") +
geom_text(aes(label = n), color = "white", vjust = 1.2, size = 3) +
labs(x = NULL, y = NULL,
title = "Observations by Region and Ethnicity",
caption = "Data Source: US Census Bureau")
k8
k12
# Kiểu 6:
k13 <- CPS1988 %>% group_by(region, ethnicity) %>% count() %>%
ggplot(aes(region, n, fill = ethnicity)) + geom_col(position = "dodge") +
labs(x = NULL, y = NULL,
title = "Observations by Region and Ethnicity",
caption = "Data Source: US Census Bureau")
k13
#----------------------------------------------
# Biểu diễn cách khác cho lao động theo khu
# vực địa lí bằng một số cách khác:
#----------------------------------------------
# Cách 2:
u <- CPS1988 %>%
group_by(region) %>%
count() %>%
ggplot(aes(x = "", n, fill = region)) +
geom_col(width = 1, position = "fill") +
coord_flip() + theme(legend.position = "top") +
scale_y_percent() +
labs(x = NULL, y = NULL,
title = "Percentage of Observations by Region",
caption = "Data Source: US Census Bureau")
u
Tất nhiên còn nhiều cách thức vẽ bar graph khác và các bạn nên tìm tòi thực hành thêm dựa trên R
codes đã có ở trên. Một cách khác rất tốt để nâng cao khả năng sử dụng ggplot2 cho Data Visualization
là thực hiện các dự án nhỏ (ví dụ: http://rpubs.com/chidungkt/285385 ).
Nếu sử dụng toán tử pipe (khuyến khích sử dụng) và tô màu cho từng đường cong thì chúng ta không
cần phải tạo ra object trung gian là con:
set.seed(29)
CPS1988 %>%
sample_n(200) %>%
ggplot(aes(experience, log(wage), color = region, fill = region)) +
geom_point(show.legend = FALSE) +
stat_smooth(method = "lm",
formula = y ~ x + I(x^2),
size = 1, show.legend = FALSE) +
facet_wrap(~region)
Hoặc trên cùng một cửa sổ hiển thị đồng thời không lấy khoảng tin cậy 95%:
set.seed(29)
con <- CPS1988 %>% sample_n(200)
con %>% ggplot(aes(experience, log(wage), colour = region)) +
geom_point(alpha = 0.3) +
stat_smooth(method = "lm", formula = y ~ x + I(x^2), se = FALSE) +
theme_bw()
Hoặc không phân biệt theo từng khu vực địa lý:
Các ví dụ trên cũng cho thấy rằng để có cùng một sản phẩm là graph (và tổng quát là các phân tích)
trong R có thể rất linh hoạt, nhiều cách thức khác nhau. Sức mạnh của R và đồng thời cũng là điểm
yếu của nó, theo như cách nói vui của Bob Rudis – một chuyên gia về phân tích dữ liệu là “..có 12 cách
làm cho một thứ công việc..”. Điều này có thể làm bạn rất khó nhớ và bạn muốn thành thạo R thì chỉ
còn cách là thực hành đủ nhiều để nắm được cái “hồn” của ngôn ngữ này.
Chúng ta có thể vẽ hàm mật độ xác suất ứng với 4 nhóm lao động theo một cách khác:
Chúng ta cũng thể vẽ hàm mật độ xác suất của log(wage) với toàn bộ quan sát bằng lệnh:
ggplot(CPS1988, aes(log(wage))) +
geom_density(color = "darkblue", fill = "lightblue")
Hoặc cho từng nhóm làm thêm hay không làm thêm:
Chú ý rằng bộ số liệu này thì biến time không phải mang ý nghĩa thời gian thực. Để vẽ đồ thị đường
với thời gian thực chúng ta trở lại với bộ số liệu các cổ phiếu ở mục 2.3.8:
# Chuyển biến X.DTYYYYMMDD. theo đúng bản chất thời gian và vẽ:
library(lubridate)
# Kiểu 1:
data %>% mutate(Date = ymd(X.DTYYYYMMDD.)) %>%
ggplot(aes(Date, X.Open.)) + geom_line(color = "blue") +
facet_wrap(~ X.Ticker., drop = TRUE, scales = "free") +
theme_bw()
# Kiểu 2:
data %>% mutate(Date = ymd(X.DTYYYYMMDD.)) %>%
ggplot(aes(Date, X.Open., color = X.Ticker.)) + geom_line() +
theme_bw()
# Kiểu 3:
data %>% mutate(Date = ymd(X.DTYYYYMMDD.)) %>%
rename(Price = X.Open., Symbol = X.Ticker.) %>%
ggplot(aes(Date, Price, color = Symbol)) + geom_line() +
theme_bw()
Ở trên chúng ta đã sử dụng hàm ymd() của gói lubridate để tạo biến thời gian có tên Date dựa trên
biến X.DTYYYYMMDD. (vốn có thứ tự là năm, tháng, ngày – tương ứng với ba chữ ymd của hàm
ymd()). Ngoài ra với cách vẽ 3 chúng ta cũng đổi tên một số biến số cho graph đẹp và dễ hiểu với
lệnh rename() của gói dplyr trước khi vẽ.
Có thể thấy hai loại biểu đồ này mang ý nghĩa thông tin như nhau nhưng biểu đồ bánh chiếm không
gian trình bày nhiều lại thiết kế phức tạp nên trừ khi không còn cách nào khác (như thông lệ ở Việt
Nam vẫn có xu hướng lạm dụng biêu đồ bánh) thì ta nên kể một câu chuyện về số liệu bằng biểu đồ
cột chứ không phải biểu đồ hình bánh. Lí do như đã được trình bày ở mục trước.
3.3.3.1 Trình bày nhiều Graphs trên cùng một cửa sổ hiển thị trong R với gói grid
Một câu hỏi là các bạn có thể trình bay nhiều Graphs trên cùng một cửa sổ hiển thị nếu sử dụng gói
ggplot2 hay không? Câu trả lời là được. Chúng ta có thể thực hiện điều này với sự trợ giúp của gói
gridExtra. Dưới đây là một ví dụ về hiển thị đồng thời hai graphs trên một cửa sổ hiển thị:
Tất nhiên tất cả các đồ thị - hình vẽ mà gói Basic Graphics có thể làm được thì ggplot2 cũng có thể làm
được (và với chất lượng tốt hơn) như các bạn đã thấy. Trên đây chúng ta mới chỉ nghiên cứu các chức
năng của ggplot2 kiểu “cưỡi ngựa xem hoa”. Bạn nào quan tâm đến gói này có thể đọc các sách chuyên
biệt về ggplot2. Một trong những cuốn cơ bản nhất là “ggplot2 Essentials” của Donato Teutonico.
3.3.3.2 Vẽ thêm Histogram cho đường hồi quy với gói ggExtra
Chúng ta có thể đồng thời vẽ cả đường hồi quy với khoảng tin cậy 95% với Histogram cho các biến số
trên cùng một đồ thị với sự trợ giúp của gói ggExtra (các bạn cài đặt gói này bằng cách gõ
install.packages(“ggExtra”) trong cửa sổ lệnh của R). Để minh họa, phần này tôi sử dụng lại bộ dữ
liệu dung ở mục 3.1. Các câu lệnh thực hiện là:
library(ggExtra)
aoe <- ggplot(dung, aes(INCOME, HEALTH)) + geom_point() +
geom_smooth(method = "lm")
ggMarginal(aoe, type = "histogram")
3.3.3.3 Vẽ thêm hàm mật độ xác suất cho đường hồi quy với gói gridExtra
Chúng ta có thể đồng thời vẽ cả đường hồi quy với quãng đáng tin 95% và hàm mật độ xác suất các
biến số trên cùng một cửa sổ hiển thị với sự trợ giúp của gói gridExtra (trước hết cài đặt gói này bằng
cách gõ install.packages(“gridExtra”). Đầu tiên chúng ta thực hiện các dòng lệnh sau:
Kế tiếp chúng ta cần tạo một khoảng trống (blank) như sau:
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.line = element_blank())
3.3.3.4 Vẽ thêm Boxplot cho đường hồi quy với gói gridExtra
Chúng ta có thể đồng thời vẽ cả đường hồi quy với quãng đáng tin 95% và boxplot các biến số trên
cùng cửa sổ hiển thị:
Đây là một đồ thị rất quen thuộc với bạn nào chơi AOE – một game rất phổ biến. Các bạn có thể thấy
vào giai đoạn 1995 – 2000 thị phần của R gần như bằng 0 nhưng đến năm 2011 thì nó đã vươn lên vị
trí thứ nhất trong số 6 phần mềm khảo sát.
3.3.3.6 Sử dụng gói plotly tạo ra các hình ảnh tương tác
Các hình ảnh tương tác (Interactive Graphs) là một công cụ hình ảnh hóa dữ liệu rất ấn tượng và mang
lại nhiều thông tin. Điều này đặc biệt có giá trị nếu chúng ta sử dụng chúng cho các buổi thuyết trình
hay hỗ trợ cho các phân tích sâu hơn. Dưới đây chúng ta sẽ nghiên cứu cách tạo ra hình ảnh tương tác
với gói plotly. Trước hết các bạn hãy cài đặt gói này bằng install.packages(“plotly”).
Để minh họa chúng ta xé bộ số liệu iris (bộ số liệu này luôn đi kèm với R khi ta cài đặt). Đây là bộ số
liệu về chiều dài đài hoa, chiều rộng đài hoa .. của 150 quan sát thuộc 3 giống hoa là sesota, vericolor
và viginica. Dưới đây là R code cho việc tạo ra hình ảnh tương tác đơn giản nhất trong đó chúng ta
biểu diễn biểu đồ rời rạc (Scater Plot) với biến Petal.Length ở trục X và Petal.Width ở trục Y tương
ứng với 3 giống hoa:
library(plotly)
data(iris)
plot_ly(iris, x = ~ Petal.Length, y = ~Petal.Width,
type="scatter", mode = "markers" , color = ~Species)
Hình ảnh mà chúng ta thu được nếu bạn di con chuột vào thì chúng ta sẽ thấy hiện ra các con số.
Những hình ảnh kiểu như thế này được gọi là hình ảnh tương tác:
Chúng ta cũng có thể công bố hình ảnh trên Internet bằng Rpub (khoanh vàng có chữ Puslish) hoặc
cửa sổ có hình histogram. Chẳng hạn chúng ta có thể công bố hình ảnh này với Rpub:
http://rpubs.com/chidungkt/228114
Chúng ta chú ý mối liên hệ thú vị sau giữa gói các hàm của gói ggplot và các hàm cùa gói plotly (không
hiển thị hình ảnh ở đây):
Có nghĩa là, để tạo ra một hiệu ứng hình ảnh tương tự, đầu tiên chúng ta tạo ra một object có tên m
(do hàm ggplot() tạo ra). Kế tiếp để tạo hiệu ứng hình ảnh tương tác thì áp dụng hàm ggplotly() cho
object tên trang này.
Tương tự, chúng ta có thể tạo các Boxplot cho 3 giống hoa này:
Dưới đây là lệnh phức tạp hơn để tạo ra một hình ảnh ấn tượng: minh họa mối liên hệ giữa GDP và
tuổi thọ băng biểu đồ bong bóng. Sử dụng bộ số liệu bong1.csv chúng ta có hình ảnh sau:
Dưới đây là R code để tạo ra hình ảnh ấn tượng (nhưng cũng nhiều thông tin) này:
mode = "markers",
sizes = c(min(data_2007$size),
max(data_2007$size)),
marker = list(symbol = "circle",
sizemode = "diameter",
line = list(width = 2, color = "#FFFFFF")),
text = ~paste("Country:",
country,
"<br>Life Expectancy:",
lifeExp, "<br>GDP:",
gdpPercap,
"<br>Pop.:",
pop)) %>%
layout(title = 'Life Expectancy v. Per Capita GDP, 2007',
xaxis = list(title = 'GDP per capita (2000 dollars)',
gridcolor = 'rgb(255, 255, 255)',
range = c(2.003297660701705, 5.191505530708712),
type = 'log',
zerolinewidth = 1,
ticklen = 5,
gridwidth = 2),
yaxis = list(title = 'Life Expectancy (years)',
gridcolor = 'rgb(255, 255, 255)',
range = c(36.12621671352166, 91.72921793264332),
zerolinewidth = 1,
ticklen = 5,
gridwith = 2),
paper_bgcolor = 'rgb(243, 243, 243)',
plot_bgcolor = 'rgb(243, 243, 243)')
p
Cuối cùng, sử dụng gói quantmod để thu thập dữ liệu tài chính của Apple và Microsoft chúng ta có
thể minh họa giá của hai cổ phiếu này theo: (1) thời gian, và (2) theo từng năm (1 yr) hay tất cả (all).
Trước hết bạn cài đặt gói quantmod (chi tiết hơn về sử dụng gói này các bạn có thể xem tại chương
15) và thực hiện những dòng mã sau:
step = "month",
stepmode = "backward"),
list(
count = 6,
label = "6 mo",
step = "month",
stepmode = "backward"),
list(
count = 1,
label = "1 yr",
step = "year",
stepmode = "backward"),
list(
count = 1,
label = "YTD",
step = "year",
stepmode = "todate"),
list(step = "all"))),
rangeslider = list(type = "date")),
yaxis = list(title = "Price"))
p
Đến đây chúng ta di chuột vào các đường để biết giá của các cổ phiếu. Chúng ta cũng có thể kích vào
cửa sổ có tên 6 mo hay all để tìm hiểu xu hướng giá trong những khoảng thời gian khác nhau.
3.3.3.7 Sử dụng gói googleVis tạo ra các hình ảnh tương tác
Ngoài sử dụng gói plotly chúng ta cũng có thể dùng gói googleVis để tạo ra các hình ảnh tương tác
theo một cách thức khác. Trước hết chúng ta tìm hiểu về bộ số liệu có tên ginivsgdp1.csv về tăng
trưởng (đo bằng gdp_ann) và mức độ bất bình đẳng về thu nhập tại Hoa Kì (đo bằng hệ số Gini) từ
thời cầm quyền của Johnson cho đến Obama. Chúng ta hãy đánh giá một cách hình ảnh mức độ bất
bình đẳng về thu nhập quan các thời kì cầm quyền:
Từ hình ảnh này chúng ta có thể thấy rằng thời kì cần quyền của G.Bush (Bush cha) thì mức độ bất
bình đẳng tăng cao nhất và đến thời của Clinton thì tốc độ bất bình đẳng giảm dần.
Giả sử mức độ bất bình đẳng và tăng trưởng có mối quan hệ tuyến tính và chúng ta thực hiện hồi quy
với biến độc lập là tăng trưởng, biến phụ thuộc là tăng trưởng (chúng ta sẽ nghiên cứu kĩ ở chương
4) đồng thời chúng ta muốn hiển thị cả các con số cũng như phương trình đường hồi quy. Để thực
hiện điều này trước hết bạn cần cài đặt gói googleVis. Dưới đây là các lệnh cho phép thực hiện điều
đó với điều kiện máy tính nối Internet:
library(googleVis)
trang <- data.frame(gdp = c(dung$gdp_ann), gini= c(dung$Gini))
trangyeu <- gvisScatterChart(trang, option= list(width = 650,
height = 600, legend = "none", title = "Moi quan he giua bat binh dang - tang
truong tai Hoa Ki",
hAxis = "{title :'GDP'}",
vAxis = "{title :'Gini'}",
dataOpacity = 0.8,
trendlines="{0:{type : 'linear', visibleInLegend: true,
showR2: true}}"))
plot(trangyeu)
Lúc này nếu bạn di chuột dọc theo đường thẳng bạn sẽ thấy phương trình hồi quy được hiện thị cũng
như tọa độ của các điểm trên đồ thị.
Với gói googleVis chúng ta cũng có thể vẽ được bản đồ nợ công của một số nước châu Âu tương tự
như một bài viết đăng trên New York Times. Các bạn có thế tham khảo bài viết cùng hình ảnh tại đây:
http://www.nytimes.com/interactive/2010/04/06/business/global/european-debt-map.html
Khi kích vào bản đồ của từng nước, các bạn sẽ thấy hiện ra các thông tin về nợ công của quốc gia được
chọn.
Chúng ta hoàn toàn có thể vẽ bản đồ nợ công tương tự như trên. Sử dụng bộ số liệu debt.csv về nợ
công của một số nước châu Âu:
numvar= "Debt_to_GDP_Ratio_2003",
hovervar="text",
options = list(width = "600px", height ="700px",
dataMode = "regions", region = '150',
colors= "[0xF8DFA7,
0x8D9569,
0xE9CC99,
0xE2AD5A,
0xCA7363]"))
plot(nghiyeu)
Sử dụng bộ số liệu có tên ghg.csv chúng ta có thể vẽ bản đồ hiển thị mức độ thải khí CO2 của 99 quốc
gia lớn nhất thế giới trong năm 2010:
width = 900,
height =500,
markerOpacity = 0.5,
sizeAxis = "{maxSize:'35'}",
colorAxis = "{colors:['green','red']}"))
plot(love)
Hình ảnh này cho thấy Trung Quốc là nước thải khí hiệu ứng nhà kính lớn nhất thế giới trong năm
2010. Tất nhiên chúng ta có thể lặp lại hình ảnh này với số liệu của năm khác.
Ngoài ra, chúng ta cũng có thể vẽ hình ảnh biểu diễn theo thời gian mức độ xả thải của một số quốc
gia từ năm 1990 cho đến năm 2030 (con số dự báo) :
dung <-read.csv("ghg1.csv")
love <- gvisLineChart(dung, xvar = "Year", yvar = c("Brazil", "China", "India
","Russia", "USA"), options = list( width = 500, height = 500,title = "Green
House Gas Emissions", vAxis="{title:'Million Metric tons of CO2'}",
hAxis="{title:'Year'}", gvis.editor ="Edit the Line Chart"))
plot(love)
Như vậy có thể thấy trong số những nước khảo sát, Nga là quốc gia duy nhất giảm lượng xả thải khí
gây hiệu ứng nhà kính.
3.4 Môt số nguyên tắc của hình ảnh hóa dữ liệu của Edward Tufte
Khi khai thác các thông tin hữu ích nhưng tiềm ẩn trong bộ số liệu bằng công cụ hình ảnh, chúng ta
không thể bỏ qua hai nguyên tắc cơ bản nhất của việc trình bày hình ảnh, đồ thị đã được giới thống
kê và phân tích số liêu thừa nhận của Edward Tufte – một bậc thầy về hình ảnh hóa dữ liệu đồng thời
là một giáo sư về thống kê, khoa học máy tính và chính trị học ở đại học Yale.
Nguyên tắc thứ nhất có thể được gọi là nguyên tắc tối giản theo đó việc hình ảnh hóa dữ liệu phải thỏa
mãn truyền tải tối đa các thông tin ẩn dấu trong bộ dữ liệu đồng thời các hình ảnh phải đơn giản nhất,
tiết kiệm mực in và không gian trình bày tối đa nhất có thể. Theo quan điểm này của Tufte thì biểu đồ
hình tròn (Pie Chart) không nên được sử dụng và có thể được thay thế bằng biểu đồ cột (Bar Chat).
Lí do là, chẳng hạn, để biểu diễn tỉ trọng % của nam và nữ trong một mẫu chẳng hạn, thì biểu đồ cột
hoàn toàn có thể thỏa mãn yêu cầu này đồng thời vẽ biểu đồ cột là rất đơn giản, linh hoạt và chiếm ít
không gian trình bày hơn so với biểu đồ hình bánh.
Nguyên tắc thứ hai là rõ ràng, không gây nhầm lẫn và hiểu lầm cho người đọc trong việc nắm bắt, diễn
giải các thông tin ẩn chứa trong bộ dữ liệu. Để minh họa, xét bộ số liệu giả thuyết về xuất khẩu của
Việt Nam trong bốn quý của năm 2020:
## Quy XuatKhau
## 1 Q1 7.00
## 2 Q2 7.10
## 3 Q3 7.15
## 4 Q4 6.95
Giả sử chúng ta sử dụng công cụ hình ảnh để mô tả xu hướng về xuất khẩu của Việt Nam lần lượt bằng
ba biểu đồ cột dưới đây:
Theo Tufte thì cả ba biểu đồ cột này đều vi phạm nguyên tắc thứ hai. Thực vậy, do các con số về xuất
khẩu là rất sát nhau nên người đọc có thể không phân biệt được, và do vậy không hề rút ra bất cứ
thông tin hữu ích nào về xu hướng xuất khẩu.
Riêng biểu đồ thứ nhất và thứ hai còn vi phạm thêm nguyên tắc thứ nhất: đó là sự tối giản trong trình
bày nhưng phải mang lại tối đa thông tin. Biểu đồ cột thứ nhất không cần thiếu phải sử dụng: (1) màu
sắc đại diện cho các quý, và (2) chú thích ở phía bên phải cho các quý. Vì rằng đã có 4 tên gọi từ Q1
đến Q4 đại diện cho các quý và như vậy, sử dụng thêm màu sắc là thừa.
Biểu đồ thứ 3 thỏa mãn nguyên tắc thứ nhất nhưng vi phạm rõ ràng nguyên tắc thứ hai vì nó không
thể hiện rõ xu hướng về xuất khẩu, hoặc rất khó để nhìn ra xu hướng ấy.
Trong tình huống này, biểu đồ đường sẽ thỏa mãn cả hai nguyên tắc của Tufte về hình ảnh hóa dữ liệu
như chúng ta có thể thấy:
Khi đọc đến những dòng này, có thể thấy một số graph trình bày trước đó đã vi phạm các nguyên tắc
của Tufte. Chẳng hạn việc sử dụng 4 màu sắc Box Plot ở mục 3.3.1.4 là thừa. Tuy nhiên tôi cần lưu ý
các bạn rằng những mục mục trước đó chỉ hướng vào minh họa và thực hành vẽ, tô màu chứ chưa
bám sát các nguyên tắc của Tufte. Bạn đọc quan tâm và muốn tìm hiểu sâu hơn có thể tham khảo một
trong số các sách của Tufte về hình ảnh hóa dữ liệu có tên “Visual Explanations: Images and
Quantities, Evidence and Narrative”.
pdf("chidung.pdf")
ggplot(CPS1988, aes(log(wage), fill = region)) + geom_density(alpha = 0.3)
dev.off()
Lúc này, tại folder có tên KTLR sẽ có một file PDF có tên chidung.pdf. Trong tình huống các bạn muốn
lưu Graph này ở dạng file JPG hoặc PNG thì câu lện đầu tiên trong ba câu lện ở trên được thay lần lượt
bằng png("chidung.png") hoặc jpeg("chidung.jpeg").
Cách thức vừa trình bày ở trên là cách thức tổng quát cho việc lưu các graph. Riêng với trường hợp
sử dụng gói ggplot2 chúng ta có thể sử dụng hàm ggsave() của gói này để lưu lại các hình ảnh theo
một cách thức khác như sau:
Hình ảnh là cách thức hiệu quả truyền tải những thông tin hữu ích của dữ liệu như John Tukey – một
cây đại thụ của khoa học thống kê đã phát biểu:
“The simple graph has brought more information to the data analyst’s mind than any other
device.”
Trong dự án thứ nhất là hình ảnh hóa dữ liệu về đầu tư ròng của nước ngoài từ năm 1987 đến 2015
của Việt Nam theo phong cách trình bày hình ảnh của tạp chí The Econimists (có thể tìm hiểu thêm
bằng cách gõ cụm từ “the economist graph” vào Google) với dữ liệu cung cấp bởi Ngân Hàng Thế Giới
WB.
Trước hết thu thập những dữ liệu này trực tiếp từ R với gói WDI:
library(WDI)
df <- WDI(country = c("VN"),
indicator=c("BX.KLT.DINV.CD.WD"),
start = 1987,
end = 2015,
extra = TRUE,
cache = NULL)
Ở đây, VN là kí hiệu của Việt Nam và BX.KLT.DINV.CD.WD là kí hiệu bộ dữ liệu về dòng vốn đầu tư ở
Việt Nam. Dữ liệu thu thập được gồm nhiều biến số nhưng chúng ta chỉ quan tâm đến FDI ròng và
thời gian cho nên chúng ta chỉ cần giữ lại hai biến số đó. Ngoài ra để dễ hiểu chúng ta có thể đổi tên
cho biến số đồng thời tạo ra một biến mới là FDI_b với ngụ ý đơn vị của FDI ròng là tỉ Dollar:
library(tidyverse)
df <- rename(df, Year = year, FDI = BX.KLT.DINV.CD.WD)
df <- select(df, Year, FDI)
df <- mutate(df, FDI_b = FDI / 1000000000)
Kế tiếp chúng ta sử dụng gói ggplot2 (không cần phải gọi gói này vì hệ sinh thái tidyverse khi được
gọi thì gói ggplot2 cũng được gọi cùng) để hình ảnh hóa dòng FDI ròng trong khoảng thời gian trên
với nền (themes) theo phong cách của tạp chí The Economists:
library(ggthemes)
ggplot(df, aes(x = Year, y = FDI_b)) +
geom_bar(stat="identity", position="identity",
show.legend = F, fill = c("#1874CD")) +
labs(x = NULL,
y = NULL,
title = "Vietnam's net FDI flows: 1987 - 2015",
subtitle = "Unit: Billion",
caption = "Source: The World Bank") +
theme_economist()
Nếu sử dụng toán tử pipe mà chúng ta đã biết thì tất cả các dòng lệnh (mỗi dòng lệnh đại diện cho
một công đoạn xử lí dữ liệu – data manipulation) dài dòng trên có thể thu gọn về chỉ còn một dòng
lệnh (không tính các dòng lệnh gọi các gói) như sau mà vẫn thu được kết quả cuối cùng:
library(WDI)
library(tidyverse)
library(ggthemes)
WDI(country = c("VN"),
indicator=c("BX.KLT.DINV.CD.WD"),
start = 1987,
end = 2015,
extra = TRUE,
cache = NULL) %>%
rename(Year = year, FDI = BX.KLT.DINV.CD.WD) %>%
select(Year, FDI) %>%
mutate(FDI_b = FDI / 1000000000) %>%
ggplot(aes(x = Year, y = FDI_b)) +
geom_bar(stat="identity",
position="identity",
show.legend = F,
fill = c("#1874CD")) +
labs(x = NULL,
y = NULL,
title = "Vietnam's net FDI flows: 1987 - 2015",
subtitle = "Unit: Billion",
Nếu có chỗ nào khó hiểu, các bạn có thể xem lại cách thức sử dụng toán tử pipe đã trình bày ở mục
2.6.
Dự án thứ hai chúng ta lấy dữ liệu trực tiếp từ Ủy Ban Người Tị Nạn của Liên Hợp Quốc (UNHCR) để
đưa ra các thông tin về: (1) 10 quốc gia có nhiều người tị nạn nhất từ năm 1951 đến năm 2014, và (2)
cơ cấu của người tị nạn trong khoảng thời gian trên. Ngoài ra, đây cũng là dự án mà lần đầu tiên
chúng ta tạo ra một đám mây từ (word cloud) – một công cụ hình ảnh hóa dữ liệu mà các tạp chí
thường làm.
Trước hết lấy dữ liệu trực tiếp từ Internet và thực hiện một số bước xử lí số liệu thô (nếu không có
Internet bạn có thể sử dụng bộ dữ liệu có tên unhcr_data.csv) :
for (k in 1:length(old.countries)){
ref.d$Country_Origin[ref.d$Country_Origin == old.countries[k]] <- new.count
ries[k]
ref.d$Country[ref.d$Country == old.countries[k]] <- new.countries[k]
}
# Tính toán số người rời bỏ quê hương mình theo quốc gia:
or.count.tot2 <- ref.d %>%
group_by(Country_Origin) %>%
summarise_each(funs(sum(., na.rm = TRUE)), Total)
# 10 quốc gia có nhiều người bỏ quê hương nhất (không hiển thị):
u <- or.count.tot2 %>% arrange(desc(Total)) %>% slice(1:10)
u
# Loại ra nhóm chưa xác định đến từ đâu (Unknown) và vẽ Bar Plot:
library(ggthemes)
u %>% filter(Country_Origin != "Unknown") %>%
mutate(Total = Total/1000) %>%
ggplot(aes(x = reorder(Country_Origin, Total), y = Total, fill = Country_Or
igin)) +
geom_bar(stat = "identity", show.legend = FALSE) +
coord_flip() +
labs(x = NULL,
y = NULL,
title = "9 Countries With the Most Refugees",
subtitle = "Unit: Thousand",
caption = "Data Source: http://popstats.unhcr.org") +
# Có thể lọc ra thông tin về người tị nạn Việt Nam để khai thác:
vn <- ref.d %>% filter(Country_Origin == "Viet Nam")
Thực hiện vẽ đám mây từ hiển thị tên của 100 quốc gia có nhiều người tị nạn nhất. Kích cỡ của từ
càng lớn thì có nghĩa là quốc gia đó càng có nhiều người tị nạn:
# ----------------
# Vẽ word cloud
#----------------
max.words = 100,
# Chọn phông chữ:
family = "Garamond",
font = 2,
random.order = F,
colors = brewer.pal(8, "Paired"))
#-----------------------------
# Hình ảnh hóa cơ cấu người
# tị nạn từ năm 1951
#-----------------------------
# Vẽ sơ bộ:
library(scales)
p1 <- ggplot(mydf, aes(Year, value)) +
geom_bar(aes(fill = variable), stat = "identity") +
labs(title = "Number of refugees from 1951 to 2014",
subtitle = "Unit: Millions",
caption = "Data Source: http://popstats.unhcr.org",
x = "",
y = "") +
theme_light() +
scale_fill_manual(labels = gsub("*_", " ", ten), values = mycol,
guide_legend(title = "Class"))
Dưới đây chúng ta sẽ thực hiện mini project thứ ba nhằm trả lời cho một câu hỏi là liệu hệ thống y
tế của Việt Nam có thực sự tệ đến mức mà bộ Y Tế (cũng như người đứng đầu bộ này) thường bị
chỉ trích gay gắt và có phần khắc nghiệt. Để trả lời câu hỏi này chung ta sẽ thu thập dữ liệu về tuổi thọ
bình quân, thu nhập đầu người tính theo tương đương sức mua, và quy mô dân số. Dưới đây là R
codes biểu diễn thu nhập bình quân trên trục X, tuổi thọ trên trục Y còn diện tích hình tròn biểu diễn
quy mô dân số của các quốc gia. Màu sắc thì biểu diễn nhóm thu nhập (có 4 nhóm thu nhập):
library(ggthemes)
mydf <- WDI(country = "all",
start = 2015,
end = 2016,
indicator = c("SP.POP.TOTL",
# Tuổi thọ bình quân:
"SP.DYN.LE00.IN",
# GDP đầu người:
"NY.GDP.PCAP.PP.CD"))
d <- WDIcache()
d2 <- data.frame(d[[2]])
# Chỉ lấy dữ liệu năm 2015:
nam2015 <- mydf %>% filter(year == 2015)
# Lấy thêm một cột biến về nhóm thu nhập cho các quốc gia:
chung <- intersect(d2$country, nam2015$country)
u <- d2 %>%
filter(country %in% chung) %>%
arrange(country) %>%
mutate(country = as.character(country))
# Không lấy các quốc gia không rõ nhóm thu nhập (loại Aggregates):
nam2015 <- nam2015 %>% filter(Group != "Aggregates")
title = "The relationship between Life Expectancy and GDP per capit
al",
caption = "Data Source: The World Bank")
p + theme_economist()
Có thể thấy rằng Việt Nam là quốc gia có tuổi thọ trung bình cao nhất trong nhóm nước có thu nhập
trung bình (màu xanh) và cao hơn nhiều nước thuộc nhóm có thu nhập trung bình cao (màu tím),
ngang hàng với nhiều nước có thu nhập cao (màu đỏ) . Vào năm 2015, tuổi tọ trung bình của người
Việt Nam là 76 - một con số chỉ thua chút đỉnh so với Hoa Kì là 79 – quốc gia giàu và có tỉ trọng chi
cho Y Tế tính theo GDP cao nhất thế giới. Các bạn có thể tham khảo thêm một số cách trình bày hình
ảnh với bộ số liệu này tại: http://rpubs.com/chidungkt/271482 .
Các bạn cũng có thể thực hành thêm để nâng cao hai kĩ năng về data manipulation và data
visualization tại http://rpubs.com/chidungkt/245032 với số liệu từ ủy ban Nobel. Những thông tin
đáng chú ý thu được từ bộ số liệu này (trong rất nhiều) là: (1) Paris không phải là thành phố sinh ra
nhiều nhà khoa học nhất như New York nhưng lại là thành phố mà nhiều nhà khoa học nhất muốn
chết ở đó, (2) Berkerley chính là trường đại học sinh ra nhiều nhà khoa học nhất chứ không phải
Harvard, và (3) giai đoạn trước 1945 – thời kì hoàng kim của khoa học Đức thì số giải Nobel của nước
này gần gấp đôi hai quốc gia xếp sau là Hoa Kì và Anh.
Mục tiêu của chương này là hướng dẫn các thực hành cho mô hình hồi quy hai biến số (còn gọi là hồi
quy đơn với ngụ ý rằng chỉ có một biến độc lập trong mô hình), kiểm định giả thuyết về các hệ số hồi
quy, ước lượng khoảng, ước lượng điểm, cũng như kiểm tra một số giả thuyết cơ bản về phần dư.
Trong chương này chúng ta sẽ thực hành với file dữ liệu có tên ch2_health.wf1 được cung cấp bởi khoa
Toán thuộc ĐH Kinh Tế Quốc Dân. File dữ liệu này gồm các thông tin về chi cho hệ thống chăm sóc y tế
(biến HEALTH), dân số (biến POP) và thu nhập từ các thuế và phí (biến INCOME) từ 50 bang và khu vực
hành chính Washington DC của Hoa Kì. Mục tiêu nghiên cứu là đánh giá xem chi cho hệ thống y tế có
liên hệ thế nào với nguồn thu nhập của các bang.
setwd("D:/KTLR")
library(hexView)
dung <- readEViews("ch2_health.wf1", as.data.frame = TRUE)
summary(dung)
library(tidyverse)
dung %>% summary()
Nếu chúng ta quan tâm đến ngũ phân vị của biến INCOME:
with(dung, quantile(dung$INCOME))
Điều này có nghĩa là có (25%)⨉51 = 13 bang có INCOME bé hơn 35800. Chú ý rằng giá trị ứng với
50% là 87300 chính là trung vị (Median) – giá trị mà chúng ta đã thấy ở phần trước.
Kết quả trên cũng có thể thu được theo một cách khác với toán tử pipe (không hiển thị kết quả):
Chú ý rằng khi đã sử dụng toán tử pipe thì dấu chấm (.) trong câu lệnh trên có nghĩa là chúng ta đang
“ám chỉ” đến data frame có tên dung.
Nếu chúng ta quan tâm đến các chi tiết thống kê chi tiết hơn cho bộ số liệu chúng ta có thể sử dụng
gói pastecs (xem lại chương 3):
options(scipen = 100)
options(digits = 8)
library(pastecs)
stat.desc(dung)
Chúng ta có thể, chẳng hạn, tìm ra quãng đáng tin 95% của HEALTH nằm trong khoảng từ 19929 –
6216 đến 19929 + 6216. Còn giá trị coef.var = 1.109 chính là thương số của std.dev chia cho mean.
Giá trị CI.mean.0.95 là quãng đáng tin 95% cho các biến số (CI là viết tắt của chữ Confidence Interval
– quãng đáng tin).
cor(dung)
Hệ số tương quan giữa POP và INCOME gần bằng 1 (lớn hơn 0.8) nên nếu cả hai biến này xuất hiện
với tư cách là biến độc lập trong phương trình hồi quy thì mô hình có thể mắc lỗi đa cộng tuyến ở
mức độ nghiên trọng. Chúng ta sẽ xem xét vấn đề này ở chương 7.
4.2 Thực hiện hồi quy và một số kiểm định thường gặp
Mục này chúng ta xem xét việc thực hiện hồi quy đơn cũng như thực hiện các kiểm định thường gặp
với R.
4.2.1 Hồi quy đơn, khoảng tin cậy cho các hệ số và bảng ANOVA
Chúng ta xét mô hình hồi quy hai biến số sau:
Với toán tử pipe thì toàn bộ kết quả này có thể được thực hiện ngắn gọn như sau:
Các bạn có thể nâng độ chính xác của các kết quả bằng cách như sau:
options(digits = 10)
summary(hoiquy)
## Call:
## lm(formula = HEALTH ~ INCOME, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10396.2691 -1272.7115 -361.2774 1087.9789 9019.4712
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1263.687112078 555.416723600 2.27521 0.027305 *
## INCOME 0.129483522 0.002513543 51.51434 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3006.205 on 49 degrees of freedom
## Multiple R-squared: 0.9818702, Adjusted R-squared: 0.9815002
## F-statistic: 2653.727 on 1 and 49 DF, p-value: < 2.2204e-16
Lúc này, thống kê F được lấy tới 3 chữ số sau dấu phẩy. Rõ ràng, nếu căn cứ theo các tiêu chuẩn truyền
thống thì mô hình hồi quy của chúng ta là tốt thể hiện ở: (1) tất cả các hệ số hồi quy có ý nghĩa thống
kê ở mức 5%, (2) R2 rất cao, và (3) thống kê F có giá trị lớn.
Chúng ta cũng có thể biểu diễn đường hồi quy (Regression Line) với khoảng tin cậy 95%:
library(ggplot2)
ggplot(dung, aes(INCOME, HEALTH)) + geom_point() + geom_smooth(method = "lm")
Có thể vẽ đường hồi quy theo một cách khác (vừa xấu hơn và gõ cũng dài dòng):
Sau khi thực hiện hồi quy chúng ta có thể sử dụng một số hàm để khai thác thêm một số thông tin liên
quan đến mô hình. Dưới đây là một số hàm cơ bản:
print() Hiển thị kết quả hồi quy ở dạng đơn giản
summary() Hiển thị kết quả hồi quy ở dạng chi tiết
predict() Dự đoán
confint() Hiển thị khoảng tin cậy (mặc định 95%) cho các hệ số hồi quy
df.residual() Hiển thị giá trị n – k (bậc tự do của mô hình hồi quy)
plot() Hiển thị 4 Graphs tiêu chuẩn dùng để tìm các quan sát bất thường
Bên cạnh đó, nhằm hỗ trợ cho việc chẩn đoán các lỗi của mô hình (hiện tượng đa cộng tuyến, phương
sai sai số thay đổi, các quan sát bất thường) – một vấn đề mà chúng ta sẽ nghiên cứu kĩ hơn trong các
phần sau của tài liệu này. Sau khi thực hiện hồi quy chúng ta có thể sử sụng một số hàm mà gói car
cung cấp dưới đây:
outlierTest() Tính giá trị Bonferoni p-Value cho quan sát bất thường
crPlots() Đồ thị phần dư chẩn đoán hiện tượng phi cộng tuyến
ceresPlots() Đồ thị phần dư chẩn đoán hiện tượng phi cộng tuyến
durbinWatsonTest() Kiểm định Durbin – Watson cho hiện tượng tự tương quan
Phần trên chúng ta đã quen thuộc với hàm summary(). Chẳng hạn để tính khoảng tin cậy 95% cho
các hệ số hồi quy:
confint(hoiquy)
## 2.5 % 97.5 %
## (Intercept) 147.5354180444 2379.8388061115
## INCOME 0.1244323678 0.1345346762
## 5 % 95 %
## (Intercept) 332.5027083524 2194.8715158035
## INCOME 0.1252694389 0.1336976051
Vấn đề tính khoảng tin cậy cho một hệ thức của hai biến số , chẳng hạn cho mβ1+nβ2 chúng ta sẽ
nghiên cứu chi tiết ở chương 5.
Một trong những thông tin quan trọng khi thực hiện hồi quy là phân tích bảng ANOVA:
anova(hoiquy)
Ở đây RSS (với df2 = 51 – 2 = 49 bậc tự do) là 442826151 và ESS (với df1 = 1 bậc tự do) là
23982446067. Với chú ý rằng TSS = RSS + ESS chúng ta có thể kiểm tra lại là R2 =ESS/TSS = 0.982.
Bảng ANOVA này cũng hiển thị giá trị thống kê F là 2653.727 = (ESS/df1)/(RSS/df2) =
(23982446067/1)/( 442826151/49). Kết quả này chính là giá trị F được hiển thị ở kết quả phân tích
hồi quy.
Trong tình huống chúng ta muốn thực hiện ước lượng cho mô hình:
HEALTH = β1 + β2INCOME.22+ u
Do mỗi một phần mềm đều có một quy cách thực hiện nên trong R bạn phải gõ:
Chúng ta phải lưu tâm điều này: những phép đổi biến đơn giản thì phép đổi biến ấy nên đặt trong I()
như trên.
Một tình huống khác mà chúng ta có thể gặp là thực hiện hồi quy không có hệ số chặn (Regression
through the Origin). Đó là các mô hình hồi quy dạng:
HEALTH = β⨉INCOME + u
Thực hiện hồi quy không có hê số chặn cho mô hình trên trong R là:
Chú ý rằng trong hồi quy không có hệ số chặn thì chỉ tiêu R2 được tính theo công thức truyền thống là
không áp dụng được và không có ý nghĩa trong việc đánh giá độ phù hợp của mô hình. Chúng ta sẽ
nghiên cứu kĩ hồi quy không có hệ số chặn trong chương sau.
4.2.2 Tìm các quan sát bất thường và chẩn đoán lỗi mô hình bằng hình ảnh
Chúng ta cũng có thể tìm ra các quan sát bất thường (outliers) – một vấn đề sẽ được nói kĩ hơn trong
chương 7. R cung cấp cùng một lúc 4 Graphs tiêu chuẩn phục vụ cho việc tìm ra các quan sát bất
thường chỉ bằng 2 dòng lệnh:
library("ggfortify")
autoplot(hoiquy, which = 1:4, ncol = 2, label.size = 3)
Sự xuất hiện của các quan sát bất thường trong mô hình hồi quy sẽ có tác động rất mạnh lên các kết
quả thu được. Xử lý các quan sát bất thường sẽ được nghiên cứu kĩ hơn trong chương 10.
Cũng có thể có được hình vẽ và các thông tin tương tự theo một cách khác (không hiển thị graph):
4.2.3 Thực hiện một số kiểm định thường gặp cho mô hình hồi quy
Dưới đây trình bày một số kiểm định thường gặp cho mô hình hồi quy. Các kiểm định này có thể phân
thành hai nhóm. Nhóm thứ nhất là các kiểm định nhằm đánh giá môt số giả thuyết của mô hình hồi
quy tuyến tính cổ điển, chẳng hạn, kiểm định tính phân phối chuẩn của phần dư. Nhóm thứ hai là các
kiểm định liên quan đến hệ số hồi quy của mô hình.
𝑆 2 (𝐾 − 3)2
JB = 𝑛 [ + ]
6 24
Thống kê JB này tuân theo phân phối khi bình phương (χ2) với hai bậc tự do. Nếu giá trị JB tính toán
ứng với p-value lớn hơn 5% thì chúng ta chưa thể bắc bỏ giả thiết rằng phân phối là chuẩn. Ngược lại,
ta chấp nhận giả thuyết phân phối là không chuẩn. Phân tích hình ảnh có thể chỉ cho ta thấy rằng phần
dư có thể là phân phối chuẩn hay không:
## 1 2 3 4 5 6
## 2361.8948 -1178.8553 -1113.3251 246.0478 -10396.2691 -3003.2262
Hoặc có thể thể hiện bằng line graph như phần mềm Eviews thường thực hiện:
Những hình ảnh trên không chỉ ra dấu hiệu chắc chắn nào cho thấy phần dư là phân phối chuẩn.
Chúng ta có thể sử dụng kiểm định Jarque – Bera để đưa ra bằng chứng thống kê về phân phối chuẩn:
##
## Title:
## Jarque - Bera Normalality Test
##
## Test Results:
## STATISTIC:
## X-squared: 24.9701
## P VALUE:
## Asymptotic p Value: 3.783e-06
##
Giá trị của Asymptotic p Value = 3.783*10-6 > 5% nên chúng ta có bằng chứng thống kê để chấp nhận
giả thuyết gốc rằng phần dư phân phối chuẩn.
Vì các thông tin về phần dư là rất quan trọng trong việc chẩn đoán các lỗi của mô hình hồi quy – một
vấn đề mà chúng ta sẽ nghiên cứu chi tiết từ chương 7 nên chúng ta nên lưu các giá trị phần dư này
để sử dụng và gán nó vào data frame tên dung như ở trên.
Chú ý rằng gói fBasics cung cấp nhiều kiểm định phân phối chuẩn khác nhau chứ không riêng gì
Jarque-Bera Test . Để biết chi tiết gói này cung cấp những kiểm định phân phối chuẩn gì các bạn gõ
?fBasics trong cửa sổ lệnh của R thì các bạn có thể thấy gói này cung cấp một số kiểm định phân
phối chuẩn như sau:
Các bạn có thể truy vấn trực tiếp về kiểm định Kolmogorov – Smirnov về tính phân phối chuẩn chẳng
hạn bằng cách gõ ?ksnormTest trong cửa sổ lệnh.
Chúng ta cũng có thể đánh giá chi tiết hơn về phần dư thu được:
## X..dung.phandu
## nobs 5.100000e+01
## NAs 0.000000e+00
## Minimum -1.039627e+04
## Maximum 9.019471e+03
## 1. Quartile -1.272711e+03
## 3. Quartile 1.087979e+03
## Mean 0.000000e+00
## Median -3.612774e+02
## Sum 0.000000e+00
## SE Mean 4.167221e+02
## LCL Mean -8.370110e+02
## UCL Mean 8.370110e+02
## Variance 8.856523e+06
## Stdev 2.975991e+03
## Skewness 1.184680e-01
## Kurtosis 3.169952e+00
Chúng ta thấy rằng phần dư có Mean = 0, Skewness = 0.118 (độ méo), và Kurtosis = 3.169. Những
thông tin này ngụ ý rằng phần dư có thể không phân phối chuẩn. Và kiểm định Jarque-Bera mà chúng
ta thực hiện ở trên đã đưa ra bằng chứng thống kê cho nhận định trên.
Nếu cần thiết, trong R cũng có thể thực hiện kiểm định này với gói lmtest bằng hàm dwtest():
library(lmtest)
hoiquy %>% dwtest()
##
## Durbin-Watson test
##
## data: .
## DW = 1.6995, p-value = 0.1432
## alternative hypothesis: true autocorrelation is greater than 0
Căn cứ vào giá trị p-value = 0.143 > 5% chúng ta có thể chấp nhận giả thuyết gốc rằng không tồn tại
tự tương quan trong mô hình.
Cũng cần phải lưu ý rằng kiểm định Durbin – Watson có khả năng áp dụng rất hạn chế vì kiểm định
này chỉ áp dụng cho tương quan bậc 1 và mô hình không có biến nội sinh. Chúng ta sẽ nghiên cứu kĩ
hơn kiểm định này trong những chương về tự tương quan và phân tích dữ liệu thời gian (Time Series
Analysis).
4.2.3.3 Kiểm định Wald về một giá trị cụ thể của một hệ số hồi quy
Giả sử chúng ta tin rằng số hồi quy β2 = 0.15. Chúng ta có thể kiểm định giả thuyết này với gói AER
như sau:
library(AER)
hoiquy <- lm(data = dung, HEALTH ~ INCOME)# Chạy lại mô hình hồi quy
linearHypothesis(hoiquy, "INCOME = 0.15")
Cột giá trị Pr(>F) = 10.79⨉10-11 là rất bé nên ta bác bỏ giả thiết β2 = 0.15. bạn có thể thực hiện kiểm
định này bằng gõ linear.hypothesis(hoiquy,"INCOME=0.15"). Tất nhiên kết quả là không thay đổi.
4.2.3.4 Kiểm định Wald đồng thời cho nhiều hệ số hồi quy
Nếu chúng ta tin rằng β1 = 1300 và β2 = 0.15 chúng ta có thể thực hiện kiểm định Wald như sau:
Cột giá trị Pr(>F) = 0.94 > 5% nên chúng ta có bằng chứng thống kê cho rằng β1 = 1300 và β2 = 0.15.
Ở đây các bạn cần chú ý rằng mặc dù chúng ta bắc bỏ giả thuyết β2 = 0.15 (mục 4.5) nhưng chúng ta
lại chấp nhận giả thuyết rằng β1 = 1300 và β2 = 0.15.
Kiểm định Wald về sự ràng buộc của các hệ số hồi quy áp dụng cho cặp giả thuyết H0: mβ2 + nβ3 = p;
H1: mβ2 + nβ3 # p. Kiểm định này áp dụng cho hồi quy bội và ta sẽ xét trong chương 5.
4.3 Mô phỏng Monte Carlo kiểm tra các giả thuyết CLMR
Chúng ta biết rằng nếu các điều kiện của mô hình hồi quy tuyến tính cổ điển (CLMR) được thỏa mãn
thì các ước lượng OLS thu được sẽ có tính chấtt BLUE. Nhưng trong thực tế bằng cách nào để chúng
ta có thể biết các ước lượng thu được, chẳng hạn, là không chệch. Chúng ta trở lại với mô hình được
xét ở mục 4.2:
Nhắc lại rằng các ước lượng OLS thu được từ sẽ là không chệch (unbiased – chữ U trong từ BLUE)
nếu:
E(β̂ 1) = β1 và E(β̂ 2) = β2
Ở đây β1 và β2 là các tham số thực nhưng chúng ta không-bao-giờ-biết những tham số thực này. Vậy
bằng cách nào chúng ta có thể đánh giá liệu rằng các ước lượng trên là không chệch hay không? Chúng
ta có thể trả lời câu hỏi này bằng thực hiện mô phỏng Monte Carlo. Quá trình này thực hiện mô phỏng
này thực hiện qua các bước sau:
Dưới đây là mô phỏng Monte Carlo (không copy các dòng lệnh này) với vòng lặp 500 lần:
plot(Beta1, main = mean(Beta1), type = "b", xlab = "So vong lap", col = "blue
")
plot(Beta2, main = mean(Beta2), type = "b", xlab = "So vong lap", col = "red"
)
hist(Beta1, col = "blue", main = "Histogram cua Beta1")
hist(Beta2, col = "red", main = "Histogram cua Beta2")
Để R trở lại chế độ hiển thị hình ảnh bình thường chúng ta gõ:
Kết quả này cho thấy E(β̂ 1) = 1299.99165 = β1 = 1300 và E(β̂ 2) = 0.14000 = β2 =0.14 do vậy cho thấy
rằng các ước lượng OLS thu được là không chệch. Có thể thấy điều này một lần nữa:
## Beta1 Beta2
## 1 1300.047 0.1400004
## 2 1299.958 0.1400006
## 3 1299.862 0.1400006
## 4 1300.215 0.1400000
## 5 1299.779 0.1400022
## 6 1300.240 0.1399989
summary(mydf)
## Beta1 Beta2
## Min. :1299 Min. :0.14
## 1st Qu.:1300 1st Qu.:0.14
## Median :1300 Median :0.14
## Mean :1300 Mean :0.14
## 3rd Qu.:1300 3rd Qu.:0.14
## Max. :1301 Max. :0.14
Cũng có thể thực hiện kiểm định giả thiết rằng các hệ số hồi quy thu được phân phối chuẩn hay không
với kiểm định Jarque - Bera Normalality Test sử dụng gói fBasics:
jarqueberaTest(mydf$Beta2)
## Title:
## Jarque - Bera Normalality Test
##
## Test Results:
## STATISTIC:
## X-squared: 1.4243
## P VALUE:
## Asymptotic p Value: 0.4906
Các giá trị P-value đều lớn hơn 5% nên chúng ta có bằng chứng thống kê cho thấy phân phối của các
hệ số beta là chuẩn.
Trên đây chỉ mới trình bày mô phỏng Monte Carlo ở dạng đơn giản nhất. Tất nhiên còn nhiều khía
cạnh phức tạp hơn nhưng những vấn đề đó có phạm vi kiến thức nằm ngoài chương trình tiêu chuẩn
dành cho bạn đọc không chuyên kinh tế lượng và thống kê. Bạn đọc quan tâm có thể tìm hiểu sâu hơn
ở các tài liệu về mô phỏng ngẫu nhiên.
HEALTH = β1 + β2INCOME. + ui
Để thuận tiện và ngắn gọn khi đánh máy, đặt HEALT = Y và INCOME = X ta có:
Y = β1 + β2X + ui
Trong đó X0 là một giá trị cụ thể nao đo. Vì Ŷ 0 là một ước lượng nên nó có thể khác giá trị thực và tuân
theo một phân phối nào đó. Khoa học thống kê đã chỉ ra rằng Ŷ 0 tuân theo phân phối chuẩn với phương
sai như sau:
1 (𝑋0 − 𝑋̅)2
var(𝑌̂0 ) = 𝜎 2 [ + ] (𝑎)
𝑛 ∑ 𝑥𝑖2
Hay:
Nhưng do σ2 là không biết nên chúng ta phải thay thế nó bằng σ̂ 2 là ước lượng của σ2 và do vậy chúng
ta thấy rằng biến:
𝑌̂0 − (𝛽1 + 𝛽2 𝑋0 )
𝑡= (𝑐)
𝑠𝑒(𝑌̂0 )
Tuân theo phân phối student t với n – 2 bậc tự do và khoảng tin cậy α là:
Chú ý rằng ước lượng σ̂ 2 của σ2 ở công thức (2) được tính theo công thức sau:
2 ∑ û 𝑖 2
σ̂ = (𝑒)
𝑛−2
Với đó X0 = 20000 (chẳng hạn thu nhập của bang California) thì chi cho ý tế Ŷ 0 là:
1263.6871121 + 0.1294835*20000
## [1] 3853.357553
Con số 3853.687này gây ra nhiều nhầm lẫn trong diễn giải ý nghĩa của nó. Thực vậy, nhiều bạn hiểu
một cách sai trái rằng khi income của Carlifornia bằng 20000 thì chi cho y tế của bang này là 3853.687.
Nguyên nhân là chi cho y tế của bang California là một biến ngẫu nhiên và ta không biết chính xác
biến ngẫu nhiên này là bao nhiêu mà chỉ biết nó nằm trong một khoảng giá trị nào đó mà thôi. Giá trị
3853.687 ở trên được gọi là ước lượng điểm (Point Prediction, tên gọi khác là ước lượng trung
bình – Mean Prediction). Sử dụng các công thức từ (a) đến (e) chúng ta có thể tính ước lượng khoảng
tin cậy 95% cho ước lượng của Ŷ 0 khi X0 = 20000. Tuy nhiên tính toán thủ công như vậy rất lâu. R cho
phép ta tính con số ước lượng điểm 3853.687 cùng với khoảng tin cậy 95% một cách nhanh chóng
chỉ với một dòng lệnh:
Ở đây giá trị fit chính là giá trị ước lượng điểm mà ta đã tính ở trên còn lwr và upr lần lượt là các cận
dưới và cận trên của ước lượng điểm theo công thức (d). Chú ý rằng hai câu lệnh trên có thể viết
thành một câu lệnh duy nhất như sau:
Nếu muốn thực hiện ước lượng khoảng tin cậy 99% thì:
Tương tự chúng ta có thể tính các ước lượng điểm cùng với khoảng tin cậy 95% cho 51 quan sát (lấy
kết quả cho 5 quan sát đầu tiên) như sau:
Chúng ta cũng có thể ước lượng HEALTH khi INCOME lần lượt là 20000,21000, và 22000 cùng một
lúc như sau:
Nếu bạn muốn dự báo một chuỗi các ước lượng ứng với mức thu nhập từ 12000 cho đến 100000
nhưng các mức thu nhập cách nhau 1000. Tức là quan sát đầu tiên ứng với INCOME = 12000, quan
sát thứ hai ứng với INCOME = 13000 cho đến quan sát cuối cùng ứng với INCOME = 100000 thì chúng
ta làm như sau (lấy 10 kết quả đầu tiên) :
Tuy nhiên nếu chúng ta quan tâm đến các ước lượng cá nhân (Individual Prediction) của Y0 (Y0 chứ
không phải la Ŷ 0 ) tương ứng với X0 thì giá trị ước lượng Y0 có phương sai tính theo công thức sau:
2 1 (𝑋0 − 𝑋̅)2
var(𝑌0 − 𝑌̂0 ) = 𝐸[𝑌0 − 𝑌̂0 ] = 𝜎 2 [1 + + ] (𝑓)
𝑛 ∑ 𝑥𝑖2
Thay thế σ2 bằng σ̂ 2 thì có thể thấy rằng:
𝑌0 − 𝑌̂0
𝑡= (𝑔)
𝑠𝑒(𝑌0 − 𝑌̂0 )
Tuân theo phân phối t, có thể ước lượng khoảng tin cậy ở ngưỡng α (mặc định là 5%) cho Y0 khi X0 =
20000 một cách nhanh chóng với lựa chọn interval="prediction":
Giá trị fit (ước lượng) thì không thay đổi và vẫn là 3853.357553 nhưng có thể thấy khoảng tin cậy trở
nên rộng hơn.
4.5 Một số tiêu chí thường sử dụng để đánh giá chất lượng mô hình
Khi thực hiện các phân tích cũng như nghiên cứu, chúng ta có thể phải đưa ra quyết định lựa chọn mô
hình nào là phù hợp. Hoặc chúng ta cũng cần phải đánh giá phẩm chất, độ phù hợp của mô hình chẳng
hạn. Để làm điều này, trước hết chúng ta phải quyết định cần phải sử dụng những tiêu chí gì để đánh
giá một mô hình là tốt hơn những mô hình khác cũng như chất lượng của một mô hình cụ thể. Ví dụ,
để lựa chọn một mô hình trong số các mô hình cạnh tranh nhau chúng ta phải dựa vào một loạt các
yếu tố cũng như tiêu chí khác nhau. Trong mục này, chúng ta xem xét một số tiêu chí thống kê thường
sử dụng để đánh giá và so sánh các mô hình.
Với hồi quy đơn (là mô hình chỉ có 1 biến độc lập) như ở mô hình a thì R2 = [cor(Y,X)]2 hay là bình
phương tương quan giữa X và Y. Với hồi quy đa biến (mô hình có nhiều hơn 1 biến độc lập) thì R2 =
[cor(Y,Ŷ )]2 trong đo ,Ŷ la gia trị dự báo của của Y thu được từ mô hình.
Trong tình huống mà hai mô hình không có biến phụ thuộc như nhau như mô hình a và mô hình b thì
để đánh giá và so sánh chúng ta có thể so sanh cor(Y,Ŷ a) va cor(Y,Ŷ b) với Ŷ a va Ŷ b lần lượt là các giá trị
ước lượng thu được của Y từ mô hình a và b. Giá trị tương quan mà càng cao thì có nghĩa là ước lượng
của Y thu được càng gần với giá trị thực của nó, và do đó mô hình nào có giá trị tương quan này cao
hơn thì sẽ là mô hình tốt hơn.
Còn RMSE được tính bằng căn bậc hai của MSE.
Một giá trị MSE (hoặc RMSE) càng bé thì có nghĩa là những giá trị ước lượng của Y sẽ càng sát với giá
trị thực và do đó, một mô hình có MSE (RMSE) bé hơn sẽ là một mô hình tốt hơn.
Ngoài ra một số tiêu chí thuộc nhóm này là MD, MAD, MPE và MAPE cũng có thể được sử dụng để
đánh giá mô hình.
4.5.3 Các tiêu chuẩn thông tin AIC, SIC, và Cp của Mallow
Đây là nhóm tiêu chí thường được sử dụng thay thế cho R2 trong nhiều tình huống và nó hạn chế được
các nhược điểm của tiêu chí R2.
Với các kí hiệu các bạn đã quen thuộc, tiêu chuẩn thông tin Akaike (AIC) được tình theo công thức:
∑ 𝑢̂𝑖2 RSS
AIC = 𝑒 2𝑘/𝑛 = 𝑒 2𝑘/𝑛
𝑛 n
Với chú ý rằng n là số quan sát, k là số biến số trong mô hình. Căn cứ vào tiêu chuẩn thông tin Akaike
AIC, mô hình có AIC thấp hơn sẽ được lựa chọn. Hầu hết các phần mềm thống kê, kể cả R đều báo cáo
tiêu chuẩn thông tin này. Với mô hình 1 như ở mục 4.2 để có tiêu chuẩn thông tin Akaike các bạn sử
dụng câu lệnh:
AIC(hoiquy)
Tương tự, tiêu chuẩn thông tin Schwarz (SIC) cũng được sử dụng để so sánh và đánh giá các mô hình
cạnh tranh. SIC được tính theo công thức sau:
∑ 𝑢̂2 RSS
SIC = 𝑛𝑘/𝑛 = 𝑛𝑘/𝑛
𝑛 n
Hiện tại, trong R chưa có sẵn hàm tính SIC nhưng các bạn có thể trực tiếp SIC trong R theo công thức
này.
Một tiêu chuẩn nữa là hệ số Cp của Mallow (Mallow’s Cp Criterion) được tính theo công thức:
RSS𝑝
𝐶𝑝 = − (𝑛 − 2𝑝)
𝜎̂ 2
Trong đó p là số biến độc lập (chú ý với mô hình k biến thì p = k – 1). Chúng ta cũng biết rằng E(σ̂ 2) là
ước lượng không chệch của phương sai sai số ngẫu nhiên σ2 – đại lượng mà chúng ta không bao giờ
biết chính xác. Do vậy, chúng ta có thể xấp xỉ E(Cp) như sau:
(𝑛 − 𝑝)𝜎 2
𝐸(𝐶𝑝 ) ≈ − (𝑛 − 2𝑝) ≈ 𝑝
𝜎2
Căn cứ theo tiêu chí Cp này, chúng ta sẽ ưu tiên lựa chọn mô hình có Cp thấp hơn và có hệ số R2 hoặc
R2 hiệu chỉnh càng cao càng tốt. Thường thì hai mục tiêu này mâu thuẫn với nhau và việc lựa chọn mô
hình cũng còn nên căn cứ vào, chẳng hạn, mối quan hệ của các biến số trong thực tế. Chúng ta sẽ
nghiên cứu kĩ hơn với tiêu chuẩn này ở mục 7.3 thuộc chương 7.
4.5.4 Tỉ lệ sai sót huấn luyện, sai sót kiểm định và hiện tượng quá khớp
Những gì các bạn sắp đọc chắc chắn là một thử thách. Không phải vì những gì được trình bày ở đây là
quá khó so với tư duy của các bạn mà vì một lí do khác rất đặc trưng của hầu hết chúng ta: chưa quen
với suy nghĩ một cách thống kê (Thinking Statistically) – điều mà hầu hết các giáo trình thống kê cũng
như kinh tế lượng bằng tiếng Việt không đề cập.
Thông thường việc so sánh chất lượng giữa hai mô hình hình cạnh tranh nhau hoặc đánh giá chất
lượng của một mô hình chúng ta thường dựa vào, chẳng hạn, tiêu chí R2 hoặc MSE. Nếu chọn MSE để
đánh giá thì mô hình nào có MSE bé hơn sẽ là mô hình tốt hơn. Trong tình huống đặc biệt, nếu MSE =
0 (tương đương với R2 =1) thì có nghĩa là chúng ta có một mô hình hoàn hảo với ngụ ý rằng các biến
số giải thích 100% biến động của biến phụ thuộc. Tương tự, khi đánh giá một mô hình chúng ta
thường căn cứ vào R2 – chỉ số này càng cao càng tốt. Hoặc chúng ta ta căn cứ vào MSE – chỉ số này
càng thấp càng tốt. Phải chăng, chẳng hạn, chỉ căn cứ vào MSE để đánh giá (hay so sánh) chất lượng
của các mô hình là đủ?
Câu trả lời là không. Để đánh giá chất lượng của một mô hình, theo James et al. (2013), chúng ta cần
căn cứ vào đồng thời cả hai tiêu chí: (1) sai số huấn luyện – training test error, và (2) sai số kiểm
định – testing test error. Để làm rõ hai khái niệm này chúng ta trở lại với bộ số liệu ở mục CPS1988
đã sử dụng ở chương 3 nhằm ước lượng mô hình sau:
Tuy nhiên thay vì ước lượng mô hình 2 với tất cả 28155 quan sát chúng ta chỉ ước lượng mô hình này
với 16.000 quan sát mà thôi. Rõ ràng là có đến K= 28155!/[16000!⨉(28155-16000)!] cách lấy ra
16000 quan sát từ 28155 quan sát và do vậy chúng ta cũng có chừng đó cặp giá trị ước lượng của β1
và β2 cũng như MSE. Dưới đây là 2 bộ số liệu rút ra từ K bộ số liệu có 16000 quan sát và do vậy có 2
bộ ước lượng β1 và β2 cũng như MSE:
## [1] 28155 7
head(CPS1988)
set.seed(2611)
p <- 16000 / 28155
id1 <- sample(nrow(CPS1988), round(p*nrow(CPS1988)))
data1 <- CPS1988[id1, ] # Lấy bộ số liệu thứ nhất gồm 16000 quan sát.
data11 <- CPS1988[-id1, ] # Bộ số liệu còn lại sau khi loại ra tất cả các
quan sát đã có ở data1.
id2 <- sample(nrow(CPS1988), round(p*nrow(CPS1988)))
data2 <- CPS1988[id2, ] # Lấy bộ số liệu thứ hai gồm 16000 quan sát.
data22 <- CPS1988[-id2, ] # Lấy phần số liệu còn lại sau khi loại ra tất cả c
ác quan sát đã có ở data2.
head(data1)
head(data2)
##
## =============================================================
## Dependent variable:
## ----------------------------
## wage
## (1) (2)
## -------------------------------------------------------------
## education 48.268*** 46.491***
## (1.150) (1.246)
##
## Constant -24.752 -1.028
## (15.432) (16.696)
##
## -------------------------------------------------------------
## Observations 16,000 16,000
## R2 0.099 0.080
## Adjusted R2 0.099 0.080
## Residual Std. Error (df = 15998) 421.488 455.417
## F Statistic (df = 1; 15998) 1,760.477*** 1,393.024***
## =============================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
library(Metrics)
MSE1 <- mse(data1$wage, predict(ols1, data1))
MSE2 <- mse(data2$wage, predict(ols2, data2))
print(paste(MSE1, MSE2))
Ở đây các bạn có thể thấy MSE1 thu được từ bộ dữ liệu data1 bé hơn MSE2 thu được từ data2. Phải
chăng các ước lượng từ data1 sẽ là đại diện hợp lí hơn so với các ước lượng từ data2 để mô tả mối
quan hệ thực giữa wage và education?.
Câu trả lời là chưa chắc. MSE1 và MSE2 mà chúng ta thu được ở trên chính là tỉ lệ sai sót huấn luyện
(training error rate). Nguyên nhân là ta thu được các ước lượng OLS từ data1 và data2 rồi ta sử dụng
chính hai mô hình thu được dựa trên hai bộ số liệu này để ước lượng wage thuộc chính data1 và
data2. Ở đây, bộ dữ liệu được sử dụng để xây dựng mô hình là data1 và data2 nên trong nghiên cứu
thống kê và kinh tế lượng, chúng có một tên gọi cụ thể hơn thể hiện bản chất và vài trò của bộ số liệu:
dữ liệu huấn luyện (training data, hoặc training set).
Tương tự khái niệm tỉ lệ sai sót huấn luyện, tỉ lệ sai sót kiểm định (testing error rate) được tính toán
dựa trên data11 và data22 – là hai bộ dữ liệu còn lại sau khi chúng ta lấy ra data1 và data2 – nhằm
đánh giá mô hình. Hai bộ dữ liệu data11 và data22 có tên gọi là dữ liệu kiểm định (testing data, hay
testing set). Tên gọi này có ngụ ý rằng, chẳng hạn, ols1 được xây dựng dựa trên bộ số liệu data1 và
sau đó bộ dữ liệu kiểm định tương ứng của data1 là data11 được sử dụng để đánh giá lại mô
hình. Chúng ta có thể tính toán tỉ lệ sai sót kiểm định ứng với hai bộ số liệu:
Như vậy, mặc dù tỉ lệ sai sót huấn luyện ứng với data1 là thấp hơn tỉ lệ sai sót huấn luyện ứng với
data2 nhưng tỉ lệ sai sót kiểm định ứng với data1 lại cao hơn tỉ lệ sai sót tỉ lệ sai sót kiểm định ứng
với data2.
Các khái niệm về tỉ lệ sai sót kiểm định và tỉ lệ sai sót huấn luyện là nền tảng của một khái niệm rất
quan trọng trong nghiên cứu thống kê nói chung và kinh tế lượng nói riêng, nhất là bài toán dự báo:
hiện tượng quá khớp (overfitting). Hiện tượng quá khớp được hiểu là một mô hình rất phù hợp với
bộ dữ liệu huấn luyện (MSE thấp và R2 cao chẳng hạn) nhưng lại không phù hợp với bộ dữ liệu kiểm
định (MSE cao và R2 thấp). Khi một mô hình xẩy ra hiện tượng quá khớp thì mặc dù nó có thể dự báo
rất tốt trên một tập quan sát nhưng nó lại thất bại trong việc dự báo khi chúng ta sử dụng bộ dữ liệu
khác. Nói cách khác, một mô hình quá khớp không có giá trị phổ quát vì nó chỉ phù hợp (fitting)
với một bộ dữ liệu cụ thể nào đó nhưng lại không phù hợp với những bộ dữ liệu khác và do vậy,
mô hình không có nhiều ý nghĩa trong bài toán dự báo cũng như mô tả.
Ngược lại với hiện tượng quá khớp là underfitting, theo đó, khả năng dự báo (hay khớp) với số liệu
của mô hình ở bộ số liệu huấn luyện là thấp hơn so với khả năng dự báo (hay khớp) của mô hình ở bộ
số liệu kiểm định.
Một mô hình tốt là một mô hình có cả hai thứ: tỉ lệ sai sót huấn luyện và tỉ lệ sai sót kiểm định đều
thấp. Thông thường khi đánh giá mô hình (hoặc so sánh các mô hình) thì chúng ta cần phải lưu tâm
đồng thời cả hai yếu tố này.
Những khái niệm các bạn vừa nghiên cứu ở trên là nền tảng cho một nhánh của khoa học thống kê
gọi là các phương pháp tái chọn mẫu (Resampling Methods) được trình bày ở mục sau.
Cuối cùng để giúp các bạn hiểu rõ hơn về hai loại tỉ lệ sai sót, dưới đây là R code dưới đây thực hiện
hồi quy OLS cho mô hình 2 với bộ dữ liệu huấn luyện là 16000 quan sát và bộ dữ liệu kiểm định là
28155 – 16000 quan sát còn lại. Sau khi thực hiện OLS xong tính MSEtraining (tỉ lệ sai sót huấn luyện)
và MSEtesting (tỉ lệ sai sót kiểm định). Quá trình này lặp đi lặp lại 1000 lần và do đó có 1000 cặp giá
trị của MSEtesting và MSEtraining được lưu lại ở data frame tên trangyeu. Cuối cùng chúng ta so sánh
mean (trung bình) của các giá trị MSE này:
## MSEtraining MSEtesting
## Min. :149297 Min. :145566
## 1st Qu.:177345 1st Qu.:173207
## Median :188070 Median :185580
## Mean :187115 Mean :186834
## 3rd Qu.:197456 3rd Qu.:199717
## Max. :218484 Max. :236670
Kết quả chỉ ra rằng MSEtesting (tỉ lệ sai sót kiểm định) có trung bình là 186834 thấp hơn MSEtraining
(tỉ lệ sai sót huấn luyện) có trung bình 187115 khi cho mô hình chạy với 1000 bộ dữ liệu khác nhau
nên có có thể thấy mô hình (2) có dấu hiệu của hiện tượng underfitting (một hiện tượng ngược lại
overfitting).
4.6 Đánh giá chất lượng của mô hình bằng các phương pháp tái chọn mẫu
Các phương pháp tái chọn mẫu (Resampling Methods) là một cách tiếp cận đầy sức mạnh và tin cậy
để đánh giá chất lượng của một mô hình thống kê nói chung cũng như các mô hình kinh tế lượng
(James et al., 2013). Trước đây, trong một thời gian khá dài, do sức mạnh tính toán của máy tính còn
hạn chế nên các phương pháp tái chọn mẫu dù rất hoàn thiện về lý thuyết nhưng trong thực tế ít được
sử dụng. Tuy nhiên, những hạn chế này không còn là trở ngại lớn khi mà sức mạnh tính toán của máy
tính ngày càng mạnh và nhanh như hiện nay.
Đúng như tên gọi của nó, phương pháp này sử dụng việc tái chọn mẫu lặp đi lặp lại, sử dụng các thông
tin thu được từ mỗi lần chọn mẫu đó để đánh giá chất lượng của một mô hình. Chẳng hạn, việc tái
chọn mẫu 1000 lần để nghiên cứu chất lượng của mô hình thông qua tỉ lệ sai sót kiểm định và huấn
luyện như các bạn đã thực hiện ở mục 4.5.4 chính là một phương pháp tái chọn mẫu. Mục này chúng
ta sẽ nghiên cứu chi tiết hơn về hai nhóm phương pháp tái chọn mẫu là Bootstrap và Cross-validation.
Mục này cũng giới thiệu phương pháp bootstrap thay thế cho sử dụng hồi quy tuyến tính OLS vốn
phụ thuộc nhiều vào các giả định chặt chẽ và do vậy các kết quả ước lượng thu được từ OLS là rất
nhậy với những giả định này. Vì lý do này, các ước lượng thu được từ phương pháp bootstrap sẽ là
tin cậy hơn.
Để minh họa cho phương pháp tiếp cận này, chúng ta nghiên cứu tình huống sau. Giả sử chúng ta có
một số tiền cố định và đầu tư số tiền này vào hai cổ phiếu A và B với lợi tức lần lượt là X và Y. Chú ý
rằng X và Y là những biến nghẫu nhiên. Nếu gọi α là tỉ trọng đầu tư vào cổ phiếu A thì (1- α) sẽ là tỉ
trọng đầu tư vào cổ phiếu B. Như vậy rủi ro của danh mục đầu tư này được đo bằng:
Var(𝛼𝑋 + (1 − 𝛼)𝑌)
Chúng ta đã biết rằng nhằm tối thiểu hóa rủi ro, tỉ trọng đầu tư vào cổ phiếu A phải thỏa mãn:
𝜎𝑌2 − 𝜎𝑋𝑌
𝛼=
𝜎𝑋2 + 𝜎𝑌2 − 2𝜎𝑋𝑌
Trong đó :
Vấn đề ở đâu là trong thực tế chúng ta không biết ba đại lượng trên, do vậy chúng ta buộc phải ước
lượng các giá trị này để tính giá trị ước lượng của α la α̂ . Điều này được tiến hành như sau. Chúng ta
lấy 100 cặp quan sát của X và Y để tình α̂ 1. Lặp lại quá trình này 1000 lần và như vậy chúng ta có 1000
giá trị của α̂ . Lúc này trung bình của α̂ được tính như sau:
1,000
1
𝛼̅ = ∑ 𝛼̂𝑟
1,000
𝑟=1
Còn độ lệch chuẩn của α̂ được tính theo công thức sau:
1,000
1
√ ∑ (𝛼̂𝑟 − 𝛼̅)2
1,000 − 1
𝑟=1
Những bước mô tả như trên trong thực tế chúng ta khó có thể áp dụng được trong thực tế vì khó có
thể lấy ra 1000 mẫu khác nhau gồm 100 cặp giá trị X, Y từ mẫu nguyên thủy ban đầu.
Tuy nhiên chúng ta có thể sử dụng phương pháp Bootstrap để thực hiện điều này bằng cách tái lấy
mẫu có hoàn lại. Nghĩa là các quan sát có thể được lấy một cách trùng lặp. Thủ tục này được mô tả
chi tiết ngay sau đây.
Giả sử mẫu nguyên thủy (Original Data) ban đầu Z của chúng ta có n = 3 quan sát . Chúng ta lấy ra
mẫu Z*1 cũng với ba quan sát – tức là đúng bằng số lượng quan sát ở mẫu nguyên thủy. Do một quan
sát bất kì có thể được chọn nhiều hơn 1 lần nên chúng ta thấy mẫu này có quan sát thứ ba (ở mẫu
nguyên thủy) xuất hiện hai lần. Quá trình này được lặp lại nhiều lần và cứ với một mẫu thứ cấp, chẳng
hạn, mẫu Z*1 chúng ta có một giá trị ước lượng α̂ *1. Lặp lại quá trình này B lần và do đó chúng ta có B
giá trị của α̂ * .
Khi đó độ lệch chuẩn của α từ phương pháp Bootstrap được tính theo công thức tổng quát sau:
𝐵
1
SE𝐵 (𝛼̂) = √ ∑(𝛼̂𝑟 − 𝛼̅)2
𝐵−1
𝑟=1
Chúng ta sẽ sử dụng bộ số liệu Portfolio tích hợp cùng gói ISLR (cài đặt gói này bằng lệnh
install.packages(“ISLR”)) để thực hiện phương pháp này với R. Bộ số liệu này là thông tin về lợi tức
X và Y của hai cổ phiếu trong 100 ngày. Trước hết chúng ta cần viết hàm tính α tối ưu theo công thức:
𝜎𝑌2 − 𝜎𝑋𝑌
𝛼=
𝜎𝑋2 + 𝜎𝑌2 − 2𝜎𝑋𝑌
# Tạo hàm có tên alpha để tính tỉ trọng đầu tư vào tài sản A.
alpha <- function(data, index){
X = data$X[index]
Y = data$Y[index]
return((var(Y) - cov(X,Y)) / (var(X) + var(Y) - 2*cov(X,Y)))
}
Chúng ta gọi bộ số liệu Portfolio của gói ISLR. Đây là bộ dữ liệu về lợi tức của hai cổ phiếu (chưa rõ
đơn vị đo) trong 100 ngày liên tiếp:
library(ISLR)
data(Portfolio)
head(Portfolio)
## X Y
## 1 -0.8952509 -0.2349235
## 2 -1.5624543 -0.8851760
## 3 -0.4170899 0.2718880
## 4 1.0443557 -0.7341975
## 5 -0.3155684 0.8419834
## 6 -1.7371238 -2.0371910
tail(Portfolio)
## X Y
## 95 2.2608577 0.6732248
## 96 0.4790909 1.4547745
## 97 -0.5350200 -0.3991748
## 98 -0.7731293 -0.9571748
## 99 0.4036343 1.3960382
## 100 -0.5884964 -0.4972851
Chúng ta có thể tính ước lượng của α (tức α̂ ) ứng với mẫu cụ thể này:
alpha(Portfolio)
## [1] 0.5758321
Chú ý rằng con số 0.5758 ở đây là ước lượng của α ứng với mẫu gốc. Dưới đây chúng ta tạo ra một
mẫu bằng phương pháp Bootstrap và tính ước lượng của α ứng với mẫu này:
## [1] 0.5220407
Tất nhiên kết quả của bạn sẽ không phải lf 0.5220407 như trên vì tính chất ngẫu nhiên của mẫu được
chọn. Và mỗi lần thực hiện thì sẽ ra một kết quả khác. Chúng ta có thể lặp lại quá trình này 1000 lần,
và do vậy có 1000 giá trị ước lượng của α. Chúng ta ghi lại 1000 giá trị này và tính mean cũng như độ
lệch chuẩn. Tuy nhiên R có gói boot có thể tự động làm việc này một cách nhanh chóng. Để tái tạo kết
quả, chúng ta sử dụng hàm set.seet() như sau:
library(boot)
set.seed(2611) # Để đảm bảo kết quả là trùng lặp.
trang <- boot(Portfolio, alpha, R = 1000)
trang
##
## ORDINARY NONPARAMETRIC BOOTSTRAP
##
##
## Call:
## boot(data = Portfolio, statistic = alpha, R = 1000)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 0.5758321 0.002269671 0.09310941
Chúng ta thấy giá trị ứng với cột original chính là ước lượng của alpha ứng với mẫu gốc. Một kết quả
mà ta đã có từ trước. Kết quả chỉ ra rằng sai số chuẩn ước lượng cho ước lượng của alpha là
0.09310941. Chúng ta có thể tính trung bình, tính lại giá trị của sai số chuẩn này:
head(trang$t) # Xem 6 quan sát đầu trong số 1000 ước lượng của alpha.
## [,1]
## [1,] 0.5081016
## [2,] 0.3961208
## [3,] 0.5432477
## [4,] 0.7088269
## [5,] 0.4465900
## [6,] 0.6602969
## [,1]
## [995,] 0.5278409
## [996,] 0.5216640
## [997,] 0.7314720
## [998,] 0.5328849
## [999,] 0.6543257
## [1000,] 0.5533597
## [1] 0.09310941
mean(trang$t) # Trung bình các ước lượng ứng với 1000 mẫu Bootstrap.
## [1] 0.5781017
Chúng ta có thể hình ảnh hóa cho 1000 giá trị ước lượng của alpha:
par(mfrow = c(1, 1)) # Đặt chế độ hiển thị mặc định của R
Hoàn toàn tương tự chúng ta có thể sử dụng phương pháp Bootstrap để đánh giá chất lượng cũng
như các khía cạnh khác cho kết quả hồi quy thu được ở mục 4.2. Trước hết chúng ta viết hàm có tên
boot.hesohoiquy để hiển thị các hệ số hồi quy:
## (Intercept) INCOME
## 1263.6871121 0.1294835
Kết quả trên là trùng khớp với kết quả thu được ở mục 4.2 khi chúng ta thực hiện hồi quy. Dưới đây
là các câu lệnh thực hiện bootstrap cho hai mẫu. Chú ý rằng những ước lượng thu được tương ứng là
khác nhau:
set.seed(123)
boot.hesohoiquy(dung, sample(51, 51, replace = T))
## (Intercept) INCOME
## 65.794685 0.139344
## (Intercept) INCOME
## 1720.8031663 0.1258176
Chúng ta có thể lặp lại quá trình này 1000 lần để nghiên cứu sự ổn định của mô hình hồi quy thu được
ở mục 4.2:
##
## ORDINARY NONPARAMETRIC BOOTSTRAP
##
##
## Call:
## boot(data = dung, statistic = boot.hesohoiquy, R = 1000)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 1263.6871121 -2.136956e+02 7.374884e+02
## t2* 0.1294835 1.849314e-03 6.860844e-03
Chúng ta có thể hiểu rõ hơn những kết quả trên như sau:
## [,1] [,2]
## [1,] 1122.742 0.1311281
## [2,] 1433.357 0.1234588
## [3,] 1407.709 0.1262977
## [4,] 1565.651 0.1269054
## [5,] 1789.845 0.1278887
## [6,] 924.016 0.1332488
tail(love)
## [,1] [,2]
## [995,] 1305.4825 0.1295534
## [996,] -250.2552 0.1447241
## [997,] 1906.9541 0.1247074
## [998,] 1892.8701 0.1269881
## [999,] 1153.3988 0.1288668
## [1000,] 734.9050 0.1325789
summary(love)
## V1 V2
## Min. :-850.5 Min. :0.1179
## 1st Qu.: 412.1 1st Qu.:0.1259
## Median :1199.1 Median :0.1300
## Mean :1050.0 Mean :0.1313
## 3rd Qu.:1612.8 3rd Qu.:0.1370
## Max. :2852.6 Max. :0.1490
So sánh, chẳng hạn sai số chuẩn của các ước lượng từ phương pháp Bootstrap với hồi quy ở mục 4.2:
Hệ số chặn và hệ số góc thu được từ phương pháp bootstrap lần lượt là 1050 và 0.1313. Những kết
quả này là khá sát với những kết quả khi sử dụng OLS. Tuy nhiên độ lệch chuẩn ứng với các ước lượng
có sai khác đáng kể hơn. Phải chăng các ước lượng thu được từ phương pháp bootstrap là có vấn đề?
Sự thực thì ngược lại. Thật vậy, các ước lượng cho sai số chuẩn ứng với các hệ số hồi quy OLS phụ
thuộc vào phương sai σ2 nhưng giá trị này là không bao giờ biết và do vậy buộc phải ước lượng giá trị
này bằng sử dụng RSS. Ngoài ra, OLS giả định rằng các giá trị của INCOME là cố định và do đó những
sai lệch (variation) được “nhóm” vào sai số ngẫu nhiên. Các ước lượng thu được từ bootstrap không
dựa vào các giả định này vào do vậy nó đưa ra những ước lượng hợp lí hơn (James et al., 2013;
Chernick, 2008) so với các ước lượng thu được từ OLS như chúng ta đã làm ở mục 4.2.
MSE1 = (y - ŷ 1)2
Rõ ràng, bộ dữ liệu gồm n-1 phần tử được sử dụng để dựng mô hình OLS chính là dữ liệu huấn luyện
và phần tử duy nhất được trừ ra (x1, y1) đóng vai trò là bộ dữ liệu kiểm định. Như vậy, MSE1 sẽ là sai
số kiểm định và sẽ được sử dụng để đánh giá mô hình ứng với bộ dữ liệu huấn luyện gồm n-1 phần
tử này.
Chúng ta sẽ lặp lại quá trình bằng trên bằng cách giữ lại phần tử (x2, y2), chạy mô hình OLS cho n-1
quan sát còn lại và tính MSE1 theo công thức MSE2 = (y - ŷ 2)2. Do bộ dữ liệu ban đầu có n phần tử nên
quá trình này được lặp lại n lần và trung bình của các MSE, kí hiệu là CV(n) được tính theo công thức
dưới đây sẽ là tiêu chí đánh giá sai sót kiểm định toàn cục của mô hình:
𝑛
1
CV(𝑛) = ∑ MSE𝑖
𝑛
𝑖=1
Chúng ta sẽ sử dụng bộ số liệu ở mục 4.2 để thực hành LOOCV. Dưới đây là R code thực hiện một vòng
lặp 51 lần cho bộ dữ liệu vì rằng chúng ta có 51 quan sát. Chú ý rằng, nếu bộ dữ liệu có 1 triệu quan
sát, thì chúng ta hoàn toàn có thể chạy một vòng lặp 1 triệu lần. Tuy nhiên, thực tế không nhất thiết
phải làm thế vì để đánh giá chất lượng và độ ổn định của mô hình ta chỉ cần một vòng lặp đủ lớn,
chẳng hạn, 10000 lần là đủ.
cacMSE <- c()
for (i in 1:51){
testing <- dung[i,]
training <- dung[-i,]
ols <- lm(HEALTH ~ INCOME, data = training)
mse <- mse(testing$HEALTH, predict(ols, testing))
cacMSE <- c(cacMSE, mse)
}
mean(cacMSE)
## [1] 14388750
Chúng ta có thể thấy trong số 51 giá trị MSE, chỉ có 4 giá trị MSE là khác biệt so với nhóm còn lại.
Nghĩa là kết quả dự báo của mô hình cũng khá ổn định. Tính ổn định của mô hình cũng là một tiêu chí
quan trọng cần đánh giá nhất là với mục đích dự báo. Trong tình huống của chúng ta, hầu hết các
MSE đều có giá trị khá sát nhau, ngoại trừ có 4 tình huống các MSE mà chúng ta thấy trên graph, đặc
biệt là đối với phần tử thứ 5. Với mục đích dự báo, chúng ta sẽ tự tin hơn khi sử dụng một mô hình
mà tạo ra các kết quả dự báo là ổn định, không sai khác quá nhiều so với nhau trên các mẫu dữ liệu
khác nhau. Do vậy, sử dụng LOOCV cũng như các thủ tục tái chọn mẫu khác để đánh giá mô hình là
cần thiết.
Theo cách tiếp cận này, bộ dữ liệu ban đầu sẽ được chia thành ba phần (gọi là 3 folds). Phần thứ nhất
được giữ lại và đóng vai trò là dữ liệu kiểm định (Testing Data 1), hai phần còn lại là dữ liệu huấn
luyện (Training Data 1). Mô hình sẽ được xây dựng trên bộ dữ liệu huấn luyện này. Sau đó, bộ dữ liệu
kiểm định tương ứng với nó (là Testing Data 1) sẽ được sử dụng để đánh giá lại mô hình căn cứ vào
một tiêu chí nào đó, chẳng hạn, là MSE. Với kiểm tra chéo 3 lớp thì quá trình này lặp lại 3 lần và chúng
ta sẽ có 3 giá trị MSE tương ứng. Sai sót kiểm định toàn cục của mô hình trong tình huống này được
tính theo công thức:
3
1
CV(3) = ∑ MSE𝑖
3
𝑖=1
Dễ dàng thấy rằng LOOCV là trường hợp đặc biệt của kiểm định chéo k lớp khi mà k = n. Tuy nhiên
trong thực tế chúng ta thường sử dụng kiểm định chéo k lớp với một trong hai giá trị tối ưu là k= 5
hoặc k = 10. Có ít nhất hai lý do để lựa chọn k như vậy. Thứ nhất là cái giá phải trả khi thực hiện tính
toán nếu chúng ta chọn k = n nếu số quan sát là rất lớn vì chúng ta sẽ phải chạy mô hình n lần, mỗi
lần cho n-1 quan sát còn lại. Thứ hai, và cũng là quan trọng nhất, theo Molinaro (2005) và Kim (2009),
đó là sự đánh đổi Bias – Variance (Bias-Variance Trade-off). Lí do thứ hai sẽ được giải thích chi tiết ở
mục sau.
Để minh họa, các bạn có thể sử dụng bộ số liệu ở mục 4.1 để thực hiện kiểm tra chéo với k = 3:
## [1] 14948088
Chúng ta có thể viết một vòng lặp for loop cho ngắn gọn chứ không nên làm dài dòng như trên:
## [1] 14948088
Tất nhiên trong thực tế, để kiểm định chất lượng cũng như tính ổn định của mô hình, quá trình này
có thể được lặp lại hàng trăm, thậm chí hàng ngàn lần. Tất nhiên chúng ta không thể thực hiện thủ
công như trên. R có một gói hỗ trợ cho việc thực hiện kiểm tra chéo k lớp một cách tự động rất thuận
tiện là caret. Chúng ta sẽ thực hành với gói caret ở mục 4.6.3.
Tuy nhiên, tính không chệch chưa phản ánh toàn bộ câu chuyện. Vì chúng ta còn quan tâm đến sự ổn
định (hay Variance) của các ước lượng. Dễ dàng thấy rằng LOOCV có mức độ ổn định kém hơn kiểm
định chéo. Nguyên nhân là khi chúng ta thực hiện LOOCV, các mô hình được dựng trên bộ dữ liệu là
gần như không thay đổi so với nhau (chỉ khác duy nhất một quan sát) do đó các ước lượng (kết quả)
thu được là tương quan dương cao với nhau. Nhưng chúng ta thực hiện kiểm tra chéo k lớp thì
những ước lượng (kết quả) thu được từ k mô hình sẽ ít tương quan với nhau hơn do bộ dữ liệu huấn
luyện là khác biệt hơn. Điều này dẫn đến, chẳng hạn, các MSE thu được từ LOOCV có xu hướng biến
động hơn so với sử dụng kiểm tra chéo k lớp. Nếu chúng ta chọn MSE là tiêu chí đánh giá chất lương
của mô hình thì giá trị kì vọng của MSE có thể được phân thành ba bộ phận sau:
Ở đây bộ phận thứ nhất σ2 được gọi là nhiễu không thể loại trừ (irreducible noise) với ý nghĩa rằng
chúng ta không thể loại bỏ nhiễu này dù sử dụng mô hình nào đi chăng nữa. Bộ phận thứ hai phản
ánh mức độ chính xác về mối quan hệ giữa biến độc lập và biến phụ thuộc. Bộ phận cuối cùng phản
ánh mức độ sai lệch của mô hình ứng với các bộ dữ liệu khác nhau. Rõ ràng, để nâng cao chất lượng
của mô hình chúng ta sẽ tìm kiếm một mô hình, một phương pháp mà tối thiểu hóa cả hai bộ phận
của MSE của phương trình trên.
Với các phương pháp tái chọn mẫu, các nghiên cứu lý thuyết và thực nghiệm đã chỉ ra rằng k tối ưu
để cân bằng giữa tính không chệch và ổn định là 5 (với mẫu lớn) hoặc 10 (nếu mẫu là nhỏ). Thực tế,
các phần mềm thống kê – kinh tế lượng nếu có chức năng kiểm định chéo thì thường mặc định k là 5
hoặc 10, chẳng hạn gói caret của R mặc định giá trị k là 5.
4.6.3 Giới thiệu về các phương pháp tái chọn mẫu bằng gói caret
Như đã thấy, việc thực hiện tra chéo LOOCV hay k lớp theo cách thức thủ công là nhàm chán và mất
thời gian gõ lệnh. R có rất nhiều gói cho phép thực hiện những công việc này một các tự động. Một
trong những gói rất mạnh là caret của Kuhn (2013) . Gói này không chỉ được sử dụng cho hầu hết các
phân tích kinh tế lượng thường thấy mà còn sử dụng cho Machine Learning (thực tế gói này được
Kuhn thiết kế với mục đích xây dựng các mô hình Machine Learning).
Trước hết chúng ta so sánh việc thực hiện OLS với gói caret bằng hàm train() và so sánh với sử dụng
hàm lm() mà chúng ta đã biết. Dữ liệu được sử dụng, để minh họa, chúng ta chọn chỉ 10 quan sát đầu
của bộ dữ liệu CPS1988. Mô hình hồi quy nghiên cứu là wage = β1 + β2education. Đánh giá tác động
của số năm đi học (education) lên mức lương (wage):
library(AER)
data(CPS1988)
dung <- CPS1988 %>% slice(1:10)
ols1 <- dung %>% lm(wage ~ education, data = .)
ols1 %>% summary()
##
## Call:
## lm(formula = wage ~ education, data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -449.05 -246.57 -21.75 54.60 957.97
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -107.57 608.80 -0.177 0.864
## education 56.67 52.53 1.079 0.312
##
## Residual standard error: 427.1 on 8 degrees of freedom
## Multiple R-squared: 0.127, Adjusted R-squared: 0.01788
## F-statistic: 1.164 on 1 and 8 DF, p-value: 0.3121
So sánh với thực hiện OLS bằng hàm train() của gói caret. Ý nghĩa của một số dòng lệnh khác được
giải thích sau:
library(caret)
set.seed(1709)
ctrl <- trainControl(method = "repeatedcv", number = 2, repeats = 1)
ols2 <- dung %>%
train(wage ~ education, method = "lm", trControl = ctrl, data = .)
ols2 %>% summary()
##
## Call:
## lm(formula = .outcome ~ ., data = dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -449.05 -246.57 -21.75 54.60 957.97
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -107.57 608.80 -0.177 0.864
## education 56.67 52.53 1.079 0.312
##
## Residual standard error: 427.1 on 8 degrees of freedom
## Multiple R-squared: 0.127, Adjusted R-squared: 0.01788
## F-statistic: 1.164 on 1 and 8 DF, p-value: 0.3121
Có thể thấy các hệ số hồi quy (cũng như tất cả các kết quả khác) thu được từ hai cách thức thực hiện
OLS là như nhau.
Dưới đây là một số giải thích về sử dụng gói caret cho thực hiện OLS. Trước khi thực hiện OLS chúng
ta đã ngầm chỉ thị cho caret thực hiện OLS đồng thời với kiểm tra chéo 2 lớp với hàm trainControl()
và được giải thích ngay sau đây:
method = "repeatedcv" : lựa chọn này để thực hiện kiểm tra chéo k lớp có lặp lại.
number = 2 : chỉ rõ số lớp là 2 (tức là k=2).
repeats = 1 : chỉ rõ số lần lặp là 1.
Để hiểu ý nghĩa của các lựa chọn này chúng ta hãy xem đối tượng ols2:
ols2
## Linear Regression
##
## 10 samples
## 1 predictor
##
## No pre-processing
## Resampling: Cross-Validated (2 fold, repeated 1 times)
## Summary of sample sizes: 6, 4
## Resampling results:
##
## RMSE Rsquared
## 449.4058 0.09213921
##
## Tuning parameter 'intercept' was held constant at a value of TRUE
Kết quả được giải thích dưới đây. Với lựa chọn như trên thì số liệu được sử dụng cho chạy mô hình
(10 quan sát) sẽ được chia làm 2 phần dữ liệu nhỏ xấp xỉ bằng nhau. Trong tình huống của chúng ta
hai phần này có số lượng lần lượt là 6 và 4 và có thể thấy ở dòng Summary of sample sizes: 6, 4.
Phần thứ nhất (gọi là training1) gồm 6 quan sát sẽ được sử dụng để chạy một mô hình OLS con thứ
nhất (gọi là tom) và mức độ phù hợp của mô hình này được đánh giá thông qua RMSE và R2 với phần
dữ liệu còn lại là 4 quan sát (gọi là testing 1). Tiếp tục, phần dữ liệu con thứ hai gồm 4 quan sát (gọi
là training2) sẽ được sử dụng để chạy một mô hình OLS con thứ hai (gọi là ca) và mô hình thu được
sẽ tiếp tục được đánh giá thông qua RMSE và R2 với phần dữ liệu còn lại là 6 quan sát (gọi là testing2).
Vì k = 2 nên các bạn có thể thấy rằng training1 chính là testing2 và training2 chính là testing1 (chú ý
rằng điều này chỉ đúng khi k =2 mà thôi). Như vậy sẽ có hai giá trị RMSE, hai giá trị R2 tương ứng với
hai mô hình con này. Cần nhắc lại rằng các cặp RMSE và R2 này chính là sai sót kiểm định. Con số R2
= 0.092139 và RMSE = 449.4058 mà chúng ta thấy là trung bình của hai cặp giá trị R2 và RMSE.
Vì phần dữ liệu thứ nhất (6 quan sát) được lấy ra từ 10 quan sát ban đầu nên cơ bản chúng ta sẽ có
tổ hợp chập 6 của 10 cách lấy khác nhau và do đó kết quả thu được ở trên nó chỉ là một tình huống
cá biệt. Nếu không có lệnh gieo hạt set.seed(1709) thì kết của của bạn sẽ khác vì tính chất ngẫu
nhiên của việc chọn mẫu.
Điều này cũng có nghĩa là con số R2 = 0.092139 sẽ có thể không trùng với R2 = 0.127 của mô hình sử
dụng cả 10 dữ liệu khi bạn sử dụng lệnh summary(ols2).
Từ phân tích trên chúng ta cũng có thể thấy ngay rằng, chẳng hạn, tổng của hai bộ dữ liệu testing1 và
training1 phải trùng hợp với bộ dữ liệu tên dung có 10 quan sát ban đầu. Có thể kiếm tra lại nhận
định này bằng một số lệnh sau (không hiển thị kết quả):
total <- rbind(training1, testing1)
summary(total)
summary(dung)
Chúng ta trở lại với các kết quả R2 = 0.092139 và RMSE = 449.4058 và phân tích kĩ hơn những con
số này đến từ đâu và bằng cách nào:
ols2$results
Kết quả trên nghĩa là RMSE và R2 của mô hình con thứ nhất lần lượt là 598.4231 và 0.181561, còn đối
với mô hình con thứ hai sẽ là 300.3885 và 0.00271741. Chúng ta có thể kiểm tra lại để thấy rằng trung
bình của các RMSE và R2 chính là 449.4058 và 0.09213921:
(598.4231 + 300.3885) / 2
## [1] 449.4058
(0.18156100 + 0.00271741) / 2
## [1] 0.09213921
Chúng ta cũng có thể tính toán thủ công, ví dụ, là R2 cho mô hình con thứ nhất như sau:
d1 <- ols2$control$index$Fold1.Rep1
training1 <- dung[d1,] # Mẫu huấn luyện thứ nhất.
testing1 <- dung[-d1,] # Mẫu kiểm định thứ nhất.
tom <- training1 %>% lm(wage ~ education, data = .)
dubao1 <- predict(tom, testing1)
Rsquared1 <- cor(dubao1, testing1$wage)^2
Rsquared1
## [1] 0.181561
Tính toán trực tiếp R2 cho mô hình con thứ 2 theo cách hoàn toàn tương tự (dù cách làm hơi khác):
d2 <- ols2$control$index$Fold2.Rep1
training2 <- dung[d2,]
testing2 <- dplyr::setdiff(dung, training2)
ca <- training2 %>% lm(wage ~ education, data = .)
dubao2 <- predict(ca, testing2)
Rsquared2 <- cor(dubao2, testing2$wage)^2
Rsquared2
## [1] 0.00271741
Đến đây các bạn có thể tò mò rằng tại sao chúng ta lại dùng những lệnh kiểu như ols2$results hay
d2 <- ols2$control$index$Fold2.Rep1. Đây chính là cách thức để khai thác thông tin từ đối tượng
có tên là ols2. Nó là một list, tạm hiểu như sau: ols2 bao gồm nhiều “đối tượng con” được hiển thị sau
dấu $ bằng câu lệnh sau (hiển thị một phần kết quả trong một danh sách rất dài) :
str(ols2)
## List of 23
## $ method : chr "lm"
## $ modelInfo :List of 13
## ..$ label : chr "Linear Regression"
## ..$ library : NULL
## ..$ loop : NULL
## ..$ type : chr "Regression"
## ..$ parameters:'data.frame': 1 obs. of 3 variables:
Quan sát thì các bạn có suy đoán rằng nếu gõ lệnh ols2$modelInfo$type sẽ cho ra chữ “Regression”.
Trong thực tế, chúng ta thường thực hiện kiểm tra chéo 5 hoặc 10 lớp với số lần lập lại đủ nhiều để
chúng ta có thể đánh giá chính xác hơn mô hình. Sử dụng toàn bộ các quan sát của bộ dữ liệu CPS1988
chúng ta có thể đánh giá nhiều khía cạch về chất lượng của mô hình OLS chứ không chỉ căn cứ vào,
chẳng hạn, R2 không thôi. Dưới đây chúng ta thực hiện OLS đồng thời với thực hiện đánh giá mô hình
với kiểm tra 10 lớp, lặp lại 10 lần. Nghĩa là chúng ta thực hiện tất cả 10*10 + 1 bằng 101 mô hình tất
cả. Cụ thể có 100 mô hình con và một mô hình chính sử dụng toàn bộ các quan sát. Do số quan sát là
rất lớn nên chúng ta nên biết thêm cần bao nhiêu thời gian để chạy các mô hình:
Mất chừng 6 giây để chạy 101 mô hình. Một số tình huống chúng ta có thể mất hàng giờ và thậm chí
hàng chục giờ để chạy mô hình.
Chúng ta có thể trích xuất ra data frame và đặt tên là k chứa các thông tin về RMSE , R2 của 100 mô
hình con:
k <- all$resample
summary(k)
Các giá trị trung bình lần lượt là 429.4 và 0.09498. Những giá trị trung bình này có thể thấy bằng hai
cách khác nhau:
all$results # Cách 1.
all # Cách 2.
## Linear Regression
##
## 28155 samples
## 1 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 10 times)
## Summary of sample sizes: 25339, 25340, 25339, 25339, 25339, 25340, ...
## Resampling results:
##
## RMSE Rsquared
## 429.4022 0.09497748
##
## Tuning parameter 'intercept' was held constant at a value of TRUE
##
Ở đây các bạn có thể thấy 100 bộ dữ liệu huấn luyện có kích thước lần lượt là 25339, 25340, 25339,
25339, 25339, 25340… Con số này chính là xấp xỉ 90% của 28155 quan sát ban đầu:
28155*0.9
## [1] 25339.5
Chúng ta có thể đánh giá, chẳng hạn, mức độ ổn định của mô hình một cách hình ảnh:
k %>%
select(-Resample) %>%
gather(Metric, Value) %>%
ggplot(aes(Metric, Value, fill = Metric)) +
geom_boxplot(show.legend = FALSE) + theme_minimal() +
facet_wrap(~ Metric, scales = "free")
k %>%
select(-Resample) %>%
gather(Metric, Value) %>%
ggplot(aes(Value)) +
geom_density(color = "red", fill = "red", alpha = 0.3) +
geom_histogram(aes(y = ..density..), color = "blue", fill = "blue", alpha = 0.3
) +
facet_wrap(~ Metric, scales = "free")
Có thể thấy rằng một tỉ lệ lớn các mô hình con có RMSE thấp (tin tốt) vì Histogram (Density) bị méo
về phía dương. Tất nhiên chúng ta còn đánh giá mức độ ổn định của mô hình này căn cứ vào độ méo
nữa. Một mô hình tốt, ngoài RMSE thấp thì cần tiêu chí ổn định. Nghĩa là phân phối của các RMSE
càng tiến về phân phối chuẩn càng tốt. Nếu nhìn vào Boxplot thì tiêu chí này có nghĩa là median Q2
gần như nằm chính giữa của hộp. Tất nhiên trong tình huống của chúng ta thì không phải vậy.
4.7 Dữ liệu thiếu và xử lý dữ liệu thiếu trong phân tích kinh tế lượng
Trong các giáo trình thống kê – kinh tế lượng tiêu chuẩn, chúng ta chỉ gặp duy nhất một trường hợp
sau: không có quan sát nào thiếu. Tuy nhiên, trong thực tế, dữ liệu thiếu mới là trường hợp chúng gặp
thường xuyên hơn. Giả sử rằng biến luong và thunhapkhac (ở mục 2.1 của chương 2) thiếu ở các quan
sát thứ hai và cuối cùng. Lúc đó trong R chúng ta sẽ nhập dữ liệu thiếu bằng kí tự NA (viết tắt của Not
Available) như sau:
luong <- c(20, NA, 28, 24, 32, 36, 32, 34, 24, 22, 28, 30)
thunhapkhac <- c(16, 10, 2, 0, 18, 10, 16, 24, 28, 20, 8, NA)
head(trangxinh)
## 5 32 18 36.0
## 6 36 10 31.4
R sẽ không thực hiện bất kì tính toán nào nếu có số liệu thiếu. Ví dụ:
mean(luong)
## [1] NA
Lúc này, để tính toán trung bình luong chúng ta phải làm như sau:
mean(luong, na.rm = T)
## [1] 28.18182
Nghĩa là lựa chọn na.rm = T chỉ thị cho R loại bất kì quan sát thiếu nào nếu có trước khi tính trung
bình. Điều này cũng có nghĩa là con số 28.18182 ở trên là trung bình của 11 quan sát chứ không phải
12.
Các xử lý thông thường là nếu tỉ lệ số liệu thiếu không quá lớn, chúng ta sẽ bỏ đi những quan sát thiếu.
Dưới đây là câu lệnh bỏ quan sát thiếu (là 2) từ trangxinh và tạo ra data frame mới với tên gọi là dung:
Lúc này, các bạn sẽ thấy dung chỉ còn lại 10 quan sát mà thôi so với 12 quan sát ban đầu:
head(dung)
dim(trangxinh)
## [1] 12 3
dim(dung)
## [1] 10 3
Cách xử lý số liệu như trên là không phù hợp và không chuyên nghiệp ngay cả trong tình huống dữ
liệu thiếu là không nhiều. Dưới đây là một ví dụ trực quan. Giả sử chúng ta khảo sát thông tin về 5
biến số a, b, c, d, và e thể hiện trạng thái sức khỏe của 5 bệnh nhân và dữ liệu thiếu (tô màu vàng) lại
xuất hiện trên một đường chéo theo kiểu như sau:
Lúc này, nếu xử lý số liệu thiếu theo cách thức trên thì bạn sẽ không còn dữ liệu nào để thực hiện
phân tích nữa.
Ví dụ trên chỉ ra rằng chúng ta cần một chiến lược xử lý số liệu thiếu khoa học hơn. Ví dụ, chúng ta có
thể thay số điểm số liệu trống bằng trung bình của biến số. Gói mice của R có thể thực hiện cách thức
chèn số liệu thiếu (Data Imputation) theo một phương pháp tương tự với mô tả ở trên với tên là
khớp trung bình dự báo (predictive mean matching - PMM).
Để mình họa, chúng ta lấy bộ số liệu pima.csv bao gồm 768 quan sát ứng với 768 bệnh nhân. Vì một
lý do nào đó, thông tin về hàm lượng insulin trong máu của bệnh nhân thứ nhất chẳng hạn là không
có. Bộ số liệu của chúng ta sẽ là bộ số liệu thiếu như chúng ta có thể thấy dưới đây:
setwd("D:/KTLR")
dung <- read.csv("pima.csv")
head(dung)
Trước hết, chúng ta có thể điều tra “mật độ” của dữ liệu thiếu bằng cả phương pháp hình ảnh và số
với sự trợ giúp của gói VIM như sau:
library(VIM)
trangyeu<- aggr(dung, col=c('navyblue','yellow'),
numbers = TRUE, sortVars = TRUE, labels = names(dung),
cex.axis = .7, gap = 3, ylab = c("Du Lieu Thieu","Pattern"))
##
## Variables sorted by number of missings:
## Variable Count
## insulin 0.486979167
## triceps 0.295572917
## diastolic 0.045572917
## bmi 0.014322917
## glucose 0.006510417
## X 0.000000000
## pregnant 0.000000000
## diabetes 0.000000000
## age 0.000000000
## test 0.000000000
Nếu bức tranh của chúng ta càng nhiều đốm màu vàng thì có nghĩa là dữ liệu của chúng ta thiếu càng
nhiều. Cụ thể hơn bằng số thì biến insulin thiếu 48.69% (nhiều nhất), còn biến glucose là 0.65%.
Dưới đây là câu lệnh cho phép chúng ta chèn dữ liệu thiếu theo phương pháp PMM bằng gói mice:
library(mice)
apple <- mice(dung, m=2, method = "pmm", seed = 100)
##
## iter imp variable
## 1 1 glucose diastolic triceps insulin bmi
## 1 2 glucose diastolic triceps insulin bmi
## 2 1 glucose diastolic triceps insulin bmi
Câu lệnh trên có nghĩa là chúng ta tạo ra hai bộ số liệu khác nhau (m=2) từ bộ số liệu trống nguyên
bản bằng phương pháp predictive mean matching (method = “pmm”). Chúng ta có thể xem qua, chẳng
hạn, hai trong số ba bộ dữ liệu này:
Chúng ta cũng có thể thực hiện hai mô hình hồi quy ứng với hai bộ số liệu này và so sánh chúng các
kết quả tương ứng với nhau với sự hỗ trợ của gói stargazer:
##
## So sánh OLS1 và OLS2
## ===========================================================
## Dependent variable:
## ----------------------------
## diabetes
## (1) (2)
## -----------------------------------------------------------
## bmi 0.007*** 0.008***
## (0.002) (0.002)
##
## Constant 0.239*** 0.228***
## (0.057) (0.056)
##
## -----------------------------------------------------------
## Observations 768 768
## R2 0.022 0.025
## Adjusted R2 0.021 0.024
## Residual Std. Error (df = 766) 0.328 0.327
## F Statistic (df = 1; 766) 17.631*** 19.581***
## ===========================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Chúng ta có thể thấy rằng các ước lượng thu được có khác biệt nhỏ. Hai kết quả hồi quy ứng với hai
bộ số liệu khác nhau này có thể thu được theo một cách thức khác (không hiển thị kết quả) :
Rõ ràng, chúng ta cần một kết quả tổng hợp. Chúng ta có thể sử dụng hàm pool() để thu được kết quả
tổng hợp này:
Ở đây kết quả cuối cùng của được hiển thị ở dòng Pooled coefficients. Chúng ta có thể thấy rằng hệ số
chặn có giá trị là 0.23334487. Con số này chính bằng trung bình cộng các hệ số chặn thu được từ thực
hiện hồi quy hai bộ dữ liệu con:
(0.238760 + 0.227929) / 2
## [1] 0.2333445
Trên đây chúng ta vừa nghiên cứu việc xử lý số liệu thiếu theo một cách thức đơn giản nhất. Trong
thực tế, để xử lý số liệu thiếu người ta thường phải tìm hiểu kĩ nguyên nhân tại sao số liệu bị thiếu,
cũng như các đặc điểm thống kê của biến số bị thiếu để từ đó đưa ra phương pháp chèn số liệu thiếu
một cách phù hợp. Rõ ràng chúng ta không thể điền số 0 vào biến insulin cho bệnh nhân thứ nhất vì
không có cơ thể sống nào có hàm lượng insulin là 0 được. Chúng ta cũng nên, và trong nhiều trường
hợp là không thể loại chúng ra khỏi mẫu. Điền giá trị trống này bằng bao nhiêu hiện là một thách thức
của khoa học thống kê về cả khía cạnh lý thuyết cũng như thực hành.
Trong phạm vi của tài liệu này, thì trình bày cách thức xử lý số liệu thiếu một cách bài bản là không
thể, cũng như không thể bao tất cả những phương pháp phù hợp vốn rất nhạy cảm với từng tình
huống khác nhau. Bạn đọc quan tâm có thể tìm đọc cuốn sách cơ bản “Flexible Imputation of Missing
Data” của Stef van Buuren. Cuốn này sử dụng R nên các bạn sẽ không phải mất nhiều thời gian để
thực hành.
Chương này chúng ta sẽ nghiên cứu các những trường hợp mở rộng của hồi quy hai biến số. Những mô
hình được nghiên cứu là hồi quy qua gốc tọa độ (regression through the origin), các mô hình logarit
và (log-linear model ) bán logarit (semilog models) và một số mô hình khác. Bên cạnh đó chúng ta cũng
nghiên cứu hồi quy chuẩn hóa (reggression on standardized variables), sự thay đổi đơn vị đo của biến
số (units of measurement) cũng như dạng hàm (functional form) của mô hình tuyến tính.
𝑌𝑖 = 𝛽2 𝑋𝑖 + 𝑢𝑖 (1)
Một ví dụ điển hình của hồi quy qua gốc tọa độ là mô hình định giá tài sản vốn CAPM (Capital Asset
Pricing Model) phổ biến trong nghiên cứu tài chính:
Nếu thị trường tài chính là vận hành hiệu quả thì người ta nói rằng phần bù rủi ro kì vọng của chứng
khoán (expected risk premium) đo bằng (ERi - rf ) sẽ bằng tích của hệ số beta nhân với phần bù rủi
ro thị trường (ERm - rf ) và được gọi là lợi nhuận thị trường. Đường thẳng biểu diễn mối quan hệ này
được gọi là đường thị trường chứng khoán (security market line):
Với các nghiên cứu thực chứng trong tài chính, mô hình (2) thường được biểu diễn ở hai dạng sau:
𝑅𝑖 − 𝑟𝑓 = 𝛽𝑖 (𝑅𝑚 − 𝑟𝑓 ) + 𝑢𝑖 (3)
𝑅𝑖 − 𝑟𝑓 = 𝛼𝑖 + 𝛽𝑖 (𝑅𝑚 − 𝑟𝑓 ) + 𝑢𝑖 (4)
Mô hình (4) còn có tên gọi là mô hình thị trường (Market Model). Nếu CAPM là đúng thì αi được kì
vọng là bằng 0.
Cần lưu ý là hệ số R2 của hồi quy qua gốc tọa độ sẽ có thể là một con số âm và không có ý nghĩa trong
việc diễn giải sức mạnh giải thích của mô hình. Thay vì sử dụng công thức truyền thống, hệ số này của
hồi quy qua gốc tọa độ được gọi là r2 thô (raw r2) hay chỉ kí hiệu chỉ là r2 để phân biệt với R2 như ở
một số tài liệu và được tính theo công thức sau:
(∑ 𝑋𝑖 𝑌𝑖 )2
raw 𝑟 2 =
∑ 𝑋𝑖2 ∑ 𝑌𝑖2
Mặc dù r2 tính theo công thức này thỏa mãn 0 ≤ r2 ≤ 1 nhưng chúng ta cũng không thể so sánh một
cách trực tiếp r2 này với R2 được. Khi thực hiện hồi quy qua gốc tọa độ, hầu hết phần mềm (bao gồm
R) sẽ báo cáo r2 này.
Bởi vì những đặc điểm cá biệt này của mô hình chúng ta cần đặc biệt chú ý và thận trọng khi sử dụng
mô hình hồi quy không có hệ số chặn. Trừ khi chúng ta có kì vọng tiên nghiệm (priori expectation)
rất mạnh rằng hệ số chặn là bằng không, chúng ta nên đánh giá mô hình CAPM theo mô hình (4) chứ
không phải (3) và thực hiện các kiểm định cần thiết để chỉ ra rằng hệ số chặn là không có ý nghĩa
thống kê – tức là có thể bỏ hệ số chặn bằng 0 về mặt thống kê (statistically equal to zero).
Chúng ta xét bộ số liệu table6_1.xls trong đó biến X là phần bù rủi ro kì vọng (thể hiện lợi tức trội
hơn so với thị trường) của Afuture còn Y là phần bù rủi ro thị trường (hay lợi nhuận thị trường) từ
năm 1971 đến 1980:
setwd("D:/KTLR")
library(gdata)
dung <- read.xls("table6_1.xls")
head(dung)
## year Y X
## 1 1971 67.5 19.5
## 2 1972 19.2 8.5
## 3 1973 -35.2 -29.3
## 4 1974 -42.0 -26.5
## 5 1975 63.7 61.9
## 6 1976 19.3 45.5
Nếu chúng ta có kì vọng tiên nghiệm mạnh rằng hệ số chặn ở (4) là không tồn tại thì chúng ta có thể
thực hiện hồi quy qua gốc tọa độ:
##
## Call:
## lm(formula = Y ~ 0 + X, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -30.291 -6.007 -0.720 4.484 46.247
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## X 1.0899 0.1916 5.69 0.000298 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 19.54 on 9 degrees of freedom
## Multiple R-squared: 0.7825, Adjusted R-squared: 0.7583
## F-statistic: 32.38 on 1 and 9 DF, p-value: 0.0002981
Có thể thấy hệ số beta β = 1.089 là lớn hơn 1, hay cổ phiếu của Afuture là năng động. Trong tài chính
kết quả này được diễn giải như sau: khi lợi nhuận thị trường tăng 1% thì lợi nhuận của Afuture sẽ
tăng 1.089%.
Nếu chúng ta không có bằng chứng tiên nghiệm trước rằng hệ số chặn bằng không, chúng ta nên sử
dụng (4) – tức là sử dụng mô hình thị trường để đánh giá mối liên hệ giữa lợi nhuận của Afuture và
lợi nhuận thị trường:
##
## Call:
## lm(formula = Y ~ X, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -30.623 -7.166 -1.237 3.585 45.373
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.2797 7.6886 0.166 0.87194
## X 1.0691 0.2383 4.486 0.00204 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 20.69 on 8 degrees of freedom
## Multiple R-squared: 0.7155, Adjusted R-squared: 0.68
## F-statistic: 20.12 on 1 and 8 DF, p-value: 0.00204
Do p-value của hệ số chặn là 0.872 > 5% nên chúng ta chưa có bằng chứng thống kê để bắc bỏ giả
thiết rằng hệ số chặn bằng 0. Cần lưu ý là chúng ta không thể so sánh R2 = 71.55% ở đây với r2 =
78.25% ở trên với nhau được.
Đánh giá sự phụ thuôc của GPD theo GDP theo những đơn vị đo khác nhau ta có:
##
## Call:
## lm(formula = GPDIBL ~ GDPB, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -68.84 -31.82 -4.01 32.47 85.86
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1026.4980 257.5874 -3.99 0.004 **
## GDPB 0.3016 0.0399 7.56 0.000066 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 54.5 on 8 degrees of freedom
## Multiple R-squared: 0.877, Adjusted R-squared: 0.862
## F-statistic: 57.1 on 1 and 8 DF, p-value: 0.0000656
##
## Call:
## lm(formula = GPDIM ~ GDPM, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -68843 -31816 -4008 32471 85856
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1026497.9900 257587.4037 -3.99 0.004 **
## GDPM 0.3016 0.0399 7.56 0.000066 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 54500 on 8 degrees of freedom
## Multiple R-squared: 0.877, Adjusted R-squared: 0.862
## F-statistic: 57.1 on 1 and 8 DF, p-value: 0.0000656
Rõ ràng với các đơn vị đo khác nhau (cùng là tỉ hoặc cùng là triệu) thì các kết quả ước lượng là không
có gì thay đổi. Cụ thể, khi GDP tăng 1 (tỉ hoặc triệu) thì GPD tăng 0.3016 (tỉ hoặc triệu).
Nghĩa là, ý nghĩa và bản chất kinh tế về mối liên hệ giữa các biến số là không thay đổi. Và điều này còn
đúng trong những trường hợp chúng ta sử dụng đơn vị đo theo một kiểu khác như có thể thấy dưới
đây (không hiển thị kết quả):
𝑌𝑖 − 𝑌̅
𝑌𝑖∗ =
𝑆𝑌
𝑋𝑖 − 𝑋̅
𝑋𝑖∗ =
𝑆𝑋
Ở đây biến được chuẩn hóa có kí hiệu * ở trên đầu. Công thức này có nghĩa là để chuẩn hóa, ví dụ,
với biến Y thì chúng ta lấy các quan sát của Y trừ đo trung bình của nó được bao nhiêu chia cho độ
lệch chuẩn của Y (kí hiệu SY).
Trong R, với bộ số liệu được sử dụng ở mục 5.2, thực hiện hồi quy chuẩn hóa được thực hiện như
sau:
##
## Call:
## lm(formula = scale(GPDIBL) ~ scale(GDPB), data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.4696 -0.2170 -0.0273 0.2215 0.5857
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.96e-16 1.18e-01 0.00 1
## scale(GDPB) 9.37e-01 1.24e-01 7.56 0.000066 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.372 on 8 degrees of freedom
## Multiple R-squared: 0.877, Adjusted R-squared: 0.862
## F-statistic: 57.1 on 1 and 8 DF, p-value: 0.0000656
Điểm đáng chú ý mà chúng ta có thể thấy ở đây là khi thực hiện hồi quy chuẩn hóa có hệ số chặn, thì
hệ số chặn luôn bằng 0 và p-value của nó luôn bằng 1. Nghĩa là hồi quy chuẩn hóa, dù ta tuyên bố rõ
ràng có sự xuất hiện của hệ số chặn thì kết quả luôn tương đương với hồi quy qua gốc tọa độ như
chúng ta có thể thấy dưới đây:
##
## Call:
## lm(formula = scale(GPDIBL) ~ 0 + scale(GDPB), data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.4696 -0.2170 -0.0273 0.2215 0.5857
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## scale(GDPB) 0.937 0.117 8.02 0.000022 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.35 on 9 degrees of freedom
## Multiple R-squared: 0.877, Adjusted R-squared: 0.864
## F-statistic: 64.3 on 1 and 9 DF, p-value: 0.0000218
Q = aLαKβ
Với a là một hằng số dương. Lấy ln (logarit tự nhiên) hai vế của phương trình trên ta có:
Trong đó ψ = ln(a).
Trong kinh tế lượng, hàm sản xuất Cobb – Douglas sẽ được viết ở dạng:
Nếu α + β = 1 thì chúng ta có hàm sản xuất có lợi tức không đổi theo quy mô. Nếu tổng này lớn hơn
1 thì chúng ta có hàm sản xuất có lợi tức giảm dần theo quy mô (và ngược lại) và thường được
đánh giá qua các mô hình kinh tế lượng thực nghiệm.
Đặc điểm đáng chú ý của (5) là các hệ số ước lượng có thể thể coi như là những hệ số co giãn
(elasticities). Cụ thể, α là hệ số co giãn của sản lượng theo lao động còn β là hệ số co giãn của sản
lượng theo vốn khi tất cả cá yếu tố khác không đổi.
Để minh họa úng ta xét dữ liệu có tên Table2_1.xls gồm các thông tin về sản lượng (output), lao động
(labor) và vốn (capital) của 50 bang và khu vực hành chính đặc biệt Washington DC trong năm 2005
và thực hiện ước lượng mô hình (5):
##
## Call:
## lm(formula = log(output) ~ log(labor) + log(capital), data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.4564 -0.1211 -0.0532 0.0452 1.2158
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.8876 0.3962 9.81 0.00000000000047 ***
## log(labor) 0.4683 0.0989 4.73 0.00001980879662 ***
## log(capital) 0.5213 0.0969 5.38 0.00000218315931 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.267 on 48 degrees of freedom
## Multiple R-squared: 0.964, Adjusted R-squared: 0.963
## F-statistic: 646 on 2 and 48 DF, p-value: <2e-16
Kết quả này chỉ ra rằng R2 = 96.4% - một con số cao bất thường đối với dữ liệu chéo. Các kết quả
khác còn lại được diễn giải như sau:
Khi tăng lao động lên 1% thì sản lượng sẽ tăng 0.4683%.
Khi tăng vốn lên 1% thì sản lượng tăng 0.5212%.
Hàm sản xuất Dobb- Douglas thu từ mô hình thực nghiệm là Q = 48.79L0.4683K0.5212 .
Ở đây chúng ta thấy rằng α + β = 0.9896 ngụ ý rằng rất có thể hàm sản xuất là lợi tức không đổi theo
quy mô. Nếu α + β thực sự bằng 1 thì α = 1- β và phương trình (5) bằng biến đổi đại số sẽ trở thành:
Mô hình (6) gọi là mô hình bị giới hạn (Restricted Model) còn (5) gọi là mô hình không bị giới hạn
(Unrestricted Model). Chúng ta thực hiện ước lượng mô hình (6):
Mô hình này có nghĩa là nếu tỉ số vốn chia cho lao động tăng 1% thì sản lượng tăng 0.5238%. Chú ý
rằng R2 = 37.9% không thể so sánh được với R2 = 96.4% ở mô hình (5).
Để đánh giá xem α + β có bằng 1 hay không chúng ta sử dụng kiểm định F được tính theo công thức
sau:
Thống kê F tính theo công thức (7) sẽ tuân theo quy luật χ2 với số bật tự do lần lượt là m và n – k.
Nếu F tính theo công thức (7) mà lớn hơn giá trị tới hạn ở ngưỡng được chọn trước thì chúng ta bắc
bỏ giả thiết α + β = 1. Dưới đây chúng ta sẽ thực hiện kiểm định F đã mô tả:
Có thể thấy Fqs = 0.14 < 4.04 ở ngưỡng 5% nên chúng ta có chưa có bằng chứng để bắc bỏ giả thiết
rằng α + β = 1.
Chúng ta có thể thực hiện kiểm định α + β = 1 theo cách khác sử dụng lệnh linearHypothesis() của
gói AER:
library(AER)
linearHypothesis(logatt, "log(labor) + log(capital) = 1") # Cách 1
Do p-value = 0.709 > 5% nên chúng ta chưa có bằng chứng thống kê bắc bỏ giả thiết α + β = 1. Chúng
ta sẽ nghiên cứu kĩ hơn kiểm định sự ràng buộc giữa các hệ số hồi quy trong chương sau.
Trong đó r là tốc độ tăng trưởng, t là thời gian (trong 48 năm) từ năm 1960 đến 2007. Lấy ln hai vế
của (8) ta có:
##
## Call:
## lm(formula = log(rgdp) ~ time, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.09088 -0.01843 0.00526 0.02307 0.05946
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.875662 0.009759 807.0 <2e-16 ***
## time 0.031490 0.000347 90.8 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.0333 on 46 degrees of freedom
## Multiple R-squared: 0.994, Adjusted R-squared: 0.994
## F-statistic: 8.25e+03 on 1 and 46 DF, p-value: <2e-16
Nghĩa là GDP của Mĩ tăng trưởng với tốc độ chừng 3.149% hàng năm. Chúng ta có thể minh họa tốc
độ tăng trưởng của ln(rgdp) theo thời gian:
library(ggplot2)
ggplot(dung, aes(time, log(rgdp))) + geom_line() + geom_point(col = "red")
Một vấn đề là vai trò của chọn trục thời gian t. Như ta thấy bộ số liệu gốc chọn time = 1 ứng với năm
1960, time = 48 ứng với 2007:
View(dung)
Tuy nhiên chúng ta có thể chọn lại các biểu diễn thời gian như sau mà không ảnh hưởng đến kết quả
ước ước lượng: chọn biến mới T từ 1960 đến 2007:
##
## Call:
## lm(formula = log(rgdp) ~ T, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.090879 -0.018426 0.005258 0.023067 0.059459
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -5.381e+01 6.878e-01 -78.24 <2e-16 ***
## T 3.149e-02 3.467e-04 90.82 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.03328 on 46 degrees of freedom
## Multiple R-squared: 0.9945, Adjusted R-squared: 0.9943
## F-statistic: 8248 on 1 and 46 DF, p-value: < 2.2e-16
Ngoại trừ hệ số chặn, tất cả các kết quả khác là không khác nhau. Nguyên nhân là, chẳng hạn, ước
lượng rgdp cho năm 1960 ứng với hai kiểu biến khác nhau lần lượt sẽ là:
Tuy nhiên kết quả của ước lượng rgdp (và tất cả các kết quả khác) vẫn không đổi. Thực vậy, chúng ta
có thể tính rgdp ước lượng cho cả hai tình huống và thấy chúng chính là một:
exp(predict(ahi, dung))
## 1 2 3 4 5 6 7
## 2716.642 2803.549 2893.236 2985.793 3081.310 3179.883 3281.609
exp(predict(loveyou, dung))
## 1 2 3 4 5 6 7
## 2716.642 2803.549 2893.236 2985.793 3081.310 3179.883 3281.609
Tất nhiên kế quả chẳng có thay đổi nếu chúng ta thay T bằng dãy số từ -1 đến -48. Việc tạo biến thời
gian là tùy ý nhưng chúng ta nên chọn sao cho thuận tiện với các phân tích và diễn giải nếu cần. Chẳng
hạn bài tập 3.9 (chương 2) cuốn giáo trình kinh tế lượng của tác giả Nguyễn Thành Cả và Nguyễn
Thị Ngọc Miên từ UEH có yêu cầu sinh viên đặt biến t bắt đầu từ 0 cho bộ số liệu gdp.xls sẽ gây khó
sinh viên và làm méo mó mô hình vì khi thực hiện mô hình có ln(t) thì giá trị ln0 sẽ không xác định.
Và như vậy khi thực hiện trong Eviews hay Stata thì các phần mềm này mặc định bỏ đi một quan sát.
Trong đó T là biến biểu diễn quý theo trình tự thời gian. Như đã phân tích ở mục trên, chúng ta không
nên chọn T bắt đầu từ 0 mà nên lấy T từ 1 trở đi (vì sau này còn có mô hình sử dụng biến lnT nữa) và
thực hiện ước lượng (10) trong R:
dung$T = 1:52
summary(lm(R_GDP ~ T, data = dung))
##
## Call:
## lm(formula = R_GDP ~ T, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -36616 -4533 3220 9444 31939
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 57915.5 4496.7 12.88 <2e-16 ***
## T 1888.5 147.7 12.79 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 15980 on 50 degrees of freedom
## Multiple R-squared: 0.7659, Adjusted R-squared: 0.7612
## F-statistic: 163.6 on 1 and 50 DF, p-value: < 2.2e-16
Kết quả này chỉ ra rằng cứ một năm GDP của Việt Nam sẽ tăng một lượng tuyệt đối là 1888.5 (không
rõ đơn vị là gì vì hai tác giả này không nói). Chúng ta cũng có thể đánh giá hình ảnh về tăng trưởng
theo thời gian:
Dễ dàng thấy rằng tăng trưởng kinh tế của Việt Nam có tính chu kì. Cụ thể, so với các quý còn lại GDP
là cao nhất trong quý 4 và tuân theo quy luật từ quý 1 đến quý 2 thì tăng, rồi lại giảm, rồi lại tăng.
Kiểm định chính thức cho tính chất chu kì này chúng ta sẽ nghiên cứu ở các chương sau.
Cũng có thể tạo ra các hình ảnh động (interactive graph) như sau:
Mô hình tuyến tính – logarit, trong tình huống với bộ số liệu này, là mô hình kiểu như sau:
Trong đó, biến LNK là logarit cơ số tự nhiên của KinhNghiem. Nhưng, trước khi lấy logarit chúng ta
phải đánh giá khoảng giá trị của KinhNghiem vì rằng phép lấy logarit không tồn tại nếu có giá trị bé
hơn hoặc bằng 0. Sử dụng lệnh range() ta có:
## [1] 0 46
Như vậy kinh nghiệm có giá trị từ 0 đến 46. Dưới đây là lệnh chỉ thị cho R: (1) chỉ lấy các quan sát
mà biến KinhNghiem dương, (2) tạo biến mới LKN, và (3) thực hiện hồi quy cho mô hình (11):
dung <- subset(dung, dung$KinhNghiem > 0) # Những quan sát có KinhNghiem > 0.
dung$LKN <- log(dung$KinhNghiem) # Tạo biến LNK = ln(KinhNghiem)
summary(lm(TienLuong ~ LKN, data = dung))
##
## Call:
## lm(formula = TienLuong ~ LKN, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.8794 -0.9070 0.2159 0.8715 2.6079
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.89542 0.22239 35.503 < 2e-16 ***
## LKN 0.33301 0.08366 3.981 9.15e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.354 on 236 degrees of freedom
## Multiple R-squared: 0.06292, Adjusted R-squared: 0.05895
## F-statistic: 15.85 on 1 and 236 DF, p-value: 9.154e-05
Chúng ta có thể vẽ đường hồi quy cho mô hình với khoảng tin cậy 95% :
Ý nghĩa của các ước lượng thu được là nếu kinh nghiệm tăng lên 1% thì mức lương sẽ tăng
0.33301/100 = 0.003331 (%). 1% của một năm chừng 3.65 ngày hay xấp xỉ 3 ngày 16 tiếng. Nói cách
khác, kinh nghiệm làm việc tăng 3 ngày 16 tiếng thì mức lương tăng 0.003331 (%). Cho nên, mô hình
này có thể sẽ diễn đạt hơn nếu thay đổi đơn vị của biến kinh nghiêm từ năm sang tuần hoặc ngày.
library(readxl)
dung <- read_excel("Table2_8.xls")
Ở mô hình này, biến độc lập là nghịch đảo của tổng chi tiêu. Thực hiện ước lượng mô hình này chúng
ta có:
##
## Call:
## lm(formula = sfdho ~ I(expend^-1), data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.2989 -0.0421 -0.0112 0.0323 0.4461
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.07726 0.00401 19.3 <2e-16 ***
## I(expend^-1) 1331.33806 63.95713 20.8 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.0697 on 867 degrees of freedom
## Multiple R-squared: 0.333, Adjusted R-squared: 0.332
## F-statistic: 433 on 1 and 867 DF, p-value: <2e-16
Hệ số của b có ý nghĩa thống kê và dương ngụ ý rằng khi tổng chi tiêu hộ gia đình tăng lên thì mức chi
cho thực phẩm sẽ giảm đi. Chúng ta cũng có thể vẽ đường hồi quy cho mô hình với khoảng tin cậy
95% cho các ước lượng:
theme_set(theme_minimal())
dung %>%
ggplot(aes(x = expend, y = sfdho)) +
geom_point(alpha = 0.3) +
geom_smooth(formular = y ~ 1/x, method = "loess")
##
## Call:
## lm(formula = R_GDP ~ T + I(T^2), data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -40137 -5080 1458 8630 26614
##
## Coefficients:
Nếu như mô hình (10) ở mục 5.4.3 nói rằng khi t tăng 1 (quý) thì GDP tăng 1888.5 và con số này là
không đổi bất kể ở quý nào thì kết quả ước lượng ở mô hình (13) có nghĩa hoàn toàn khác. Thực vậy,
lấy đạo hàm hai vế của (13) ta có:
𝑑(𝑅𝐺𝐷𝑃 )
= 𝑏 + 2𝑐𝑇 = 1124.38 + 25.06𝑇
𝑑𝑇
Điều này có nghĩa là mức tăng trưởng theo quý sẽ không phải là một con số không đổi cho tất cả các
quý mà là phụ thuộc vào mốc thời gian được chọn và là một hàm của thời gian T.
Có hai điểm chúng ta cần chú ý đối với mô hình đa thức. Thứ nhất, đây là mô hình tuyến tính tham số
chứ không phải tuyến tính dạng hàm. Thứ hai, sử dụng mô hình đa thức sẽ tồn tại nguy cơ đa cộng
tuyến ở mức cao vì, chẳng hạn, biến T và T2 thường tương quan rất chặt với nhau.
Mục tiêu của chương này là hướng dẫn các thao tác thực hành trong R cho mô hình hồi quy bội, kiểm
định Wald về sự ràng buộc của các hệ số hồi quy, ước lượng khoảng cho một hệ thức của hệ số hồi quy.
6.1 Thực hiện hồi quy bội trong R và khoảng tin cậy cho các hệ số
Từ mục 6.1 đến 6.3 chúng ta sẽ nghiên cứu bộ số liệu ch2vd5.WF1. Tôi mặc định rằng các bạn đã biết
cách chỉ thị cho R đọc file Eviews này thành một data.frame với tên gọi dung. Giả sử chúng ta đánh
giá tác động của thu nhập (TN) và tài sản (TS) lên chi tiêu (CT) bằng mô hình sau:
setwd("D:/KTLR")
library(hexView)
dung <- readEViews("ch2vd5.WF1", as.data.frame = TRUE)
hoiquyboi <- lm(data = dung, CT ~ TN + TS)
summary(hoiquyboi)
##
## Call:
## lm(formula = CT ~ TN + TS, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -16.026 -10.504 0.373 5.784 32.274
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 18.860180 8.832144 2.135 0.041010 *
## TN 0.791224 0.015991 49.481 < 2e-16 ***
## TS 0.015818 0.003984 3.970 0.000414 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 12.27 on 30 degrees of freedom
## Multiple R-squared: 0.9995, Adjusted R-squared: 0.9995
## F-statistic: 3.296e+04 on 2 and 30 DF, p-value: < 2.2e-16
Khoảng tin cậy của hệ số hồi quy, ví dụ, của 𝛽2 được tính theo công thức:
Tất nhiên chúng ta có thể áp dụng công thức này cho các hệ số beta khác. Với α = 5% chúng ta có thể
tính khoảng tin cậy 95% cho cả ba hệ số hồi quy:
confint(hoiquyboi)
## 2.5 % 97.5 %
## (Intercept) 0.822534473 36.89782483
## TN 0.758567036 0.82388141
## TS 0.007681386 0.02395467
R sẽ mặc định tính khoảng tin cậy 95% như lệnh chúng ta vừa thực hiện. Nếu muốn tìm khoảng tin
cậy 99% cho các hệ số (không hiển thị kết quả):
6.2 Khoảng tin cậy cho một biểu thức của hệ số hồi quy
Khoảng tin cậy cho, chẳng hạn, biểu thức (aβ2 + bβ3) được tính theo công thức sau:
(𝑎𝛽̂2 + 𝑏𝛽̂3 ) − 𝑡𝛼/2 𝑠𝑒(𝑎𝛽̂2 + 𝑏𝛽̂3 ) ≤ 𝑎𝛽2 + 𝑏𝛽3 ≤ (𝑎𝛽̂2 + 𝑏𝛽̂3 ) + 𝑡𝛼/2 𝑠𝑒(𝑎𝛽̂2 + 𝑏𝛽̂3 )
Trong đó:
Với mô hình OLS thu được, giả sử cần tìm khoảng tin cậy 95% cho (−𝛽̂2 + 10𝛽̂3 ). Trước hết tìm
các giá trị của var(𝛽̂2 ), var(𝛽̂3 ), và cov(𝛽̂2 , 𝛽̂3 ):
vcov(hoiquyboi)
## (Intercept) TN TS
## (Intercept) 78.00677420 7.375351e-02 -2.395591e-02
## TN 0.07375351 2.556997e-04 -6.231694e-05
## TS -0.02395591 -6.231694e-05 1.587315e-05
## [1] -0.7465574
ct
## [1] -0.5195304
Như vậy khoảng tin cậy 95% cho (−𝛽̂2 + 10𝛽̂3 ) là (-0.746; -0.519).
6.3 Kiểm định Wald về sự ràng buộc của các hệ số hồi quy
Kiểm định Wald về sự ràng buộc của các hệ số hồi quy áp dụng cho cặp giả thuyết H0: mβ2 + nβ3 = p;
H1: mβ2 + nβ3 # p trong đó m, n, và p là các số thực.
Chúng ta có thể kiểm tra giả thuyết rằng β2 =50β3 (tức là m=1, n = -50, p=0) như sau:
library(AER)
linearHypothesis(hoiquyboi, "TN = 50*TS")
Giá trị Pr(>F) = 0.998 > 5% nên chúng ta có bằng chứng thống kê để chấp nhận giả thuyết gốc.
Chúng ta có thể kiểm tra giả thuyết rằng β2 =25β3 +0.4 (tức là m=1, n = -25, p=0.4) như sau:
Giá trị Pr(>F) = 0.971 > 5% nên chúng ta có bằng chứng thống kê để chấp nhận giả thuyết gốc.
6.4 Kiểm định F về việc đồng thời bằng không của nhiều hệ số hồi quy
Đây là nhóm các kiểm định cho cặp giả thuyết dạng H0: β2i + β2j = 0; H1: β2i + β2j # 0. Chúng ta sử dụng
kiểm định F cho những tình huống như vậy.
Từ mục 5.4 trở đi chúng ta sẽ sử dụng bộ số liệu ch5bt10.WF1. Chúng ta chỉ thị cho R đọc file dữ liệu
dưới dạng một data.frame với tên dung. Chúng ta xét mô hình sau:
Giả sử chúng ta muốn kiểm định cặp giả thuyết H0: β23 + β24 = 0; H1: β23 + β24 # 0. Nếu giả thuyết Ho
đúng thì mô hình (2) trở thành:
Lúc này mô hình (2) gọi là mô hình không bị giới hạn (Unrestricted Model) còn mô hình (3) gọi là mô
hình bị giới hạn (Restricted Model). Để thực hiện kiểm định F chúng ta làm theo ba bước sau.
Bước thứ nhất chạy cả hai mô hình (2) và (3) nhằm thu được R2ur và R2r trong đó R2ur và R2r lần lượt
là R2 của mô hình (2) và (3).
Bước thứ hai chúng ta tính thống kê F theo công thức sau:
2
(𝑅𝑢𝑟 − 𝑅𝑟2 )/𝑚
𝐹= 2 )/(𝑛 − 𝑘)
(1 − 𝑅𝑢𝑟
Trong đó m là số biến bị bỏ ở mô hình (3) so với mô hình (2), n là số quan sát, k là số biến số trong
mô hình không bị giới hạn. Trong tình huống của chúng ta thì n = 32, m=2, k = 4, α = 5% (mặc định),
còn Rur và Rr lần lượt là R2 của mô hình không bị và bị giới hạn.
Bước cuối cùng chúng ta so sánh thống kê F tính ở bước thứ hai với Fα(m,n-k). Nếu F > Fα(m,n-k) thì
chúng ta có bằng chứng thống kê bắc bỏ Ho, nếu không chúng ta có bằng chứng thống kê chấp nhận
H1.
Chúng ta tuân theo ba bước này thực hiện kiểm định này trong R như sau (chỉ hiển thị phần kết quả
chứa R2):
Ta tính thống kê F:
## [1] 0.46313
## [1] 3.340386
Do 0.463 < 3.340 nên chúng ta chưa có bằng chứng thống kê để bắc bỏ H0.
Chúng ta có thể tính kiểm định F cách khác trong R nhanh hơn và chắc chắn không gặp sai sót như
sau:
anova(luonggh, luong)
Chúng ta vẫn thu được F = 0.463 như ở trên. Và cách này cũng không cần bạn phải tìm F0.05(2,28-4) mà
chỉ cần so sánh Pr(>F) = 0.634 với 5%. Do Pr(>F) = 0.634 > 5% nên chúng ta chưa có bằng chứng
thống kê bắc bỏ Ho.
Chúng ta có thể sử dụng kiểm định Wald trong tình huống này:
Chúng ta cũng có thể tính thống kê F thông qua RSS(R) và RSS(U) của mô hình bị giới hạn và không
bị giới hạn theo công đã biết ở mục 5.4.1:
anova(luong)
anova(luonggh)
6.5 Mối liên hệ hình chữ U ngược giữa giáo dục và mức lương
Trong kinh tế học lao động người ta thường quan tâm đến mô hình sau về tác động của giáo dục
(EDUC) lên logarit cơ số tự nhiên của lương (lnWAGE):
Các lý thuyết của kinh tế học lao động chỉ ra rằng β3 < 0, β2 > 0 đồng thời hai hệ số hồi quy này phải
có ý nghĩa thống kê với ngụ ý về mối quan hệ hình chữ U ngược giữa EDUC và ln(WAGE). Nghĩa là,
ban đầu số năm học tăng dẫn đến mức lương cũng tăng. Nhưng khi năm học đạt một ngưỡng nào đó,
tác động của số năm đi học lên mức lương lại ngược lại. Nói cách khác, vượt qua ngưỡng này thì mức
lương tuân theo quy luật cận biên giảm dần so với số năm đi học.
Trong R chúng ta thực hiện ước lượng cho (3) như sau:
##
## Call:
## lm(formula = log(WAGE) ~ EDUC + I(EDUC^2) + MEDUC + SSIBS, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.25091 -0.10462 0.05347 0.07849 0.15292
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.335686 0.822291 10.137 1.06e-10 ***
## EDUC -0.049861 0.122870 -0.406 0.688
## I(EDUC^2) 0.002788 0.004501 0.620 0.541
## MEDUC -0.004551 0.006258 -0.727 0.473
## SSIBS -0.011027 0.012458 -0.885 0.384
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1147 on 27 degrees of freedom
## Multiple R-squared: 0.1711, Adjusted R-squared: 0.04835
## F-statistic: 1.394 on 4 and 27 DF, p-value: 0.2626
Ở đây các bạn chú ý phải gõ I(EDUC^2) để tạo biến mới EDUC2 trong R. Kết quả cho thấy rằng hệ số
của EDUC2 là dương – ngược lại những phát biểu của kinh tế học lao động. Nguyên nhân có thể là mô
hình còn thiếu một số biến số quan trọng. Chúng ta sẽ nghiên cứu vấn đề này ở các chương sau.
6.6 hồi quy chuẩn hóa và vấn đề so sánh tác động của các biến độc lập
Một câu hỏi đặt ra là, ví dụ với mô hình hồi quy ở mục 6.1, là so sánh mức độ ảnh hưởng (hay tác
động) của các biến độc lập lên biến phụ thuộc. Có thể thấy mức chênh lệch giữa hệ số hồi quy của biến
TN và TS là 50 (0.791224 so với 0.015818) nên thường đưa ra kết luận sai trái rằng tác động của thu
nhập lên biến CT mạnh gấp 50 lần so với tác động của biên TS lên CT. Để so sánh đúng vai trò, mức
độ ảnh hưởng của các biến độc lập lên biến phụ thuộc chúng ta phải sử dụng hồi quy chuẩn hóa
(Gujarati & Porter, 2009). Với tình huống ở mục 6.1, thực hiện hồi quy chuẩn hóa trong R:
##
## Call:
## lm(formula = scale(CT) ~ scale(TN) + scale(TS), data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.02876 -0.01885 0.00067 0.01038 0.05791
##
## Coefficients:
0.92690 / 0.07437
## [1] 12.46336
Căn cứ vào hệ số hồi quy chuẩn hóa, có thể thấy tác động của biến TN so với tác động của biến TS lên
CT thực tế là chừng 12.5 lần. Để hiểu rõ hơn kết luận này chúng ta cần đọc được ý nghĩa của hệ số hồi
quy chuẩn hóa. Cụ thể ở đây, ví dụ, căn cứ vào hệ số hồi quy chuẩn hóa của TN có thể nói khi TN tăng
1 sai số chuẩn (a standard deviation increase) thì CT tăng 0.9269.
Nhắc lại rằng trong hồi quy chuẩn hóa, hệ số chặn luôn bằng 0 với Pr(>|t|) luôn bằng 1. Cũng cần chú
ý rằng các tiêu chí đánh giá mô hình như các giá trị Pr(>|t|) (trừ hệ số chặn), R2 hay thống kê F đều
không thay đổi. Vì hồi quy chuẩn hóa thực chất là hồi quy không có hệ số chặn nên có thể thu được
kết quả trên theo một cách khác như sau (không hiển thị kết quả):
6.7 Kiểm định LM, LR trong trường hợp kích cỡ mẫu là lớn
Nếu phần dư là phân phối chuẩn thì các thống kê t và F được sử dụng với mọi kích thước mẫu. Tuy
nhiên, nếu phần dư không tuân theo quy luật chuẩn thì thống kê t và F sẽ không tuân theo quy luật
Student, Fisher với kích thước mẫu là bé do vậy sử dụng thống kê t và F có thể không áp dụng được
trong tình huống này. Nhưng nếu kích thước mẫu là lớn thì chúng ta có thể sử dụng thống kê t và F
bất kể phần dư có phân phối chuẩn hay không.
Với kích thước mẫu là lớn, ngoài việc sử dụng thống kê F như đã được trình bày ở các mục trên chúng
ta có thể sử dụng: (1) Wald Test, (2) Likelihood Ratio Test, và (3) Lagrange Multiplier Test. Ba kiểm
định này không những sử dụng được cho các mô hình tuyến tính mà còn được sử dụng cho các mô
hình phi tuyến tính.
Để đảm bảo vấn đề kích cỡ mẫu là lớn, trong mục này chúng ta sử dụng bộ dữ liệu ch4bt8.wf1 với
935 quan sát. Con số này trong các nghiên cứu định lượng thực tế thì vẫn chưa được coi là lớn tuy
nhiên với mục đích minh họa chúng ta tạm sử dụng bộ dữ liệu này. Chúng ta nhập bộ dữ liệu này vào
R như sau:
Để thực hiện Likelihood Ratio Test (LR Test) trước hết chúng ta cài đặt và sử dụng package có tên
lmtest bằng cách gõ install.packages(“lmtest”) tại cửa sổ lệnh của R. Sau đó chúng ta thực hiện ước
lượng cho hai mô hình trên như sau:
mohinh1 <- lm(data = trang, WAGE ~ EDUC + EXPER + FEDUC + MEDUC + IQ)
mohinh2 <- lm(data = trang, WAGE ~ EDUC + EXPER + IQ)
lrtest(mohinh1, mohinh2)
Chúng ta thấy giá trị của Pr(>Chisq) = 0.00288 < 5% (tương ứng với χ2qs = 11.697) nên chúng ta có
bằng chứng thống kê để bắc bỏ giả thiết rằng hai hệ số của FEDUC và MEDUC đồng thời bằng 0.
Chúng ta có thể tính trực tiếp LR Test bằng cách sử dụng thống kê λ (Gujarati & Porter, 2009) mà
không cần sử dụng package lmtest. Giá trị λ được tính theo công thức sau:
Trong đó ULLF và RLLF lần lượt là giá trị Log Likehood của mô hình không giới hạn (mô hình 1) và
mô hình bị giới hạn (mô hình 2). Với n đủ lớn thì thống kê λ tuân theo phân phối χ2 với số bậc tự do
bằng số biến bị loại khỏi mô hình 1. Trong một số phần mềm như Eviews, khi chạy các mô hình hồi
quy thì nó luôn hiển thị ULLF và RLLF. Trong R chúng ta có thể gọi giá trị ULLF như sau:
logLik(mohinh1)
logLik(mohinh2)
Thay vào công thức (4) chúng ta tính ngay trong R như sau:
## [1] 11.6972
Giá trị 11.6972 này chính là giá trị ở cột Chisq. Bước cuối cùng là chúng ta cần so sánh λ = 11.6972
này với χ20.95 với số bậc tự do trùng với số biến bị loại bỏ ở mô hình 2 (hay df = 2). Chúng ta tính hai
giá trị này trong R:
qchisq(0.95, 2)
## [1] 5.991465
Do giá trị 11.6972 > 5.99 nên λ thuộc miền bắc bỏ. Nghĩa là chúng ta có bằng chứng thống kê để bắc
bỏ giả thiết rằng hai hệ số hồi quy của FEDUC và MEDUC đồng thời bằng 0.
Chú ý rằng các nhà kinh tế lượng – thống kê đã chứng minh rằng (4) có thể viết lại như sau:
Trong đó RRSS và URSS lần lượt là tổng phần dư bình phương của mô hình 2 (mô hình bị giới hạn) và
mô hình 1 (mô hình không bị giới hạn) còn n là số quan sát. Nếu chúng ta sử dụng (5) để tính toán thì
chúng ta cũng rút ra cùng một kết luận mà không cần biết các giá trị Log Likehood của các mô hình.
Người ta cũng chứng minh được hai thống kê Wald (Wald Test) và Lagrange Multiplier (LM Test)
tuân theo phân phối χ2 như sau:
(𝑛 − 𝑘)(RRSS − URSS)
Wald Statistic (W) = ~ χ2𝑟
URSS
(𝑛 − 𝑘 + 𝑟)(RRSS − URSS)
Lagrange Multiplier Statistic (LM) = ~ χ2𝑟
RRSS
Trong đó k là số biến số độc lập trong mô hình không bị giới hạn còn r là số biến số bị loại bỏ từ mô
hình bị giới hạn, n là số quan sát.
Người ta cũng chỉ ra mối liên hệ giữa ba kiểm định (hay ba thống kê) này là:
W ≥ LR ≥ LM (8)
Nghĩa là khi n lớn đến vô cùng thì ba thống kê này hội tụ về cùng một giá trị. Nói cách khác, với n là
bé thì một giả thuyết có thể bị bắc bỏ bởi kiểm định Wald nhưng không bị bắc bỏ bởi kiểm định LM.
Chúng ta có thể tính trực tiếp kiểm định (thống kê) Wald theo như (6) sau:
## [1] 11.70765
Giá trị của thống kê Wald = 11.7076 cao hơn không đáng kể so với λ = 11.6972 mà chúng ta đã tính ở
trên. Ngoài ra 11.7076 > χ20.95;2 = 5.99 nên chúng ta bắc bỏ giả thuyết rằng hai hệ số của FEDUC và
MEDUC đồng thời bằng 0.
## [1] 11.58696
Tương tự ta cũng thấy 11.587 > χ20.95;2 = 5.99 nên chúng ta bắc bỏ giả thuyết rằng hai hệ số của FEDUC
và MEDUC đồng thời bằng 0.
Một lần nữa chúng ta có thể kiểm tra lại bất đẳng thức (8) về mối liên hệ giữa ba thống kê này với ngụ
ý rằng W là thống kê Wald, LR là thống kê λ, và LM là thống kê Lagrange Multiplier:
Tất nhiên các bạn hoàn toàn có thể sử dụng kiểm định F như đã trình bày ở mục 5.4 của chương này.
6.8 Gợi ý trả lời một sô bài tập chương 2 thuộc cuốn giáo trình của NEU
Chúng ta sẽ trả lời một số khía cạnh lý thuyết, thực tiễn, cũng như thực hành trong R với các bài tập
từ 2.4 đến 2.6 (trang 120 và 131 sách giáo trình của NEU). Theo quan điểm cá nhân của tôi, nguồn
gốc số liệu đáng tin cũng như giải thích ở mức tối thiểu các biến là cần thiết cho nghiên cứu kinh tế
lượng. Rất tiếc sách của NEU nhiều bộ số liệu thì không có (nhưng sách vẫn nói có) lại còn không có
thông tin về dữ liệu. Vì lý do này, để trả lời cho câu hỏi của các bài tập từ 2.4 đến 2.6 chúng ta nghiên
cứu bộ số liệu hoàn toàn tương tự có tên WAGE1.DTA lấy từ sách của Wooldridge (2013).
Trước hết cần nhắc lại một lý thuyết khá phổ biến về quy luật cận biên giảm dần của số năm đi học
hoặc kinh nghiệm của kinh tế học lao động (Labour Economics). Theo lý thuyết này thì mức lương sẽ
tăng cùng với số năm đi học hoặc kinh nghiệm nhưng sau đó mối quan hệ này đổi chiều nếu số năm
đi học hoặc kinh nghiệm vượt một ngưỡng nào đó. Để kiểm định lý thuyết kinh tế này, chúng ta có
thể xét mô hình sau:
Trong đó wage là mức lương của người lao động, exper là số năm kinh nghiệm. Nếu lý thuyết này là
đúng thì chúng ta kì vọng rằng hệ số hồi quy của exper là dương và hệ số hồi quy của exper2 là âm.
Chúng ta sử dụng bộ dữ liệu WAGE1.DTA để đánh giá mô hình này:
setwd("D:/KTLR")
library(haven)
trang <- read_stata("WAGE1.DTA")
names(trang)
options(scipen = 3)
trang$exper2 <- trang$exper^2 # Tạo ra biến exper2 = exper*exper
qols <- lm(wage ~ exper + exper2, data = trang)
summary(qols)
## Call:
## lm(formula = wage ~ exper + exper2, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.5916 -2.1440 -0.8603 1.1801 17.7649
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.7254058 0.3459392 10.769 < 2e-16 ***
## exper 0.2981001 0.0409655 7.277 1.26e-12 ***
## exper2 -0.0061299 0.0009025 -6.792 3.02e-11 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.524 on 523 degrees of freedom
## Multiple R-squared: 0.09277, Adjusted R-squared: 0.0893
## F-statistic: 26.74 on 2 and 523 DF, p-value: 8.774e-12
Căn cứ vào kết quả này chúng ta có thể dấu của các hệ số hồi quy là phù hợp với kì vọng và lại còn có
ý nghĩa thống kê. Chúng ta có thể biểu diễn đường cong hồi quy thu được như sau:
library(ggplot2)
ggplot(trang, aes(x = exper, y = wage)) +geom_point()
+ stat_smooth(method = "lm", formula = y ~ x + I(x^2), size = 1)
Đến đây nhiều bạn có thể tự hài lòng vì những kết quả tốt đẹp này. Nhưng hãy khoan. Câu hỏi đặt ra
ở đây là mô hình thu được ở trên, dù phù hợp với lý thuyết mà kinh tế học lao động đề xuất nhưng
liệu nó có đúng trong thực tế? Thực vậy, nếu theo kêt quả thu được của mô hình thì những mức lương
sẽ tăng cùng với kinh nghiệm nhưng khi số năm kinh nghiệm này đến giới hạn 24.4 (con số này tìm
được bằng cách lấy giá trị tuyệt đối của 2β2/β1 ) thì mức lương của anh ta giảm. Liệu điều này có phù
hợp với thực tế?
Câu trả lời là không. Có thể rằng mức lương giảm cùng với số năm kinh nghiệm nhưng cái ngưỡng đó
phải lớn hơn con số 24.4. Thực vậy, cứ cho rằng bạn học NEU ra trường đúng hạn là 22 tuổi. Tại tuổi
46 (tức sau 24 năm đi làm) chính là phong độ cao nhất trong sự nghiệp kiếm tiền của bạn, chẳng có
lý do gì để tin rằng thu nhập của bạn từ độ tuổi 47 trở đi lại giảm. Một vấn đề nữa là chúng ta cần lưu
ý đến tỉ lệ khá lớn của những người có số năm kinh nghiệm lớn hơn ngưỡng 24.4. Dưới đây là những
câu lệnh tạo ra một biến mới có tên nkn (viết tắt của năm kinh nghiệm) trong đó gán nhãn A cho
những người có số năm kinh nghiệm bé hơn 24.4 và B cho những người còn lại.
# Tạo biến mới nkn và gán A cho nhóm có exper < 24.4 và >= 24.4:
trang <- trang %>% mutate(nkn = case_when(exper < 24.4 ~ "A",
exper >= 24.4 ~ "B"))
# Xem tỉ lệ của mỗi nhóm:
round(prop.table(table(trang$nkn)) * 100, digits = 2)
##
## A B
## 72.05 27.95
Như vậy, có thể thấy nhóm B chiếm tầm 28% - một tỉ lệ lớn. Con số này tương đương với 147 người
có số năm kinh nghiệm lớn hơn 24.4 và mức lương của anh ta đang giảm theo số năm kinh nghiệm.
Rõ ràng, để mô hình của chúng ta phù hợp với thực tế hơn, chúng ta cần điều chỉnh mô hình.
Một cách khác để mổ xẻ những kết quả thu được từ mô hình là xem tương quan giữa mức lương và
năm kinh nghiệm của từng nhóm. Câu lệnh dưới đây tạo ra hai data frame tương ứng với từng nhóm
và tính tương quan giữa hai biến số này:
## [1] 0.3063432
## [1] -0.2640143
Có thể thấy với nhóm A thì tương quan này là dương còn nhóm B thì ngược lại. Kết quả này, cũng như
kết hợp với kết quả hồi quy thu được tạo cơ sở cho chúng ta có thể đề xuất một cách tiếp cận khác để
nghiên cứu quy luật cận biên giảm dần của số năm kinh nghiệm:
Trong đó wage là mức lương của người lao động, exper là số năm còn nkn là biến giả. Cách tiếp cận
biến giả này được đề cập chi tiết ở chương 6. Kết quả hồi quy của mô hình này là:
##
## Call:
## lm(formula = wage ~ exper + nkn + exper * nkn, data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.5358 -2.0412 -0.9489 1.1095 17.6242
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.23791 0.31787 13.332 < 2e-16 ***
## exper 0.15585 0.02683 5.809 1.09e-08 ***
## nknB 7.75661 1.55560 4.986 8.39e-07 ***
## exper:nknB -0.31581 0.04960 -6.367 4.24e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.536 on 522 degrees of freedom
## Multiple R-squared: 0.08846, Adjusted R-squared: 0.08322
## F-statistic: 16.89 on 3 and 522 DF, p-value: 1.758e-10
Kết quả này có nghĩa là với nhóm A thì mối liên hệ giữa năm kinh nghiệm và mức lương là wage =
4.238 +0.156exper còn đối với nhóm B là wage = (4.237 + 7.75)+(0.155 – 0.316)exper = 11.99 –
0.160exper. Chúng ta có thể vẽ đường hồi quy cho cả hai nhóm:
trang %>%
ggplot(aes(exper, wage, colour = nkn)) + geom_point() +
geom_smooth(method = "lm") + theme_minimal() +
theme(legend.position = "top")
Phương trình hồi quy đối với hai nhóm ở trên chúng ta có thể có được bằng một cách khác:
ols1 <- nhomA %>% lm(wage ~ exper, data = .) # Chạy OLS cho nhóm A.
ols2 <- nhomB %>% lm(wage ~ exper, data = .) # Chạy OLS cho nhóm B.
library(stargazer)
stargazer(ols1, ols2,
title = "Mo Hinh Ung Voi Hai Nhom Kinh Nghiem", type = "text")
##
## Mo Hinh Ung Voi Hai Nhom Kinh Nghiem
## ===================================================================
## Dependent variable:
## -----------------------------------------------
## wage
## (1) (2)
## -------------------------------------------------------------------
## exper 0.156*** -0.160***
## (0.025) (0.049)
##
## Constant 4.238*** 11.995***
## (0.296) (1.771)
##
## -------------------------------------------------------------------
## Observations 379 147
## R2 0.094 0.070
## Adjusted R2 0.091 0.063
## Residual Std. Error 3.287 (df = 377) 4.113 (df = 145)
## F Statistic 39.044*** (df = 1; 377) 10.864*** (df = 1; 145)
## ===================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Chúng ta thấy rằng, nếu chưa tính đến khía cạnh phù hợp thực tế hay không thì cả hai mô hình đề mô
tả cùng một thứ: khi exper bé hơn 22.4 thì wage tăng cùng exper nhưng vượt qua ngưỡng 22.4 này
thì quan hệ này đảo chiều. Một câu hỏi mới phát sinh là mô hình 1 có R2 = 0.093 cao hơn mô hình 2
có R2 = 0.088 (chừng 5% cao hơn) thì có nghĩa mô hình 1 tốt hơn?
Rõ ràng, để trả lời câu hỏi trên chúng ta so sánh trực tiếp bằng cách sử dụng tiêu chí R2 có thể chưa
phù hợp. Trong tình huống này chúng ta có thể sử dụng tiêu chí MSE để so sánh và đánh giá hai mô
hình. Chú ý rằng MSE được tính theo công thức đã biết sau:
𝑛
1 2
MSE = ∑(𝑌̂𝑖 − 𝑌𝑖 )
𝑛
𝑖=1
Từ công thức này chúng ta thấy một môt hình tốt là một mô hình có MSE thấp hơn so với mô hình
còn lại vì điều này có nghĩa là các giá trị dự báo của mô hình sát với giá trị thực tế hơn.
Dưới đây là các lệnh thực hiện so sánh hai mô hình dựa trên tiêu chí MSE:
Có thể thấy mô hình 2 có giá trị MSE cao hơn chừng 0.05% - một con số rất bé. Như vậy nếu căn cứ
vào đồng thời cả hai tiêu chí thì mô hình 1 là mô hình tốt hơn với mẫu đã cho. Tuy nhiên cần phải
nhắc lại rằng: kết luận này chỉ đúng với mẫu cụ thể này mà thôi, chưa chắc đúng nếu mẫu là khác.
Ngoài ra bạn cũng cần lưu ý rằng những giá trị MSE, R2 ở cả hai mô hình là tỉ lệ sai sót huấn luyện.
Về vấn đề lựa chọn và cả so sánh các mô hình các bạn nên nhớ câu “all models are wrong, but some
are useful” của George Box (nhà thống kê – kinh tế lượng nổi tiếng người Anh và cũng là người cùng
với Jenkins xây dựng Box-Jenkins Methods cho phân tích chuỗi thời gian). Thực vậy, tất cả các mô
hình đều sai, chỉ có một số (mô hình) là hữu ích. Như trong tình huống của chúng ta mặc dù cả hai mô
hình đều đưa ra bằng chứng thống kê rằng quy luật cận biên giảm dần và do đó ủng hộ những lý
thuyết của kinh tế học lao động nhưng nếu xét trên khía cạnh thực tế thì chúng đều “vô nghĩa” ở một
mức độ nào đó. Thực vậy, khó có thể tin rằng sau gần 25 năm làm việc, mức lương lại giảm dần cùng
với kinh nghiệm có được. Trong thực tế, mức lương của người lao động chỉ có tăng theo thời gian
cùng với kinh nghiệm. Điều này gợi ý rằng nếu các lý thuyết của kinh tế học lao động là đúng thì
ngưỡng mà tại đó mức lương tuân theo quy luật cận biên giảm dần phải lớn hơn con số 24.4 nhiều.
Một vấn đề khác cho việc trả lời câu hỏi trong số các mô hình cạnh tranh nhau, mô hình nào tốt hơn
ngoài căn cứ vào một số tiêu chí thống kê (R2, MSE chẳng hạn) và mức độ phù hợp với thực tiễn thì
cũng còn một tiêu chí quan trọng khác đó là khả năng diễn giải của mô hình. Chẳng hạn, ở mô hình 1
nếu chúng ta cho thêm biến số bình phương của lg(exper) vào thì R2 của mô hình mới chắc chắn cao
hơn (và trong nhiều tình huống, mức tăng của R2 là đáng kể). Tuy nhiên chúng ta có thể thấy rằng
chúng ta rất khó diễn đạt (hay giải thích) cho các kết quả thu được, thậm chí trong nhiều tình huống
là không thể diễn đạt được những kết quả đó. Do vậy, lựa chọn giữa các mô hình cạnh tranh, ngoài rất
nhiều các yếu tố cần nhắc, chúng ta phải lưu ý đến khả năng diễn giải của mô hình. Một mô hình mà
chúng ta có thể diễn giải một cách thuyết phục các kết quả thu được nên được ưu tiên lựa chọn mặc
dù nếu căn cứu vào một số tiêu chí khác, nó có thể thua kém so với các mô hình cạnh tranh.
Như đã nói ở trên, mặc dù với tình huống mẫu là toàn bộ 526 quan sát thì chúng ta chỉ ra rằng, căn cứ
vào các tiêu chí đánh giá sai sót huấn luyện thì mô hình 1 là tốt hơn mô hinh 2. Tuy nhiên, chúng ta
chưa có bằng chứng thống kê cho kết luận này, vì sự khác biệt này chỉ đúng với một mẫu, chưa chắc
đã đúng với mẫu khác.
Để đưa ra bằng chứng thống kê có hay không có sự khác biệt về chất lượng của hai mô hình, dưới đây
là các R code cho đánh giá hai tiêu chí này với mẫu huấn luyện (train) và mẫu kiểm định (test) được
chia theo tỉ lệ 50:50 cho 1000 tình huống khác nhau với vòng lặp 1000 lần. Điểm khác ở đây là không
giống như trên, chúng ta sẽ đánh giá dựa trên sai sót kiểm định với tiêu chí lựa chọn là MSE. Vì rằng
với mục đích dự báo lương (wage) thì sai sót kiểm định sẽ là phù hợp hơn (James et al., 2013). Chúng
ta thực hiện bằng vòng lặp for loop:
MSE1 <- c()
MSE2 <- c()
set.seed(29)
for (i in 1:1000){
train <- trang[sample(526, 0.5*526), ]
test <- trang[-sample(526, 0.5*526), ]
qols <- train %>% lm(wage ~ exper + exper2, data = .)
love <- train %>% lm(wage ~ exper + nkn + exper*nkn, data = .)
## MSE1 MSE2
## Min. : 7.542 Min. : 7.62
## 1st Qu.:11.470 1st Qu.:11.59
## Median :12.449 Median :12.56
## Mean :12.411 Mean :12.51
## 3rd Qu.:13.368 3rd Qu.:13.48
## Max. :16.454 Max. :16.34
Chúng ta thấy rằng có sự khác biệt về MSE giữa hai mô hình. Chú ý rằng có tất cả 1000 cặp MSE1 và
MSE2 ứng với hai mô hình với trung bình lần lượt là 12.411 và 12.510. Tuy nhiên để chứng minh rằng
sự khác biệt này có ý nghĩa thống kê hay không, chúng ta phải sử dụng kiểm định t để có kết luận
chính thức. Do p-value = 0.089 > 5% nên chúng ta có thể thấy rằng sự khác biệt về chất lượng dự báo
của hai mô hình là không có ý nghĩa thống kê:
t.test(trang2611$MSE1, trang2611$MSE2)
##
## Welch Two Sample t-test
##
## data: trang2611$MSE1 and trang2611$MSE2
## t = -1.7002, df = 1998, p-value = 0.08924
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -0.2217237 0.0158003
## sample estimates:
## mean of x mean of y
## 12.41148 12.51444
Ví dụ này một lần nữa nhấn mạnh nguyên lý suy nghĩ một cách thống kê trong nghiên cứu: mô hình
1 tốt hơn mô hình 2 chỉ trong 1 tình huống. Để khẳng định có sự khác biệt về chất lượng trong, chẳng
hạn, dự báo của hai mô hình thì bạn phải đưa ra bằng chứng thống kê cho kết luận của mình. Nói cách
khác, bạn phải có bằng chứng rằng sự khác biệt ấy có tính phổ quát, tức đúng cho nhiều trường hợp,
chứ không chỉ mới đúng với một tình huống của mẫu mà thôi.
Chương này chúng ta sẽ nghiên cứu các mô hình hồi quy mà một số hay tất cả biến giải thích là các biến
định tính (Qualitative Variables). Các mô hình hồi quy như vậy còn được biết đến với cái tên là các mô
hình hồi quy biến giả (Dummy Variable Regression Models). Sự thưc thực thì biến giả có tác động thực
sự đến biến phụ thuộc như chúng ta sẽ thấy. Do vậy, tôi ưa thích hơn sử dụng cụm từ biến định tính thay
vì biến giả. Vì lí do này, hai danh từ trên được sử dụng thay thế cho nhau mà không có sự khác biệt về ý
nghĩa.
7.1 Bản chất của biến giả và các mô hình hồi quy ANOVA
Trong phân tích hồi quy, biến phụ thuộc không chỉ phụ thuộc vào biến giải thích là biến định lượng
mà còn phụ thuộc vào cả các biến định tính (hay còn gọi là biến giả - dummy variables). Chẳng hạn,
mức lương theo giờ Y không chỉ phụ thuộc vào số năm đi học X (biến định lượng) mà còn phụ thuộc
vào cả giới tính (biến định tính). Thậm chí, có những mô hình mà biến giải thích hoàn toàn là các
biến định tính – những mô hình như vậy có tên gọi là các mô hình ANOVA (ANOVA Models) . Chúng
ta nghiên cứu về một số mô hình như vậy ngay sau đây. Chương này chúng ta sẽ sử dụng bộ dữ liệu
ch4bt8.wf1 với 935 quan sát được cung cấp bởi khoa toán NEU và đã được sử dụng ở mục 5.7 ở
chương 5.
7.1.1 mô hình ANOVA với chỉ một biến giải thích là biến giả duy nhất
Chúng ta xét mô hình sau:
Trước hết chúng ta đọc dữ liệu và thực hiện một số phân tích sơ bộ:
library(hexView)
trang <- readEViews("D:/KTLR/ch4bt8.wf1", as.data.frame = TRUE)
# Đánh giá sơ bộ về từng nhóm chủng tộc:
library(tidyverse)
theme_set(theme_minimal())
trang %>%
group_by(BLACK) %>%
count() %>%
ggplot(aes(BLACK, n)) +
geom_col() +
geom_text(aes(label = n), color = "white", hjust = 1.2) +
coord_flip()
## BLACK
## 0 1 Sum
## 0.8716578 0.1283422 1.0000000
Như vậy có 87.16% lao động là người da trắng, 12.83 % là người Mĩ gốc Phi. Những tỉ lệ này có thể
được biểu thị bằng Bar Plot như trên.
Như chúng ta đã biết, mức lương trung bình ở Mĩ có thể khác biệt giữa các nhóm chủng tộc. Chúng ta
có thể đánh giá sơ bộ như sau:
trang %>%
mutate(BLACK = as.factor(BLACK)) %>%
ggplot(aes(BLACK, WAGE)) +
geom_boxplot()
Chúng ta có nhận định trực giác rằng mức lương của người da trắng là cao hơn. Chúng ta thực hiện
phân tích hồi quy cho mô hình (1):
##
## Call:
## lm(formula = WAGE ~ BLACK, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -875.65 -269.15 -52.65 209.35 2087.35
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3490.65 13.85 251.977 < 2e-16 ***
## BLACK -254.81 38.67 -6.589 7.37e-11 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 395.5 on 933 degrees of freedom
## Multiple R-squared: 0.04447, Adjusted R-squared: 0.04345
## F-statistic: 43.42 on 1 and 933 DF, p-value: 7.37e-11
Dựa vào kết quả hồi quy này ta có WAGE = 3490.64785 -254.80619BLACK. Phương trình này có ý
nghĩa như sau:
1. Khi BLACK = 0 (không phải là người Mĩ gốc Phi) thì WAGE = 3490.64785. Đây chính là mức
lương trung bình tháng của nhóm lao động da trắng, người gốc Tây Ban Nha, người gốc Á.
2. Khi BLACK = 1 mức lương trung bình của người Mĩ gốc Phi luôn thấp hơn nhóm còn lại là
254.80619. Không những thế, hệ số hồi quy này còn có ý nghĩa thống kê ở mức cao. Điều này
cũng có nghĩa là chúng ta có bằng chứng thống kê rất mạnh để đưa ra kết luận rằng mức lương
trung bình của người Mĩ gốc Phi thấp hơn đáng kể so với nhóm còn lại.
Chú ý rằng kết luận mà chúng ta vừa có được có thể thu được bằng cách khác với kiểm định t:
t.test(WAGE ~ BLACK)
##
## Welch Two Sample t-test
##
## data: WAGE by BLACK
## t = 8.3373, df = 192.73, p-value = 1.42e-14
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 194.5269 315.0854
## sample estimates:
## mean in group 0 mean in group 1
## 3490.648 3235.842
Kết quả chỉ ra rằng mức lương của nhóm 0 (da trắng) là 3490.54, của nhóm 1 (da màu) là 3235.84 và
sự khác biệt này có ý nghĩa thống kê do p-value = 1.42⨉10-14 là rất bé.
Chúng ta đánh giá sơ bộ bằng hình ảnh về mức lương biến đổi ra sao giữa vùng miền và chủng tộc:
trang %>%
mutate(BLACK = as.factor(BLACK), SOUTH = as.factor(SOUTH)) %>%
ggplot(aes(BLACK:SOUTH, WAGE)) +
geom_boxplot()
Hình ảnh này cho thấy, ví dụ, người da trắng và ở khu vực phi miền nam (box plot màu xanh) có mức
lương khác biệt so với người da màu và ở miền nam (box plot màu vàng). Để củng cố nhận định này
cũng như thực hiện các phân tích sâu hơn ta thực hiện hồi quy trong R cho mô hình (2):
Dựa vào kết quả hồi quy này ta có WAGE = 3520.13 -221.66BLACK - 98.89SOUTH. Phương trình này
có ý nghĩa như sau:
1. Khi BLACK = 0 và SOUTH = 0 (không phải là người Mĩ gốc Phi và không ở khu vực miền nàm)
thì WAGE = 3520.13. Đây chính là mức lương trung bình tháng của nhóm lao động người phi
da đen và không ở miền nam.
2. Khi BLACK = 1 và SOUTH = 1 mức lương trung bình của người Mĩ gốc Phi lại còn sống ở miền
Nam (tệ phân biệt chủng tộc rất gay gắt ở các ban miền Nam và là một trong những nguyên
nhân của nội chiến Mĩ) luôn thấp hơn (221.66+98.89).
3. Khi BLACK = 1 và SOUTH = 0 mức lương trung bình của người Mĩ gốc Phi không sống ở miền
Nam được cải thiện hơn chút ít khi mức lương của anh ta chỉ thấp hơn nhóm còn lại 221.66.
4. Khi BLACK = 0 và SOUTH = 1 mức lương trung bình của người Mĩ da trắng (và các màu da
khác) thấp hơn 98.89.
5. Tất cả 4 kết luận trên là có ý nghĩa thống kê vì tất cả các hệ số hồi quy đều có ý nghĩa thống kê
ở mức cao.
Diễn giải mô kết quả của mô hình cũng tương tự như trên với chú ý rằng hệ số hồi quy β4 cho
BLACK*SOUTH là -113.44. Điều này có nghĩa là nếu một quan sát mà anh ta vừa là người da màu, vừa
là dân miền nam thì mức lương của anh ta sẽ thấp hơn so với nhóm còn lại là (155 + 83 + 113). Chúng
ta có thể liên hệ tình huống này cho nghiên cứu ở Việt Nam theo kiểu lao động vừa là người dân tộc
thiểu số, lại ở vùng Tây Bắc – địa bàn khó khăn nhất của cả nước.
7.2. Mô hình có chứa cả biến giả lẫn biến định lượng – mô hình ANCOVA
Mô hình ANOVA – mô hình chỉ chứa toàn biến định tính như chúng ta vừa nghiên cứu ở trên thường
rất phổ biến trong các nghành xã hội học, tâm lý học, giáo dục, marketing nhưng lại không quá phổ
biến trong nghiên cứu kinh tế. Trong kinh tế, chúng ta thường gặp hơn những mô hình vừa chứa các
biến định tính, vừa chứa cả các biến định lượng. Những mô hình này có tên là mô hình ANCOVA
(ANCOVA Models).
Mô hình này chỉ ra rằng nếu mọi thứ khác là như nhau thì mức lương của người ở khu vực thành thị
sẽ cao hơn so với mức lương của người ở khu vực khác 158 USD và sự khác biệt này có ý nghĩa thống
kê.
Việc diễn giải các mô hình (4) và (5) các bạn có thể xem ở trang 182, 183 sách giáo trình kinh tế lượng
NEU. Một nhận xét quan trọng ở đây là nếu lao động thuộc khu vực thành thị thì tác động đến việc gia
tăng thêm một năm học đến mức lương là mạnh hơn so với lao động thuộc khu vực khác. Thực vậy,
theo kết quả này thì gia tăng thêm một năm học, nếu là lao động ở thành thị thì mức lương sẽ tăng
(38.91 + 26.14) nhưng nếu là lao động ở khu vực khác thì mức lương chỉ tăng 38.91. Chi tiết hơn về
vấn đề này chúng ta sẽ nghiên cứu ngay sau đây.
7.2.3 Vai trò của biến định tính và kiểm định Chow
Giả sử ngoài trình độ học vấn, chúng ta muốn đánh giá xem yếu tố vùng miền, cụ thể là khu vực thành
thị (URBAN = 1) và khu vực phi thành thị (URBAN = 0) tác động như thế nào đến mức lương và tác
động này có ý nghĩa thống kê hay không chúng ta có thể vận dụng cách tiếp cận dưới đây do Chow
(1960) đề xuất. Trước hết chúng ta tách hai nhóm lao động như sau: giả sử các lao động ở khu vực
phi thành thị được sắp xếp từ 1 đến m còn các lao động thành thị được sắp xếp từ m+1 đến n. Sau đó
chúng ta xét hai mô hình hồi quy sau:
Nếu chúng ta đưa ra bằng chứng thống kê cho thấy γ1 = λ1 và γ2 = λ2 thì chúng ta có thể gộp (6) và (7)
thành một phương trình duy nhất:
Chúng ta có thể sử dụng kiểm định F theo cách tiếp cận của Chow (công thức 4.3.6 trang 186 sách
giáo trình NEU) để kiểm tra khả năng gộp (6) và (7) thành duy nhất mô hình (8) như sau:
## [1] 18.82677
## [1] 3.005393
Do Fqs = 18.827> F0.95(2,931) = 3.000 nên chúng ta bắc bỏ giả thuyết gốc rằng γ1 = λ1 và γ2 = λ2 . Nói
cách khác, tác động của giáo dục lên mức lương là khác biệt giữa hai nhóm lao động nông thôn và
thành thị.
7.2.4 Sử dụng biến định tính thay thế cho kiểm định Chow
Để chỉ ra nhược điểm của kiểm định Chow (hay cách tiếp cận kiểu Chow) chúng ta hãy phân tích mối
liên hệ giữa hai mô hình (6) và (7) căn cứ vào các khả năng có thể xẩy ra giữa các hệ số hồi quy tương
ứng. Giữa hai mô hình này có 4 khả năng sau có thể xẩy ra (hình 1):
1. Cả hệ số chặn lẫn hệ số góc là như nhau. Trường hợp này được gọi là các hồi quy trùng lặp
(coincident regressions). Trong tình huống này thì γ1 = λ1 và γ2 = λ2 và chúng ta chỉ cần sử
dụng duy nhất mô hình (8).
2. Hệ số chặn là khác nhưng hệ số góc như nhau. Trong tình huống này thì γ1 # λ1 và γ2 = λ2 .
Nghĩa là chúng ta có các hồi quy song song (parallel regressions).
3. Hệ số chặn giống nhau nhưng hệ số góc thì khác. Lúc này ta có các hồi quy chung hệ số chặn
(concurrent regressions) với γ1 = λ1 và γ2 # λ2.
4. Cả hệ số chặn lẫn hệ số góc khác nhau. Lúc này ta có các hồi quy khác biệt (dissimilar
regressions) ứng với tình huống γ1 # λ1 và γ2 # λ2.
Quan phân tích ở trên chúng ta thấy rõ ràng hạn chế của kiểm định Chow: sử dụng kiểm định Chow có
thể chỉ ra rằng mô hình (6) và (7) là khác biệt – tức có sự thay đổi về cấu trúc nhưng nó không chỉ ra
sự khác biệt này có nguyên nhân là do sự khác biệt về hệ số chặn, hệ số góc, hay cả hai loại hệ số này.
Chúng ta có thể sử dụng cách tiếp cận biến giả nhằm xử lý hạn chế của kiểm định Chow bằng cách xét
mô hình sau:
Sự khác biệt về mức lương giữa hai nhóm, theo Gujarati (1970, 2009) là tồn tại nếu xẩy ra một trong
ba tình huống sau:
1. β3 có ý nghĩa thống kê và β4 không có ý nghĩa thống kê. Trong tình huống này chúng ta parallel
regressions.
2. β3 không có ý nghĩa thống kê và β4 có ý nghĩa thống kê. Trong tình huống này chúng ta có
concurrent regressions.
3. Cả β3 và β4 có ý nghĩa thống kê. Trong tình huống này chúng ta có dissimilar regressions.
Ngược lại, nếu cả ba tình huống trên không thỏa mãn (tức là cả β3 và β4 không có ý nghĩa thống kê)
thì chúng ta có thể lấy (9) làm mô hình mô tả chung cho tác động của học vấn lên mức lương của hai
nhóm lao động mà không tính đến yếu tố vùng miền. Nghĩa là chúng ta có thể bỏ qua nhân tố khu vực
cũng như tương tác giữa nhân tố này với EDUC trong việc đánh giá mức lương. Tất cả điều này được
giải quyết trọn vẹn chỉ bởi chạy duy nhất mô hình (9).
Căn cứ vào kết quả này ta thấy β3 không có ý nghĩa thống kê còn β4 có ý nghĩa thống kê. Nói cách khác
chúng ta có thể thấy đường hồi quy cho nhóm cư dân đô thị là dốc hơn so với đường hồi quy của cư
dân nông thôn (trường hợp 3). Chúng ta có thể minh họa đường hồi quy cho hai nhóm lao động như
sau:
trang %>%
mutate(Region = case_when(URBAN == 1 ~ "Urban",
URBAN != 1 ~ "Country")) %>%
ggplot(aes(EDUC, WAGE, color = Region)) + geom_point() +
geom_smooth(method = "lm", se = FALSE) + theme_minimal() +
labs(x = NULL, y = NULL,
title = "The Relationship between Wage and Education",
caption = "Data Source: GSO")
Chúng ta có thể xem các thông tin vắn tắt về bộ dữ liệu này:
summary(CPS1988)
Ở đây biến định tính khu vực (region) có bốn cặp phạm trù đại diện cho 4 khu vực địa lý của nước Mĩ.
Giả sử chúng ta xét mô hình ANCOVA đơn giản thường được nghiên cứu bởi kinh tế học lao động như
sau:
Căn cứ vào kết quả chúng ta thấy rằng nếu các yếu tố khác không đổi, khi kinh nghiệm = 0 thì mức
lương của lao động vùng northeast là 5.56$ một giờ (chính là hệ số chặn Intercept) trong khi mức
lương của người vùng south là thấp nhất và thua kém các lao động vùng northeast (lấy làm chuẩn) là
0.19$. Ngoài ra các hệ số hồi quy thu được cũng có dấu phù hợp với các lý thuyết về kinh tế học lao
động cũng như bối cảnh ở nước Mĩ: mối quan hệ hình chữ U ngược giữa kinh nghiệm và mức lương
cũng như mức lương cao hơn hẳn của vùng đông bắc so với các khu vực khác.
Như đã phân tích về mối quan hệ hình chữ U ngược giữa kinh nghiệm và mức lương chúng ta có thể
minh họa mối quan hệ này bằng hình ảnh trong R như sau:
Chú ý dạng đường cong này là chung cho cả 4 nhóm lao động ứng với 4 khu vực địa lý. Nếu lấy
northeast làm chuẩn thì ba đường cong cho ba nhóm lao động còn lại chỉ là phép tịnh tiến xuống dưới
của hình 3 mà thôi.
Nghĩa là với mô hình (13) chúng ta chỉ chạy mô hình này ứng với các số liệu về wage, experience thu
được từ người lao động ở vùng northeast. Làm tương tự như vậy đối với ba nhóm lao động còn lại.
Để thực hiện hồi quy cho 4 mô hình trên (ứng với 4 nhóm dữ liệu con) chúng ta thực hiện trong R
như sau:
Thực ra chúng ta đã thực hiện kiểu hồi quy với nhóm dữ liệu con như vậy ở mục 7.2.3. Điểm khác biệt
ở đây là ở mục 7.2.3 thì biến số URBAN = 0 hoặc 1 và cả 0 và 1 đều là biến dạng số học trong khi biến
region nhận giá trị kí tự (character). Vì lý do này chúng ta phải sử dụng dấu “ ” trong câu lệnh.
Các bạn có thể xem kết quả hồi quy cho nhóm lao động đến từ northeast:
summary(nor)
## Call:
## lm(formula = log(wage) ~ experience + I(experience^2), data = CPS1988,
## subset = (region == "northeast"))
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.63780 -0.34942 0.04541 0.39147 2.71906
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.606e+00 1.801e-02 311.31 <2e-16 ***
## experience 7.893e-02 1.907e-03 41.40 <2e-16 ***
## I(experience^2) -1.518e-03 4.044e-05 -37.54 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6047 on 6438 degrees of freedom
## Multiple R-squared: 0.2151, Adjusted R-squared: 0.2148
## F-statistic: 881.9 on 2 and 6438 DF, p-value: < 2.2e-16
Chúng ta cũng thấy rằng số quan sát ở mô hình (13) là 6438+3 = 6441. Đây chính là số lao động từ
vùng northeast được khảo sát. Chúng ta có thể kiểm tra lại:
summary(region)
Tất nhiên chúng ta có thể sử dụng gói stargazer để trình bày hoặc so sánh các ước lượng OLS thu
được cho 4 nhóm.
Liên hệ với tình huống nghiên cứu mà chúng ta đã đề cập ở mục 4.8 có thể thấy số năm kinh nghiệm
mà vượt qua đó mức lương giảm là xấp xỉ 26 (đối với vùng northeast). Làm tương tự với ba vùng còn
lại các bạn có thể thấy điểm turning point này là gần như nhau. Để giải thích kết quả này xem có phù
hợp thực tế hay không cần các bạn cân nhắc nhiều vấn đề cũng như hiểu chi tiết về thị trường lao
động ở Hoa Kì thời điểm năm 1988.
Trong R chúng ta có thể biểu diễn 4 đường cong hồi quy cho 4 mô hình trên:
CPS1988 %>%
ggplot(aes(x = experience, y = log(wage))) +
geom_point(alpha = 0.05) +
stat_smooth(method = "lm",
formula = y ~ x + I(x^2),
size = 1, se = FALSE) +
facet_wrap(~ region)
(Hình 4. Mối liên hệ hình chữ U ngược giữa kinh nghiệm và mức lương ứng với 4 vùng)
Cũng có thể biểu diễn cả 4 đường cong hồi quy này trên cùng một hình (không hiển thị hình):
CPS1988 %>%
ggplot(aes(x = experience, y = log(wage), colour = region)) +
geom_point(alpha = 0.1) +
stat_smooth(method = "lm",
formula = y ~ x + I(x^2),
size = 1, se = FALSE)
Ở mục trên chúng ta đã thực hiện hồi quy một cách lần lượt cho 4 nhóm đến từ bốn vùng khác nhau.
Thực tế, tất cả các câu lệnh dài dòng trên có thể làm nhanh gọn hơn nhiều. Đây là một thế mạnh của
R khi nó có thể thực hiện hồi quy với biến giả nhiều phạm trù:
##
## Call:
## lm(formula = log(wage) ~ region * experience + region * I(experience^2),
## data = CPS1988)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.6378 -0.3725 0.0509 0.4158 4.1966
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.606e+00 1.876e-02 298.814 < 2e-16 ***
## regionmidwest -2.176e-01 2.595e-02 -8.385 < 2e-16 ***
## regionsouth -1.747e-01 2.474e-02 -7.060 1.71e-12 ***
## regionwest -1.875e-01 2.722e-02 -6.888 5.79e-12 ***
## experience 7.893e-02 1.986e-03 39.737 < 2e-16 ***
## I(experience^2) -1.518e-03 4.213e-05 -36.029 < 2e-16 ***
## regionmidwest:experience 9.792e-03 2.772e-03 3.533 0.000412 ***
## regionsouth:experience -3.792e-03 2.593e-03 -1.462 0.143632
## regionwest:experience 5.345e-03 2.881e-03 1.855 0.063606 .
## regionmidwest:I(experience^2) -1.109e-04 5.951e-05 -1.864 0.062367 .
## regionsouth:I(experience^2) 9.547e-05 5.477e-05 1.743 0.081322 .
## regionwest:I(experience^2) -4.714e-05 6.179e-05 -0.763 0.445509
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.63 on 28143 degrees of freedom
## Multiple R-squared: 0.2257, Adjusted R-squared: 0.2254
## F-statistic: 745.9 on 11 and 28143 DF, p-value: < 2.2e-16
Ở đây northeast được lấy làm chuẩn. Với gợi ý này các bạn hãy so sánh những kết quả thu được với,
chẳng hạn, câu lệnh summary(nor) ở trên.
Thay vì gán cho BLACK = 0 với ý nghĩa không phải là người Mĩ gốc Phi và BLACK = 1 là người Mĩ gốc
Phi bạn hoàn toàn có thể gán BLACK = 1 để mô tả không phải người Mĩ gốc Phi và BLACK = -1 là người
Mĩ gốc Phi. Dưới đây là R code thực hiện chạy mô hình (1) với các đổi biến mới:
trang$BLACK[trang$BLACK == 1] <- -1
trang$BLACK[trang$BLACK == 0] <- 1
hehe <- lm(WAGE ~ BLACK, data = trang)
summary(hehe)
##
## Call:
## lm(formula = WAGE ~ BLACK, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -875.65 -269.15 -52.65 209.35 2087.35
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3363.24 19.33 173.951 < 2e-16 ***
## BLACK 127.40 19.33 6.589 7.37e-11 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 395.5 on 933 degrees of freedom
## Multiple R-squared: 0.04447, Adjusted R-squared: 0.04345
## F-statistic: 43.42 on 1 and 933 DF, p-value: 7.37e-11
Dựa vào kết quả hồi quy này ta có WAGE = 3363.24 +127.40BLACK. Nếu bạn không là người Mĩ gốc
Phi thì lương trung bình là 3363.24 + 127.40 =3490.64. Tính toán tương tự (cũng như so sánh các
tiêu chí khác, từ kiểm định F đến R2) các bạn thấy rằng ý nghĩa của mô hình chẳng có gì thay đổi cả
ngoại trừ một số điểm thuộc hình thức bề ngoài.
Một vấn đề nữa cần lưu ý là bản chất của biến định tính. Không giống như một số phần mềm khác, R
cho phép một biến định tính được gán bằng một trong hai cách: (1) hoặc là gán số cho biến định tính,
hoặc (2) gán kí tự. Để minh họa điều này chúng ta trở lại với bộ số liệu dữ liệu ch4bt8.wf1.
Bộ dữ liệu này có nhiều biến định tính. Chẳng hạn biến BLACK có hai giá trị là số nguyên 0 ứng với
người đa trắng và 1 ứng với người da màu. Mặc dù mang giá trị là số nhưng đây không phải là biến
định lượng. Với biến định lượng, chúng ta thường dùng kí hiệu kí tự để biểu diễn để thể hiện rõ hơn
bản chất của biến. Lệnh dưới đây cho phép chúng ta tạo một một biến mới có tên là chungtoc trong
đó white ứng với người da trắng, black ứng với người da màu. Đương nhiên ý nghĩa của hai biến
BLACK và chung toc là như nhau:
Tất nhiên, kết quả hồi quy như ở mục 7.1.1 là không có gì thay đổi nếu ta sử dụng biến giả này (không
hiển thị kết quả):
Điều này một lần nữa nhắc nhở các bạn về ý nghĩa thực sự của những biến định tính nằm ẩn sau
những con số. Ví dụ này cũng cho thấy R có thể xử lý linh hoạt biến định tính bất kể chúng được gán
chữ số hay kí tự - một lợi thế mà các phần mềm khác không có.
7.6 Sử dụng biến định tính cho hồi quy từng khúc và phân tích mùa vụ
Phần này chúng ta nghiên cứu việc ứng dụng kĩ thuật biến giả (biến định tính) cho một số phân tích
kinh tế thường thấy.
Trong đó, savings là tiết kiệm, income là thu nhập còn giaidoan là biến định tính chỉ khoảng thời gian.
Cụ thể, giaidoan = A ứng với khoảng thời gian nghiên cứu từ năm 1981 trở về trước, giaidoan = B ứng
với khoảng thời gian nghiên cứu từ 1982 đến 1995.
Do bộ dữ liệu gốc chưa có biến giả giaidoan nên trước hết, chúng ta tạo biến này với mô tả như trên.
Dưới đây là lệnh đọc dữ liệu và tạo biến:
library(gdata)
dung <- read.xls("table9_2.xls")
head(dung)
tail(dung)
dung$giaidoan[dung$year <= 1981] <- "A" # Tạo biến cho giai đoạn trước 1981
dung$giaidoan[dung$year > 1981] <- "B" # Tạo biến cho giai đoạn từ 1982.
head(dung)
tail(dung)
Chúng ta có thể đánh giá sơ bộ bằng hình ảnh về hành vi của tiết kiệm ứng với hai giai đoạn như sau:
library(ggplot2)
ggplot(dung, aes(income, savings, colour = giaidoan)) + geom_point()+
geom_smooth(method = "lm", se = FALSE) + theme_bw()
Có vẻ như những chính sách kinh tế mới này có ảnh hưởng to lớn đến hành vi tiết kiệm. Cụ thể, đường
hồi quy ở giai đoạn B (từ năm 1982 đến 1995) là ít dốc hơn giai đoạn trước. Tuy nhiên đây mới chỉ là
nhận định ban đầu. Để có bằng chứng thống kê chúng ta thực hiện hồi quy cho mô hình (17)
##
## Call:
## lm(formula = savings ~ giaidoan + income + giaidoan * income,
## data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -38.729 -14.777 -1.398 11.689 50.535
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.01612 20.16483 0.050 0.960266
## giaidoanB 152.47855 33.08237 4.609 0.000136 ***
## income 0.08033 0.01450 5.541 1.44e-05 ***
## giaidoanB:income -0.06547 0.01598 -4.096 0.000477 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 23.15 on 22 degrees of freedom
## Multiple R-squared: 0.8819, Adjusted R-squared: 0.8658
## F-statistic: 54.78 on 3 and 22 DF, p-value: 2.268e-10
Chúng ta thấy rằng hệ số hồi quy của giaidoan*income là -0.06547 và có ý nghĩa thống kê ở mức 1%
nên chúng ta có bằng chứng thống kê xác nhận giả thuyết rằng các hộ gia đình từ năm 1982 trở về
sau tiết kiệm ít hơn (hay chi tiêu dùng nhiều hơn) giai đoạn trước.
6.7.1 Tính chất mùa vụ trong phân tích kinh tế sử dụng biến định tính
Nhiều chuỗi dữ liệu kinh tế có tính chất chu kì (seasonal pattern). Chẳng hạn như CPI ở Việt Nam có
xu hướng tăng vào những quý cuối năm. Một ví dụ khác là doanh thu bán của tủ lạnh rõ ràng cũng có
tính chu kì. Chúng ta hãy nghiên cứu doanh thu theo quý của tủ lạnh (biến FRIG) được lưu ở bộ dữ
liệu table9_3.xls trong 8 năm liên tiếp (từ 1978 đến 1985), tức là dữ liệu trải dài trong thời gian 32
quý. Trước hết ta đọc bộ dữ liệu này:
Vì chúng ta nhận định rằng doanh thu của tủ lạnh là khác biệt giữa các quý, trong khi bộ dữ liệu gốc
này chưa có những biến định tính thể hiện doanh thu ứng với các quý nên chúng ta cần tạo ra các biến
giả này trước hết:
dung$quy1 <- rep(c(1, 0, 0, 0), 8) # Tạo biến giả ứng với quý 1.
dung$quy2 <- rep(c(0, 1, 0, 0), 8) # Tạo biến giả ứng với quý 2.
dung$quy3 <- rep(c(0, 0, 1, 0), 8) # Tạo biến giả ứng với quý 3.
dung$quy4 <- rep(c(0, 0, 0, 1), 8) # Tạo biến giả ứng với quý 4.
dung$t <- 1:32 # Tạo biến t ứng với 32 quý.
head(dung) # Xem kết quả của việc tạo biến giả.
Chúng ta có thể minh họa doanh thu của tủ lạnh theo thời gian như sau:
Hình ảnh này cho thấy rằng doanh thu về tủ lạnh cao nhất sẽ là quý 3, thấp nhất là quý 4 và có vẻ như
quy luật này được lặp lại hàng năm.
Để chắc chắn hơn cho nhận định này, chúng ta xét mô hình hồi quy sau:
##
## Call:
## lm(formula = FRIG ~ quy1 + quy2 + quy3, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -300.75 -130.81 51.88 104.91 231.50
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1160.00 59.99 19.336 < 2e-16 ***
## quy1 62.12 84.84 0.732 0.47009
## quy2 307.50 84.84 3.625 0.00114 **
## quy3 409.75 84.84 4.830 4.42e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 169.7 on 28 degrees of freedom
## Multiple R-squared: 0.5318, Adjusted R-squared: 0.4816
## F-statistic: 10.6 on 3 and 28 DF, p-value: 7.908e-05
Chúng ta thấy rằng nếu lấy quý 4 làm gốc, thì doanh thu trung bình của quý này là 1160 còn doanh
thu trung bình của quý 3 là cao hơn 490.75. Đáng chú ý là hệ số hồi quy của quy3 có ý nghĩa thống kê
nên chúng ta có thể nói kết luận rằng doanh thu trung bình tủ lạnh cao nhất ở quý 3.
Nếu đưa vào biến giả quy4 vào mô hình thì chúng ta sẽ mắc bẫy biến giả (dummy variable trap).
Chương này chúng ta sẽ nghiên cứu về hiện tượng đa cộng tuyến (tiếng Anh là Multicollinearity hoặc
Collonearity) cũng như cách xử lý hiện tượng này bằng một số giải pháp xử lí hiện tượng đa cộng
tuyến.
X2 X3 X4
10 50 52
15 75 75
18 90 97
24 120 129
30 150 152
Chúng ta có thể nhập bộ dữ liệu này vào R dưới dạng một data.frame với tên gọi ct:
## x2 x3 x4
## 1 10 50 52
## 2 15 75 75
## 3 18 90 97
## 4 24 120 129
## 5 30 150 152
Chúng ta có thể thấy rằng thấy rằng X3=5X2 (cộng tuyến hoàn hảo). Nói theo ngôn ngữ thống kê thì
tương quan giữa X3 và X2 bằng 1 còn tương quan gữa X3 và X4 gần bằng 1 (cộng tuyến phi hoàn hảo)
như chúng ta có thể thấy dưới đây:
cor(ct)
## x2 x3 x4
## x2 1.0000000 1.0000000 0.9958817
## x3 1.0000000 1.0000000 0.9958817
## x4 0.9958817 0.9958817 1.0000000
Ở đây trường hợp của X3 và X2 gọi là cộng tuyến hoàn hảo (Perfect Collinearity) còn tình huống của
X3 và X4 gọi là cộng tuyến không hoàn hảo (Imperfect Collinearity). Theo Gujarati & Porter (2009),
hiện tượng đa cộng tuyến gây ra những hậu quả sau:
1. Các ước lượng OLS vẫn có tính chất BLUE nhưng sai số chuẩn của các ước lượng này rất lớn
dẫn đến ước lượng khoảng tin cậy là không chính xác.
2. Do khoảng tin cậy là rất rộng nên chúng ta có thể thất bại trong việc bắc bỏ giả thuyết rằng
một hệ số hồi quy nào đó là bằng 0.
3. Một hoặc nhiều thống kê t trong mô hình không có ý nghĩa trong khi R2, giá trị thống kê F có
thể rất cao.
4. Các ước lượng OLS và sai số chuẩn của chúng đạc biệt nhạy cảm với một sự thay đổi nhỏ của
số liệu.
5. Thêm một biến số có tương quan cao với một biến bất kì có ở mô hình đã chọn có thể làm thay
đổi rất lớn các giá trị ước lượng của các biến số khác trong mô hình.
Theo Montgomery & Peck(1975), hiện tượng đa cộng tuyến có thể xẩy ra vì những nguyên nhân sau:
1. Phương pháp thu thập dữ liệu. Chẳng hạn như chọn mẫu với một khoảng nhỏ các giá trị cho
biến độc lập.
2. Những hạn chế về mô hình hoặc tổng thể được chọn mẫu. Ví dụ, trong hồi quy tiêu dùng điện
Y với thu nhập hộ gia đình (X2) và diện tích hộ gia đình (X3) thì thường các hộ gia đình có thu
nhập cao diện tích lớn.
3. Định dạng mô hình sai. Chẳng hạn chúng ta cho thêm biến X2 vào mô hình đã có biến độc lập
X. Điều này càng nghiêm trọng khi X nhận giá trị trong một khoảng nhỏ.
4. Số lượng biến độc lập nhiều hơn số quan sát (Overdetermined Model). Điều này thường xẩy
ra trong các nghiên cứu về Y Khoa. Thông thường, mẫu thử nghiệm (bệnh nhân) có số lượng
rất bé trong khi nhà nghiên cứu lại phải thu thập rất nhiều thông tin cho biến độc lập từ họ.
5. Xu hướng chung của các chuỗi thời gian. Nhiều chuỗi thời gian cùng tăng hoặc cùng giảm theo
thời gian (common trend). Do đó nếu thực hiện hồi quy tăng trưởng chi tiêu theo thu nhập và
tài sản thì hai biến độc lập thường là những biến có cùng xu hướng và do vậy có tương quan
cao.
Y = b1 +b2X2i + b3X3i + ui
𝑏1 = 𝑌̅ − 𝑏2 𝑋̅2 − 𝑏3 𝑋̅3
Với các phương sai lần lượt là:
𝜎2 𝜎2
var(𝑏2 ) = 2 (1 2 ) = ∑ 2 VIF
∑ 𝑥2𝑖 − 𝑟23 𝑥2𝑖
𝜎2 𝜎2
var(𝑏3 ) = 2 (1 2 ) = ∑ 2 VIF
∑ 𝑥3𝑖 − 𝑟23 𝑥3𝑖
Trong đó:
1
VIF = 2
1 − 𝑟23
Với r223 là bình phương hệ số tương quan giữa biến X3 và X2 , VIF gọi là hệ số phóng đại phương sai
(Variance Inflating Factor). Chúng ta có thể thấy khi r23 càng lớn thì hệ số VIF này càng cao, var(b3)
càng lớn và nếu r23 = 1 (cộng tuyến hoàn hảo) thì var(b3) là vô cùng:
Chú ý rằng ngoài hệ số VIF như trên người ta còn lấy TOL = 1/VIF (nghịch đảo của VIF) là tiêu chí
nhận định về hiện tượng đa cộng tuyến. Hiện tại, ngưỡng VIF (hay TOL, r23) bằng bao nhiêu để chỉ ra
hiện tượng đa cộng tuyến vẫn là một vấn đề chưa có sự thống nhất giữa các nhà kinh tế lượng. Gujarati
& Porter (2009) chỉ ra một số dấu hiệu của hiện tượng đa cộng tuyến trong mô hình khi: (1) hệ số VIF
≥ 10, hoặc (2) hệ số tương quan r của bất kì cặp biến nào trong mô hình lớn hơn 0.8. Trong khi đó
Allison (1999) đưa ra tiêu chí chặt hơn khi chọn VIF > 2.5 (hay r > 0.775).
Y, $ X2, $ X3, $
70 80 810
65 100 1009
90 120 1273
95 140 1425
110 160 1633
115 180 1876
120 200 2052
140 220 2201
155 240 2435
150 260 2686
(Bảng 2: Dữ liệu về tiêu dùng, thu nhập, và tài sản)
Y <- c(70, 65, 90, 95, 110, 115, 120, 140, 155, 150)
X2 <- c(80, 100, 120, 140, 160, 180, 200, 220, 240, 260)
X3 <- c(810, 1009, 1273, 1425, 1633, 1876, 2052, 2201, 2435, 2686)
dung <- data.frame(Y, X2, X3)
attach(dung)
jj <- lm(data = dung, Y ~ X2 + X3)
summary(jj)
##
## Call:
## lm(formula = Y ~ X2 + X3, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -11.1120 -4.4767 0.9206 4.1744 7.5844
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 24.77473 6.75250 3.669 0.00798 **
## X2 0.94154 0.82290 1.144 0.29016
## X3 -0.04243 0.08066 -0.526 0.61509
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.808 on 7 degrees of freedom
## Multiple R-squared: 0.9635, Adjusted R-squared: 0.9531
## F-statistic: 92.4 on 2 and 7 DF, p-value: 9.286e-06
Kết quả này chỉ ra rằng mặc dù R2 là rất cao (0.9635) và thống kê F rất lớn (92.4) nhưng không một
hệ số hồi quy nào của X2, X3 có ý nghĩa thống kê. Điều này cho thấy mô hình có dấu hiệu của bệnh đa
cộng tuyến vì rằng thu nhập (X2) và tài sản (X3) là những biến có tương quan dương rất cao. Chúng
ta có thể kiểm tra bảng hệ số tương quan:
cor(dung)
## Y X2 X3
## Y 1.0000000 0.9808474 0.9780997
## X2 0.9808474 1.0000000 0.9989624
## X3 0.9780997 0.9989624 1.0000000
Chúng ta có thể thấy tương qua giữa X2 và X3 là 0.9989 (gần bằng 1).
##
## Call:
## lm(formula = Y ~ X2, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.364 -4.977 1.409 4.364 8.364
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 24.45455 6.41382 3.813 0.00514 **
## X2 0.50909 0.03574 14.243 5.75e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.493 on 8 degrees of freedom
## Multiple R-squared: 0.9621, Adjusted R-squared: 0.9573
## F-statistic: 202.9 on 1 and 8 DF, p-value: 5.753e-07
Và Y theo X3:
##
## Call:
## lm(formula = Y ~ X3, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.6227 -5.5867 0.9576 5.0414 9.4142
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 24.411045 6.874097 3.551 0.0075 **
## X3 0.049764 0.003744 13.292 9.8e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.938 on 8 degrees of freedom
## Multiple R-squared: 0.9567, Adjusted R-squared: 0.9513
## F-statistic: 176.7 on 1 and 8 DF, p-value: 9.802e-07
Căn cứ vào các kết quả trên chúng ta có thể thấy rằng: mặc dù cả hai hệ số hồi quy của X2 và X3 không
có ý nghĩa thống kê khi chúng cùng xuất hiện trong một mô hình nhưng loại bỏ biến số có tương quan
cao (hoặc là X2, hoặc là X3) với các biến số khác thì việc này làm cho hệ số hồi quy của các biến số
khác có ý nghĩa thống kê ở mức cao.
Chúng ta cũng có thể tính hệ số VIF cho mô hình hồi quy Y = β1+ β2X2+ β3X3 như sau:
## [1] 482.1275
Chúng ta có thể thấy hệ số VIF là rất lớn: 482.13. Trong tình huống mà mô hình hồi quy có nhiều biến
số thì tính hệ số VIF như vậy phải lặp đi lặp lại. Chúng ta có thể tính cách khác với gói car (đã đề cập
trong mục 4.2.1 của chương 4) trong R như sau:
library(car)
vif(jj)
## X2 X3
## 482.1275 482.1275
Do mô hình của chúng ta chỉ có hai biến độc lập nên r23 = r32 do đó VIF ứng với X2 và X3 như nhau và
cùng bằng 482.1275 như chúng ta tính trực tiếp từ công thức như ở trên.
Chúng ta cũng có thể mở rộng công thức tính VIF cho mô hình hồi quy k biến số (mô hình có k-1 biến
độc lập) như sau:
𝜎2 1 𝜎2
var(𝑏𝑘 ) = ( )= VIF
∑ 𝑥𝑘2 1 − 𝑅𝑘2 ∑ 𝑥𝑘2
Trong đó R2k chính là R2 thu được từ hồi quy biến độc lập thứ k với k-2 biến độc lập còn lại – gọi là
các hồi quy phụ (Auxiliary Regression). Như vậy nếu mô hình hồi quy 11 biến số thì chúng ta sẽ có 10
hồi quy phụ ứng với 10 biến độc lập và do vậy chúng ta phải tính 10 hệ số VIF. Chúng ta có thể tính
các hệ số VIF này nhanh chóng với sự trợ giúp của lệnh vif() của gói car được trình bày ở trên.
Chúng ta cũng có thể tìm hiểu mức độ nhạy cảm của các mô hình hồi quy đối với một sự thay đổi nhỏ
của số liệu khi có hiện tượng đa cộng tuyến giữa các biến số. Chúng ta hãy xem xét hai bộ số liệu sau:
Y X2 X3 Y X2 X3
1 2 4 1 2 4
2 0 2 2 0 2
3 4 12 3 4 0
4 6 0 4 6 12
5 8 16 5 8 16
Nhập hai bộ dữ liệu này vào R dưới dạng hai data.frame với tên gọi là dulieu1 và dulieu2 rồi thực hiện
hồi quy cho Y theo X2 và X3:
##
## Call:
## lm(formula = y ~ x2 + x3, data = dulieu1)
##
## Residuals:
## 1 2 3 4 5
## -1.09878 0.80000 -0.01585 0.12805 0.18659
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.193902 0.773679 1.543 0.263
## x2 0.446341 0.184810 2.415 0.137
## x3 0.003049 0.085066 0.036 0.975
##
## Residual standard error: 0.9744 on 2 degrees of freedom
## Multiple R-squared: 0.8101, Adjusted R-squared: 0.6202
## F-statistic: 4.267 on 2 and 2 DF, p-value: 0.1899
##
## Call:
## lm(formula = y ~ x2 + x3, data = dulieu2)
##
## Residuals:
## 1 2 3 4 5
## -1.12162 0.73514 0.18378 0.05676 0.14595
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.21081 0.74802 1.619 0.247
## x2 0.40135 0.27206 1.475 0.278
## x3 0.02703 0.12523 0.216 0.849
##
## Residual standard error: 0.9635 on 2 degrees of freedom
## Multiple R-squared: 0.8143, Adjusted R-squared: 0.6286
## F-statistic: 4.386 on 2 and 2 DF, p-value: 0.1857
Ở bảng số liệu 2 chúng ta chỉ thực hiện thay đổi thứ tự cho một cặp giá trị của X3. Tuy nhiên sự thay
đổi này gây ra những tác động rất mạnh lên độ lệch chuẩn (cả cả giá trị thống kê t) ứng với hệ số của
X2: giá trị thống kê t giảm gần 2 lần. Nguyên nhân là tương quan giữa X2 và X3 tăng từ 0.5523 lên
0.8285 như chúng ta có thể thấy:
cor(dulieu1)
## y x2 x3
## y 1.000000 0.9000000 0.5063160
## x2 0.900000 1.0000000 0.5523448
## x3 0.506316 0.5523448 1.0000000
cor(dulieu2)
## y x2 x3
## y 1.0000000 0.9000000 0.7824884
## x2 0.9000000 1.0000000 0.8285172
## x3 0.7824884 0.8285172 1.0000000
Ví dụ này một lần nữa nhấn mạnh kết luận như các bạn đã biết ở trên: sai số chuẩn, thống kê t, và giá
trị p-value bị ảnh hưởng rất mạnh bởi một sự thay đổi nhỏ của số liệu.
8.3 Xử lý hiện tượng đa cộng tuyến bằng bỏ biến số căn cứ vào tiêu chí Cp của Mallows
Theo Gujarati (2011), Goldberger (1991) thì có ba cách có thể áp dụng để xử lí hiện tượng đa cộng
tuyến: (1) bỏ biến có mức độ tương quan cao với biến số khác, (2) sử dụng phương pháp phân tích
thành phần chính, và (3) không làm gì – Do Nothing. Phương pháp thứ hai đặc biệt hiệu quả khi xử lý
các mô hình có nhiều biến độc lập.
Trong phần này chúng ta sẽ nghiên cứu phương pháp bỏ biến số căn cứ vào tiêu chí Cp của Mallows.
Với mục đích minh họa, trong phần này chúng ta sẽ sử dụng bộ dữ liệu có tên Table4_0.dta từng
được sử dụng bởi Mroz (1987). Đây là bộ dữ liệu về 753 phụ nữ đã kết hôn trong năm 1975. Giả sử
chúng ta nghiên cứu tác động của các biến số như mức thu nhập của gia đình năm 1975 (faminc), mức
lương của chồng (hwage), độ tuổi (age), số năm đi học (educ).. lên số giờ làm việc (hours) của những
phụ nữ này. Tuy nhiên trong số đó có 325 người không làm việc trong năm đó và do vậy biến hours
= 0 cho các quan sát này. Chúng ta sẽ loại bỏ các quan sát này trong mô hình nghiên cứu. Như vậy
mẫu của chúng ta còn lại 428.
Trước hết, tôi giả định rằng các bạn đã thành thạo cách chỉ thị cho R đọc file dữ liệu Excel này dưới
dạng một data.frame có tên dacongtuyen. Sau khi thao tác nhập dữ liệu này, chúng ta bắt đầu thực
hành trong R.
Trước hết chúng ta xem xét mô hình gốc với hours là biến phụ thuộc với 15 biến độc lập còn lại. Trong
tình huống này không cần gõ tên của 15 biến độc lập trên khi thực hiện hồi quy mà chỉ làm như sau
là R tự hiểu rằng hours được hồi quy theo tất cả các biến còn lại:
setwd("D:/KTLR")
library(foreign)
dacongtuyen <- read.dta("Table4_0.dta")
# Loại một số biến không có trong mô hình cho gọn bộ số liệu:
nghiyeu <- dacongtuyen[, -c(1, 2, 3, 4, 5, 6, 7, 14, 24)]
# Chỉ lấy các quan sát mà hours > 0 từ data frame nghiyeu:
yeunghi <- subset(nghiyeu, hours > 0)
haha <- lm(data = yeunghi, hours~.)
summary(haha)
##
## Call:
## lm(formula = hours ~ ., data = yeunghi)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1683.9 -436.8 40.8 384.4 3500.3
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.595e+03 1.027e+03 8.368 9.21e-16 ***
## kidsl6 -1.916e+02 8.783e+01 -2.181 0.0297 *
## kids618 -2.451e+01 2.806e+01 -0.873 0.3830
## age -1.431e+01 9.661e+00 -1.481 0.1394
## educ -1.840e+01 1.934e+01 -0.951 0.3421
## wage -4.815e+01 1.041e+01 -4.624 5.04e-06 ***
## hhours -4.735e-01 7.327e-02 -6.463 2.91e-10 ***
## hage -5.586e+00 8.938e+00 -0.625 0.5323
## heduc -6.769e+00 1.399e+01 -0.484 0.6287
Trước khi chạy mô hình chúng ta kì vọng rằng số giờ làm việc có mối quan hệ tỉ lệ thuận với số năm
đi học (wage), trình độ giáo dục của bố (fathereduc), trình độ giáo dục của mẹ (mothereduc) và tỉ lệ
nghịch với tuổi (age), tuổi của chồng (hage), số giờ làm việc của chồng (hhours), mức lương của chồng
(hwage), tỉ lệ thuế thu nhập (mtr), số con nhỏ dưới 6 tuổi (kidsl6). Tuy nhiên, một số hệ số hồi quy
có dấu ngược với kì vọng. Ngoài ra, mô hình của chúng ta có tới 8 hệ số hồi quy không có ý nghĩa
thống kê.
library(car)
vif(haha)
Mặc dù các hệ số VIF này chưa phải là lớn lắm nhưng số lượng các biến không có ý nghĩa thống kê là
lớn gợi ý rằng rất có thể tồn tại hiện tượng đa cộng tuyến. Chẳng hạn, rõ ràng trình độ giáo dục của
mẹ (mothereduc) có tương quan cao với trình độ giáo dục của bố (fathereduc) và cũng tương quan
cao với trình độ giáo dục của con (educ). Như chúng ta đã biết, nguyên nhân là do các biến độc lập có
trong mô hình có thể có tương quan cao. Theo Gujarati & Porter (2009) nếu hệ số tương quan của
một cặp biến độc lập bất kì mà cao hơn 0.8 thì mô hình có thể gặp lỗi đa cộng tuyến nghiêm trọng.
Chúng ta có thể tìm hệ số tương quan của các biến độc lập bằng lệnh cor như đã làm ở mục 8.1 và 8.2.
Tuy nhiên, chúng ta có thể sử dụng gói PerformanceAnalytics để tìm hệ số tương quan giữa các biến
số cùng với các thông tin khác như mức ý nghĩa thống kê cùng histogram của các biến. Trước hết
chúng ta cài đặt bằng lệnh install.packages(“PerformanceAnalytics”). Bảng ma trận hệ số tương
quan của các biến độc lập từ kids đến faminc:
library(PerformanceAnalytics)
chart.Correlation(yeunghi[,-c(1, 12:16)], histogram = TRUE, pch = 19)
Kết quả chỉ ra rằng tương quan giữa, chẳng hạn, age và hage là rất cao (0.89) và có ý nghĩa thống kê
ở mức 1% (tương ứng với ba dấu ***).
Từ phân tích trên, chúng ta có thể loại biến số hage ra khỏi mô hình. Lập luận tương tự cho các biến
số khác chúng ta xét mô hình sau:
##
## Call:
## lm(formula = hours ~ ., data = yamato)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1660.5 -446.5 15.6 393.8 3495.9
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.485e+03 9.876e+02 8.591 < 2e-16 ***
## kidsl6 -1.804e+02 8.637e+01 -2.089 0.037297 *
## age -1.773e+01 4.903e+00 -3.616 0.000336 ***
## educ -2.703e+01 1.579e+01 -1.712 0.087713 .
## wage -4.743e+01 1.031e+01 -4.601 5.59e-06 ***
## hhours -4.865e-01 7.046e-02 -6.904 1.89e-11 ***
## hwage -1.450e+02 1.588e+01 -9.127 < 2e-16 ***
## faminc 1.378e-02 5.866e-03 2.349 0.019279 *
## mtr -6.351e+03 1.030e+03 -6.167 1.64e-09 ***
## unemployment -1.650e+01 1.056e+01 -1.563 0.118826
## exper 2.420e+01 4.653e+00 5.201 3.11e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 640.2 on 417 degrees of freedom
## Multiple R-squared: 0.3358, Adjusted R-squared: 0.3199
## F-statistic: 21.08 on 10 and 417 DF, p-value: < 2.2e-16
Có thể thấy rằng sau khi bỏ các biến số, hầu hết các hệ số hồi quy đều có ý nghĩa thống kê. Cách làm
trên phải qua hai bước: (1) trước tiên là loại các biến từ bộ số liệu, và (2) chạy lại mô hình. Có thể thu
được kết quả hoàn toàn tương tự (không hiển thị kết quả) theo cách thức khác như sau:
Hoặc cũng có thể sử dụng hàm update(). Các bạn có thể gõ ?update() trong R để tìm hiểu thêm.
Chúng ta cũng có thể tìm các hệ số VIF cho mô hình mới và có thể thấy rằng tất cả chúng đều khá bé:
vif(bb1)
Một lần nữa chúng ta chú ý rằng hệ số VIF được tính cho biến age chẳng hạn được tính bằng VIF =
1/(1-R2) trong đó R2 chính là hệ số xác định (Multiple R-Squared) thu được khi hồi quy, chẳng hạn,
kidsl6 theo 9 biến số còn lại là age cho đến exper.
Cần nhắc lại rằng chiến lược xử lý bằng cách bỏ biến như vậy là cần phải rất thận trọng (Gujarati,
2011) vì việc bỏ biến có thể còn gây ra những hậu quả nghiêm trọng hơn những hậu quả gây ra bởi
hiện tượng đa cộng tuyến (Nguyễn & Nguyễn, 2012). Một vấn đề nữa là chiến lược bỏ biến mà chúng
ta vừa thực hiện ở trên có vẻ tùy tiện và không tuân theo một quy tắc cụ thể nào ngoài việc căn cứ vào
hiểu biết của chúng ta về mối quan hệ giữa các biến số. Để xử lý vấn đề này, chúng ta có thể căn cứ
vào tiêu chí Cp của Mallows (Mallows’ Cp) để lựa chọn mô hình (Ledolter, 2013). Theo đó, chúng ta
sẽ chọn mô hình bằng căn cứ vào hai tiêu chí sau: (1) R2 hoặc R2 hiệu chỉnh càng cao càng tốt, và (2)
có Cp càng thấp càng tốt.
Để thực hiện việc loại biến nhằm xử lý đa cộng tuyến ở mức cao của mô hình, trước hết chúng ta cần
cài đặt gói leaps bằng lệnh install.packages(“leaps”). Sau khi cài đặt gói này, chúng ta có thể thực
hiện chiến lược bỏ biến cho mô hình một cách khoa học hơn như sau:
## (Intercept) kidsl6 kids618 age educ wage hhours hage heduc hwage faminc
## 1 1 0 0 0 0 0 0 0 0 0 0
## 1 1 0 0 0 0 0 0 0 0 0 0
## 2 1 0 0 0 0 0 0 0 0 1 0
## 2 1 0 0 0 0 0 0 0 0 0 0
## 3 1 0 0 0 0 0 1 0 0 1 0
## 3 1 0 0 0 0 0 0 0 0 1 0
….
## mtr mothereduc fathereduc unemployment exper R2 Cp
## 1 0 0 0 0 1 0.08953864 143.625603
## 1 1 0 0 0 0 0.03293060 178.917792
## 2 1 0 0 0 0 0.13923672 114.641418
## 2 1 0 0 0 1 0.11801302 127.873299
## 3 1 0 0 0 0 0.22821590 61.167499
## 3 1 0 0 0 1 0.19322075 82.985167
Ở đây các bạn có thể thấy hai cột giá trị cuối cùng lần lượt chính là R2 và Cp. Với các biến độc lập, cột
biến số nào mà đánh số 1 thì mô hình có biến ấy, đánh số 0 thì không có biến trong mô hình. Ở đây có
ba mô hình có Cp thấp hơn cả. Ví dụ, có một mô hình có 9 biến độc lập (là các biến độc lập nào các bạn
căn cứ vào cột biến có giá trị 1) với R2 và Cp lần lượt là 0.33189522 và 8.528801. Tuy nhiên, nếu
chúng ta theo đuổi chiến lược chọn mô hình có Cp thấp nhất nhưng lại có R2 lớn nhất có thể thì chúng
ta sẽ chọn mô hình có 10 biến ở dòng trên (chú ý có hai mô hình có 10 biến độc lập) thì chúng ta sẽ
có kết quả như sau:
greek <- yeunghi[, -c(3, 8, 9, 13, 14)] # Bỏ các biến ở cột 3,8,9,13,và 14.
bb2 <- lm(data = greek, hours~.) # Chạy mô hình 10 biến độc lập.
summary(bb2)
##
## Call:
## lm(formula = hours ~ ., data = greek)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1660.5 -446.5 15.6 393.8 3495.9
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.485e+03 9.876e+02 8.591 < 2e-16 ***
## kidsl6 -1.804e+02 8.637e+01 -2.089 0.037297 *
## age -1.773e+01 4.903e+00 -3.616 0.000336 ***
## educ -2.703e+01 1.579e+01 -1.712 0.087713 .
## wage -4.743e+01 1.031e+01 -4.601 5.59e-06 ***
## hhours -4.865e-01 7.046e-02 -6.904 1.89e-11 ***
## hwage -1.450e+02 1.588e+01 -9.127 < 2e-16 ***
## faminc 1.378e-02 5.866e-03 2.349 0.019279 *
## mtr -6.351e+03 1.030e+03 -6.167 1.64e-09 ***
## unemployment -1.650e+01 1.056e+01 -1.563 0.118826
## exper 2.420e+01 4.653e+00 5.201 3.11e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 640.2 on 417 degrees of freedom
## Multiple R-squared: 0.3358, Adjusted R-squared: 0.3199
## F-statistic: 21.08 on 10 and 417 DF, p-value: < 2.2e-16
Chú ý rằng giá trị R2 ở mô hình bb2 chỉ có 10 biến độc lập này là 0.3358. Đây chính là giá trị R2 mà
chúng ta đã biết trước vì nó cũng chính là mô hình bb1 (việc trùng lặp giữa hai mô hình bb1 và bb2
chỉ là ngẫu nhiên). Mô hình bb2 so với mô hình 15 biến độc lập ban đầu có R2 thua kém 1% (0.3358
so với 0.3392). Nói cách khác, khi chúng ta loại đi 5 biến số, thì sức mạnh giải thích của mô hình giảm
không đáng kể.
Bạn cũng có thể chọn mô hình chỉ có 9 biến số (nếu ưu tiên Cp thấp nhất) một cách tương tự. Ví dụ
này cũng cho thấy ưu thế của R so với các phần mềm thống kê khác trong việc hỗ trợ chiến lược loại
biến khi xử lý hiện tượng đa cộng tuyến với tiêu chí Cp và R2, đặc biệt là với các mô hình có số lượng
biến độc lập rất lớn.
8.4 Xử lý hiện tượng đa cộng tuyến bằng phân tích thành phần chính PCA
Ngoài cách xử lý bằng cách bỏ biến như trên, Gujarati (2011) còn đề xuất sử dụng phương pháp phân
tích thành phần chính PCA (Principal Component Analysis). Với R chúng ta có thể thực hiện PAC cho
dữ liệu với sự trợ giúp của gói psych và gói factoextra. Trước hết cài đặt gói psych:
install.packages("psych")
Riêng gói factoextra cài đặt có chút phức tạp hơn vì phải cài đặt từ Github:
install.packages("devtools")
library(devtools)
install_github("kassambara/factoextra")
Để minh họa cho PCA chúng ta tiếp tục sử dụng data frame có tên yeunghi ở mục 8.3. Để thực hiện
PCA trước hết chúng ta cần loại biến hours ra khỏi data frame này rồi mới thực hiện PCA:
dung <- yeunghi[, -c(1)]
Kế tiếp chúng ta cần đảm bảo rằng sử dụng PCA là phù hợp bằng kiểm định KMO:
library(psych)
KMO(dung)
Để phân tích PCA chúng ta cần giá trị KMO này tối thiểu là 0.5. Với dữ liệu của chúng ta, KMO Test là
0.68 cho thấy sử dụng PCA là phù hợp. Với số liệu đã cho chúng ta thực hiện PCA trong R như sau:
pca <- prcomp(dung, scale = TRUE)
library(factoextra); library(ggplot2); library(factoextra)
get_eig(pca)
Số lượng các nhân tố được rút ra căn cứ vào tiêu chuẩn giá trị eigenvalue lớn hơn 1. Từ kết quả phân
tích PCA, chúng ta thấy 15 biến số ban đầu rút lại còn 5 nhân tố chính. Nhân tố thứ nhất (Dim1) giải
thích cho 24% tổng biến thiên (dòng variance.percent) và 5 nhân tố này (từ Dim1 đến Dim5) giải
thích tất cả 74% biến thiên (dòng cumulative.variance.percent). Chúng ta có thể minh họa các nhân
tố được rút ra cùng tỉ lệ phương sai giải thích của chúng:
fviz_screeplot(pca, addlabels = TRUE, n = 15)
Chúng ta cũng có thể minh họa các nhân tố rút ra cùng trị số eigenvalue tương ứng:
# Mặc định độ chính xác 1 chữ số sau dấu phẩy:
fviz_screeplot(pca, n=15, choice = "eigenvalue", addlabels = TRUE)
Thực hiện hồi quy cho hours theo 5 điểm nhân tố được rút ra như sau:
choson <- principal(dung, nfactors = 15, rotate = "none", scores = TRUE)
yeunghi <- cbind(yeunghi, choson$scores)
summary(lm(data = yeunghi, hours ~ PC1 + PC2 + PC3 + PC4 + PC5))
##
## Call:
## lm(formula = hours ~ PC1 + PC2 + PC3 + PC4 + PC5, data = yeunghi)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1568.4 -635.4 68.2 559.7 3682.7
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1302.930 36.619 35.580 < 2e-16 ***
## PC1 -2.812 36.662 -0.077 0.938889
## PC2 142.660 36.662 3.891 0.000116 ***
## PC3 22.496 36.662 0.614 0.539817
## PC4 -120.400 36.662 -3.284 0.001109 **
## PC5 4.884 36.662 0.133 0.894092
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 757.6 on 422 degrees of freedom
## Multiple R-squared: 0.05872, Adjusted R-squared: 0.04757
## F-statistic: 5.265 on 5 and 422 DF, p-value: 0.0001053
Kết quả này chỉ ra rằng có vẻ như hai nhân tố PC2 và PC4 giải thích hành vi của biến hours tốt nhất.
Tuy nhiên, điểm khó ở đây là diễn đạt các kết quả thu được. Thực vậy, một trong những khó khăn đàu
tiên là chúng ta không thể sử dụng cách diễn đạt thường thấy kiểu như “.. khi các biến số khác không
đổi, thì PC2 tăng 1 dẫn đến biến phụ thuộc hours tăng 142.66..”.
Cách diễn giải đó là không chính xác. Thực vậy, PC2 được tạo ra bằng cách “tổ hợp” các biến số khác
và do đó, nó không có đơn vị. Nếu diễn giải như trên thì câu hỏi đầu tiên là: PC2 tăng 1, thế thì 1 ở đây
là 1 m, 1 h, hay 1 năm? Việc sử dụng hồi quy OLS cho các biến thành phần chính PC (và nhân tố chính
sau khi thực hiện EFA – một nội dung được đề cập kĩ ở chương 15) là không có ý nghĩa với mục đích
giải thích vì các biến độc lập là không có đơn vị trong tình huống chúng ta vừa nghiên cứu.
Một vấn đề nữa cần phải lưu ý ở đây là việc loại bỏ các biến tương quan cao một cách thủ công bằng
cách quan sát các cặp biến số có tương quan cao hơn một ngưỡng nào đó (chẳng hạn là 0.8) như trên
là không khuyến khích, đặc biệt là nếu mô hình có hàng trăm biến số. Việc loại bỏ chúng một cách có
hệ thống dựa trên một ngưỡng nào đó được thực hiện một cách nhanh chóng bằng gói caret.
Chúng ta cũng có thể khảo sát chi tiết các thông số về chất lượng của mô hình cũng như việc lựa chọn
biến số cho mô hình theo một cách khác được trình bày ngay sau đây.
8.5 Lựa chọn số lượng biến căn cứ vào các tiêu chuẩn thông tin BIC
Chúng ta biết rằng khi tăng số lượng biến số cho mô hình thì R2 của mô hình tăng. Tuy nhiên nỗ lực
tăng R2 cho mô hình bằng tăng biến số có mặt trong mô hình đối mặt với một số hạn chế sau. Thứ
nhất, gia tăng khả năng chúng ta cho vào một biến có tương quan cao với một hoặc một số biến sẵn
có. Thứ hai, càng nhiều biến số mô hình càng trở nên khó diễn giải. Và cuối cùng, R2 cũng tuân theo
quy luật “lợi ích cận biên giảm dần” – điều mà chúng ta sẽ nghiên cứu ở trong mục này. Hơn nữa ngoài
R2 chúng ta cũng cần căn cứ vào một số tiêu chuẩn khác, chẳng hạn, tiêu chuẩn thông tin BIC/AIC hoặc
hệ số Cp của Mallows để lựa chọn biến số cho mô hình.
Dưới đây chúng ta sẽ khảo sát một số tiêu chí lựa chọn mô hình đã biết để từ đó đưa ra một chiến
lược lựa chọn biến số khoa học hơn. Chúng ta trở lại với bộ số liệu yeunghi đã sử dụng ở các mục
trên với hàm regsubsets() của gói leaps. Hàm này cho biết sự thay đổi của các tiêu chí lưa chọn mô
hình ra sao khi số lượng biến số thay đổi. Từ đó, chúng ta có thể đưa ra chiến lược lựa chọn biến số
phù hợp.
# nvmax = 15 chính là số biến độc lập của mô hình đầy đủ. Nếu không có lựa ch
ọn này, mặc định là 8:
full <- regsubsets(hours~., data = yeunghi, nvmax = 15)
love <- summary(full)
# Hiển thị các tiêu chí sử dụng để đánh giá mô hình:
names(love)
Ở đây chúng ta thấy có những tiêu chí quên thuộc như R2 (kí hiệu rsq), BIC (ki hiệu bic). Giả sử chúng
ta chọn bốn tiêu chí là R2, BIC, Cp, và RSS:
r2 <- love$rsq
bic <- love$bic
which.min(bic) # Số lượng biến số trong mô hình cho BIC thấp nhất.
## [1] 6
cp <- love$cp
which.min(cp) Số lượng biến số trong mô hình cho Cp thấp nhất.
## [1] 10
rss=love$rss
Chúng ta đánh giá các tiêu chuẩn lựa chọn mô hình thay đổi ra sao với biến số có trong mô hình bằng
hình ảnh sau:
par(mfrow=c(2, 2))
par(bg = "grey90")
plot(r2, xlab = "So luong bien", ylab = "R2", type = "b", pch = 16)
plot(rss, xlab = "So luong bien", ylab = "RSS", type="b", pch = 16)
plot(bic, xlab = "So luong bien", ylab = "BIC", type = "b", pch = 16)
points(which.min(bic), bic[which.min(bic)], col = "red", cex = 2, pch = 20)
plot(cp, xlab = "So luong bien", ylab = "Mallows' Cp", type = "b", pch = 16)
points(which.min(cp), cp[which.min(cp)], col = "red", cex = 2, pch = 20)
Chúng ta thấy rằng với R2 chẳng hạn, khi số lượng biến tăng thì tiêu chí này cũng tăng nhưng với tốc
độ chậm dần. Đến ngưỡng 8 biến số thì gia tăng thêm biến số gần như không dẫn đến tăng tiêu chí
này một cách dáng kể (đồ thị gần như là một đường thẳng). Điều này ngụ ý rằng nếu lấy mục tiêu là
tối đa hóa R2 nhưng lại đảm bảo số lượng biến tối thiểu thì nên chọn mô hình có 8 biến số. Chúng ta
có thể biết mô hình là những biến số nào cùng với hệ số hồi quy của chúng:
coef(full, 8)
Tương tự nếu chúng ta chọn mô hình có BIC thấp nhất thì mô hình ấy sẽ có 6 biến số. Cụ thể các biến
ấy cùng hệ số hồi quy của chúng là:
coef(full, 6)
Nếu chọn mô hình là tối thiểu hóa Cp thì các bạn gõ lệnh coef(full,10). Kết quả thu được (hệ số hồi
quy) sẽ trùng với kết quả ở mục 8.3.
Nếu chọn tiêu chí BIC, chúng ta có thể phân tích chi tiết hơn như sau:
par(mfrow=c(1, 1))
par(bg = "white") # Trả lại nền trắng.
plot(full, scale = "bic")
Hình ảnh này cho thấy có 5 mô hình khác nhau có BIC là -110. Một mô hình trong số đó gồm các biến
kidsl6, age, wage, hhours, hwage, mtr, faminc, và exper. Riêng mô hình có BIC là -120 thì chỉ có 6 biến
và là những biến nào thì chúng ta đã biết.
Ở đây tôi không trình bày lựa chọn mô hình theo tiêu chí AIC vì lựa chọn tiêu chí theo AIC là khá tương
đồng với lựa chọn mô hình theo tiêu chí BIC.
Chương 9: Phương sai sai số thay đổi trong mô hình hồi quy
Một trong những giả định nền tảng của mô hình hồi quy tuyến tính cổ điển là sai số ngẫu nhiên phải có
phương sai không đổi, đồng nhất (Homoskedasticity). Rõ ràng trong thực tế giả định này là khó tồn
tại. Trong chương này chúng ta sẽ nghiên cứu những nguyên nhân của hiện tượng phương sai sai số
thay đổi (Heteroskedasticity), các kiểm định nhằm chẩn đoán hiện tượng này cũng như một số cách
khác phục đơn giản nhất.
𝐸(𝑢𝑖2 ) = 𝜎 2 𝑖 = 1, 2, … , 𝑛
Điều này được minh họa như sau:
Ngược lại, nếu phương sai của sai số ngẫu nhiên ứng với mỗi quan sát là khác nhau thì chúng ta gặp
hiện tượng phương sai sai số thay đổi (Heteroscedasticity). Hình dưới đây minh họa phương sai sai
số ngẫu nhiên tăng dần:
Theo Valavanis (1959), hiện tượng heteroscedasticity có thể xuất hiện bởi các nguyên nhân sau:
1. Nếu chúng ta xét mô hình hồi quy giữa tiết kiệm (savings) với thu nhập (income) thì rõ ràng
các gia đình có thu nhập cao sẽ có nhiều lựa chọn hơn về quyết định tiết kiệm của mình và do
vậy biến động khoản tiết kiệm của họ có thể rất lớn. Tương tự, các công ti có lợi nhuận lớn
thường có chính sách cổ tức biến động hơn các công ti có lợi nhuận bé. Hiện tượng phương
sai sai số ngẫu nhiên thay đổi là một hiện tượng thường gặp trong các nghiên cứu kinh tế sử
dụng dữ liệu chéo.
2. Tuân theo hành vi học – sửa lỗi. Chúng ta hãy xem xét ví dụ về số lỗi đánh máy phụ thuộc như
thế nào vào số giờ thực hành. Rõ ràng, khi số giờ thực hành tăng lên thì số lỗi đánh máy trung
bình và phương sai của chúng giảm dần theo thời gian. Trường hợp này thì phương sai sai số
ngẫu nhiên giảm dần.
3. Phương pháp thu thập dữ liệu ngày càng được cải thiện rất có thể làm cho σ2i ngày càng nhỏ
đi.
4. Do các quan sát bất thường (Outliers – các quan sát rất khác biệt so với nhóm còn lại trong
mẫu). Sự xuất hiện của chúng có thể gây ra thay đổi quan trọng đến kết quả phân tích số liệu,
đặc biệt là với mẫu có kích thước nhỏ.
5. Định dạng mô hình sai. Chẳng hạn như mô hình hồi quy bỏ sót một số biến số quan trọng hay
đổi biến không phù hợp.
6. Do độ méo (Skewness) của một hay nhiều biến độc lập trong mô hình. Trong kinh tế chúng ta
thường biết rằng các biến số như thu nhập, tài sản thường méo về phía dương.
Phương sai sai số thay đổi có thể gây ra các hiện tượng sau:
1. Các ước lượng OLS thu được vẫn là không chệch (Unbiasedness) và là các ước lượng vững
(Consistency).
2. Các ước lượng OLS không còn là các ước lượng có phương sai nhỏ nhất.
3. Kiểm định t và F sẽ bé dẫn đến việc sử dụng các kiểm định liên quan đến hai thống kê này
không còn ý nghĩa.
Chúng ta thấy ở trường hợp a, phần dư bình phương không có liên hệ gì với giá trị ước lượng và do
vậy có thể không tồn tại hiện tượng phương sai sai số thay đổi. Tuy nhiên, các tình huống còn lại thì
khác. Chẳng hạn tình huống c ngụ ý rằng phần dư có quan hệ tuyến tính với giá trị ước lượng Ŷ . Con
trường hợp d thì mối quan hệ đó là hình chữ u ngược.
Trong phần này, chúng ta sử dụng bộ dữ liệu có tên Table5_1.dta (file Stata). Giả sử chúng ta muốn
đánh giá tỉ lệ phá thai trên 1000 phụ nữ ở độ tuổi 15 đến 44 (abortion) ở 50 bang của Hoa Kì phụ
thuộc như thế nào vào tỉ lệ dân số theo đạo (religion), giá của mỗi lần phá thai dưới 10 tuần tuổi
(price), luật (laws = 1 nếu bang có luật chặt chẽ về phá thai, = 0 nếu không có), tỉ lệ dân số trên 25 tốt
nghiệp trung học hoặc hơn (educ), quỹ hỗ trợ (funds = 1 nếu bang có hỗ trợ tài chính, = 0 nếu khác),
thu nhập đầu người (income). Hồi quy trong R:
setwd("D:/KTLR")
library(foreign)
homo <- read.dta("Table5_1.dta")
attach(homo)
c8 <- lm(data = homo, abortion ~ religion + price +
laws + funds + educ + income)
summary(c8)
##
## Call:
## lm(formula = abortion ~ religion + price + laws + funds + educ +
## income, data = homo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -12.894 -5.210 -1.515 5.198 20.484
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.1959887 15.0524658 -0.079 0.937
## religion -0.0051889 0.0923269 -0.056 0.955
## price -0.0416943 0.0238850 -1.746 0.088 .
## laws -2.1751208 2.5040006 -0.869 0.390
## funds 3.4174262 2.9828050 1.146 0.258
## educ -0.1340455 0.2060909 -0.650 0.519
## income 0.0023318 0.0004885 4.773 2.12e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.591 on 43 degrees of freedom
## Multiple R-squared: 0.5002, Adjusted R-squared: 0.4304
## F-statistic: 7.172 on 6 and 43 DF, p-value: 2.418e-05
Dấu của các hệ số thu được là phù hợp với các kì vọng của chúng ta. Chẳng hạn, trình độ giáo dục càng
cao thì tỉ lệ phá thai càng bé. Người theo tôn giáo thường có xu hướng phá thai thấp hơn.
Kết tiếp, chúng ta lưu bình phương phần dư cũng như các ước lượng về tỉ lệ phá thai và gán nó vào
data.frame có tên homo đã có với các tên biến là phandubp, aborpre:
Chúng ta có thể vẽ cả histogram cho phandubp và biểu diễn phandubp trên trục Y, abopre trên trục
X:
attach(homo)
par(mfrow = c(1, 2))
plot(phandubp ~ aborpre)
hist(phandubp, col = "pink", prob = TRUE, main = "")
Căn cứ vào các đồ thị chúng ta có thể nhận định rằng có thể tồn tại hiện tượng phương sai sai số thay
đổi trong mô hình. Để đưa ra bằng chứng thống kê cho nhận định này cần sử dụng một số kiểm định
chính thức được trình bày dưới đây.
Chúng ta sử dụng kiểm định Park cho mô hình. Nếu chúng ta chọn Xi là biến regilion thì:
##
## Call:
## lm(formula = log(phandubp) ~ log(religion), data = homo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.0450 -0.9740 0.8252 1.5875 3.4789
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.6620 3.0149 1.546 0.129
## log(religion) -0.6398 0.8773 -0.729 0.469
##
## Residual standard error: 2.355 on 48 degrees of freedom
## Multiple R-squared: 0.01096, Adjusted R-squared: -0.009646
## F-statistic: 0.5319 on 1 and 48 DF, p-value: 0.4694
Do hệ số của log(religion) không có ý nghĩa thống kê nên theo tinh thần của kiểm định Park chúng ta
có thể kết luận không tồn tại hiện tượng phương sai sai số thay đổi ở mô hình.
Tuy nhiên, Goldfeld & Quandt (1972) chỉ ra rằng kiểm định Park có một số nhược điểm. Chẳng hạn
trong tình huống của chúng ta, có 6 biến độc lập nên về lý thuyết phải có 6 kiểm định Park và có thể
chúng lại ra những kết quả khác nhau. Thực vậy, giả sử chúng ta chọn Xi là biến income thì kết quả là:
##
## Call:
## lm(formula = log(phandubp) ~ log(income), data = homo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.4689 -0.8049 0.6242 1.5258 3.9064
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -71.674 20.746 -3.455 0.001161 **
## log(income) 7.525 2.105 3.575 0.000812 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.105 on 48 degrees of freedom
## Multiple R-squared: 0.2102, Adjusted R-squared: 0.1938
## F-statistic: 12.78 on 1 and 48 DF, p-value: 0.0008119
Lúc này hệ số của log(income) lại có ý nghĩa thống kê nên chúng ta lại ra kết luận ngược lại so với
trước: tồn tại hiện tượng phương sai sai số thay đổi.
|𝑢̂𝑖 | = 𝛽1 + 𝛽2 𝑋𝑖 + 𝑣𝑖
|𝑢̂𝑖 | = 𝛽1 + 𝛽2 √𝑋𝑖 + 𝑣𝑖
1
|𝑢̂𝑖 | = 𝛽1 + 𝛽2 + 𝑣𝑖
𝑋𝑖
1
|𝑢̂𝑖 | = 𝛽1 + 𝛽2 + 𝑣𝑖
√𝑋𝑖
|𝑢̂𝑖 | = √𝛽1 + 𝛽2 𝑋𝑖 + 𝑣𝑖
Chúng ta sử dụng kiểm định Glejser với dạng đầu tiên, biến Xi là income chẳng hạn. Trước hết chúng
ta cần tạo ra biến giá trị tuyệt đối của phần dư có tên gọi tdphandu theo cách thức như đã làm ở phần
trước:
Sau đó thực hiện hồi quy dạng đầu tiên của kiểm định này:
##
## Call:
## lm(formula = tdphandu ~ income, data = homo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.6422 -2.7862 -0.1683 2.2619 12.8091
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -8.5376347 3.9323971 -2.171 0.034899 *
## income 0.0007303 0.0002025 3.606 0.000739 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.984 on 48 degrees of freedom
## Multiple R-squared: 0.2131, Adjusted R-squared: 0.1967
## F-statistic: 13 on 1 and 48 DF, p-value: 0.000739
Theo tinh thần của kiểm định Glejser chúng ta thấy rằng hệ số của income có ý nghĩa thống kê do vậy
tồn tại hiện tượng phương sai sai số thay đổi.
Cũng như với kiểm định Park, kiểm định Glejser cũng có các nhược điểm như kiểm định Park. Ngoài
ra, hai dạng cuối cùng của kiểu kiểm định này là phi tuyến tính về tham số nên không thể thực hiện
bằng OLS.
library(AER)
gqtest(c8)
##
## Goldfeld-Quandt test
##
## data: c8
## GQ = 2.8015, df1 = 18, df2 = 18, p-value = 0.0174
Giá trị p-value = 0.0174 < 5% nên chúng ta kết luận rằng có hiện tượng phương sai sai số thay đổi.
9.2.2.4 Kiểm định do Breusch – Pagan đề xuất dựa trên kiểm định F
Chúng ta sử dụng bộ số liệu ch4bt8.wf1 với 935 quan sát được cung cấp bởi khoa toán mà chúng ta
đã nghiên cứu ở mục 6.7 thuộc chương 6 (đây cũng chính là bộ số liệu được sử dụng tại trang 222
sách giáo trình minh họa cho kiểm định Breusch – Pagan Test).
Để kiểm định mô hình này có phương sai sai số thay đổi hay không, Breusch & Pagan (1979) đề xuất
nghiên cứu mô hình phụ:
Trong đó phadubp là phần dư bình phương thu được từ mô hình gốc. Nếu một trong hai hệ số λ2, λ3
mà khác không thì chúng ta có thể kết luận tồn tại phương sai sai số thay đổi.
Phân tích trên chỉ ra rằng chúng ta chỉ cần kiểm định cặp giả thuyết sau:
Nếu chúng ta đưa ra bằng chứng thống kê bắc bỏ H0 thì có nghĩa là mô hình của chúng ta có hiện
tượng phương sai sai số thay đổi. Như vậy chúng ta có thể thực hiện kiểm định này bằng cách sử dụng
thống kê F theo các bước dưới đây.
library(hexView)
trang <- readEViews("ch4bt8.wf1", as.data.frame = TRUE)
attach(trang)
hello <- lm(data = trang, WAGE ~ AGE + EDUC)
summary(hello)
##
## Call:
## lm(formula = WAGE ~ AGE + EDUC, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -819.95 -249.87 -43.05 202.86 2233.76
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1950.250 152.823 12.762 < 2e-16 ***
Sau đó chúng ta tạo biến mới phần dư bình phương với tên gọi phandubp trong R:
Cuối cùng thực hiện kiểm định Breuch – Pagan Test bằng chạy mô hình hồi quy phụ. Đây chính là cách
thức được trình bày trong sách giáo trình kinh tế lượng của NEU:
##
## Call:
## lm(formula = phandubp ~ AGE + EDUC, data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -236399 -117710 -73131 20546 4868407
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -205606 129447 -1.588 0.113
## AGE 2823 3362 0.840 0.401
## EDUC 18849 4756 3.963 7.98e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 319300 on 932 degrees of freedom
## Multiple R-squared: 0.01722, Adjusted R-squared: 0.01511
## F-statistic: 8.164 on 2 and 932 DF, p-value: 0.0003055
Do p-value = 0.0003055 ứng với Fqs = 8.164 nên chúng ta kết luận rằng tồn tại phương sai sai số thay
đổi trong mô hình (bắc bỏ H0). Chúng ta thu được kết luận tương tự khi so sánh Fqs = 8.164 với
F0.95;2,932 =3.0054:
## [1] 3.005382
Các tiếp cận này thường được gọi là kiểm định Breusch – Pagan (BP Test) cho hiện tượng phương sai
sai số thay đổi. Cách gọi này thường gây ra sự hiểu lầm. Thực vậy, như chúng ta thấy, thực chất cách
tiếp cận mà Breusch và Pagan đề xuất là sử dụng kiểm định F. Cách tiếp cận này phát sinh từ bài báo
có tên “A Simple Test for Heteroskedasticity and Random Coefficient Variation” đăng trên tạp chí
Econometrica năm 1979 của Breusch và Pagan nhưng chính hai tác giả cũng viết rằng cách tiếp cận
này là đơn giản (a simple test) và được xây dựng trên cơ sở của kiểm định Lagrange (nguyên văn là :
A simple test for heteroscedastic disturbances in a linear regression model is developed using the
framework of the Lagrangian multiplier test) chứ chính hai tác giả cũng chưa bao giờ nói cách tiếp cận
do mình đề xuất là kiểm định mang tên mình. Cách tiếp cận của Breusch và Pagan được gọi tên là
kiểm định BP có lẽ là cách gọi của các tác giả sau này để vinh danh đề xuất của hai ông trong việc đưa
ra cách tiếp cận cho kiểm định phương sai sai số thay đổi.
Như đã trình bày ở trên, kiểm định BP được xây dựng trên cơ sở kiểm định Lagrange (chính xác là
Lagrange Multiplier Test). Do vậy, trong trường hợp mà n là lớn, thay vì sử dụng thống kê F chúng ta
có thể sử dụng thống kê Lagrange Multiplier hay thường gọi là kiểm định Lagrange Multiplier (LM
Test). Theo đó, LM Test (hay LMqs) được tính theo công thức : LMqs = R2*n trong đó R2 là của mô
hình hồi quy phụ, n là số quan sát. Kết tiếp, chúng ta so sánh LMqs này với χ20.95;3 (k= 3 chính là số
biến số trong mô hình). Nếu LMqs > χ20.95;3 thì chúng ta bắc bỏ H0, ngược lại chúng ta chấp nhận H0.
Trong tình huống của chúng ta thì χ2 = 7.8:
qchisq(0.95,3)
## [1] 7.814728
Giá trị này rõ ràng bé hơn 0.01722*935 = 16.1007 = LMqs nên ta bắc bỏ H0.
Chúng ta cũng có thể sử dụng kiểm định Wald để kiểm định sự đồng thời bằng không của các hệ số
hồi quy ở mô hình phụ:
Căn cứ kết quả thu được chúng ta cũng có kết luận tương tự: Bắc bỏ H0.
Chúng ta thấy rằng sử dụng kiểm định F (hay LM Test) như trên cần thông qua một bước trung gian
là thực hiện hồi quy phụ. R cho phép chúng ta thực hiện trực tiếp BP Test mà không cần qua bước
trung gian này với lệnh bptest() của gói lmtest. Cặp giả thuyết được kiểm định là:
Ho: phương sai là không đổi; H1: phương sai là thay đổi.
library(lmtest)
bptest(hello)
##
## studentized Breusch-Pagan test
##
## data: hello
## BP = 16.099, df = 2, p-value = 0.0003192
Do giá trị p-value = 0.00032 < 5% nên chúng ta có bằng chứng thống kê bắc bỏ Ho. Một cách khác là
so sánh thống kê BP = 16.099 với χ20.05; 2 = 5.99 để rút ra kết luận tương tự.
Nếu 1 trong các hệ số hồi quy từ ψ2 đến ψ6 mà khác không thì chúng ta có thể kết luận tồn tại phương
sai sai số thay đổi. Nói cách khác, điều này tương đương với việc chúng ta bắc bỏ H0 ở cặp giả thuyết
sau:
Do phandubp đã được có nên chúng ta thực hiện kiểm định này trong R như sau:
summary(lm(data = trang,
phandubp ~ AGE + EDUC + I(AGE^2) + I(EDUC^2) + (AGE*EDUC)))
##
## Call:
## lm(formula = phandubp ~ AGE + EDUC + I(AGE^2) + I(EDUC^2) + (AGE *
## EDUC), data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -283588 -116050 -75902 17726 4857368
##
## Coefficients:
Ở đây Fqs = 3.733 (chính là thống kê F) ứng với p-value = 0.002369 <5% nên chúng ta có bằng chứng
thống kê để kết luận tồn tại phương sai sai số thay đổi.
Chú ý: Ta có LMqs = nR2 = 0.0197*935 = 18.42 > χ2 = 7.8 nên chúng ta có kết luận như trên nếu chúng
ta sử dụng LM Test (chú ý rằng các kết quả về Fqs và LMqs trong sách tại trang 225 là sai).
Gói lmtest cũng cho phép chúng ta tính trực tiếp giá trị 18.42 ở trên mà không cần chạy hồi quy phụ:
##
## studentized Breusch-Pagan test
##
## data: hello
## BP = 18.418, df = 5, p-value = 0.002466
Do p-value = 0.0025 < 5% nên chúng ta đi đến kết luận là phương sai thay đổi.
Sau đó chúng ta thực hiện hồi quy phần dư bình phương theo các giá trị dự đoan Ŷ 2i :
##
## Call:
Kết quả này chỉ ra rằng có hiện tượng phương sai sai số thay đổi do hệ số của y2 có ý nghĩa thống kê
ở mức cao.
9.3 Một số cách khác phục phương sai sai số thay đổi
Phần trên chúng ta đã xem xét một số cách tiếp cận đánh giá hiện tượng phương sai sai số thay đổi.
Phần này chúng ta sẽ nghiên cứu một số cách thức khắc phục hiện tượng này.
9.3.1 Phương pháp bình phương nhỏ nhất có trọng số và đổi biến số
Theo Gujarati & Porter (2009) và Fox(2002), nếu chúng ta biết các phương sai σi thì chúng ta có thể
thu được các ước lượng có tính chất BLUE bằng cách chia các quan sát cho phương sai σi của chúng.
Cách tiếp cận này gọi là phương pháp bình phương nhỏ nhất có trọng số WLS (Weighted Least
Squares). Tuy nhiên trong thực tế chúng ta gần như không thể thực hiện WLS vì rằng những giá trị
phương sai là chúng ta không thể biết. Gujarati (2011) đưa ra cách tiếp cận thay thế cho vấn đề này
là sử dụng phương pháp đổi biến số. Cụ thể:
1. Nếu phương sai sai số ngẫu nhiên là tỉ lệ với bình phương của một biến độc lập nào đó chúng
ta có thể chia cả hai vế của phương trình hồi quy gốc cho biến số đó. Sau đó, chúng ta thực
hiện một trong các kiểm định (như BP Test, White Test) cho mô hình mới này. Nếu kiểm định
chỉ ra không có bằng chứng cho thấy có phương sai sai số thay đổi thì chúng ta có thể nói cách
biến đổi là thích hợp và mô hình mới không còn hiện tượng phương sai sai số thay đổi. Nếu
phương sai sai số ngẫu nhiên là tỉ lệ với một biến độc lập nào đó chúng ta có thể chia cả hai
vế của phương trình hồi quy gốc cho căn bậc hai biến số đó rồi thực hiện các kiểm định thông
thường như ở trên. Tuy nhiên, trong cả hai tình huống chúng ta lại phải đối diện với một câu
hỏi khó: bằng cách nào chúng ta có thể biết phương sai là tỉ lệ với bình phương của một biến
hay tỉ lệ với một biến số nào đó trong số rất nhiều biến độc lập có thể có trong mô hình? Thứ
hai, nếu một số biến độc lập nào đó mà bằng 0 thì rõ ràng phép biến đổi của chúng ta không
thực hiện được vì phép chia vô nghĩa. Trong nhiều tình huống, khó khăn này có thể được giải
quyết bằng cách thay vì chúng ta chia cả hai vế của mô hình gốc cho biến cụ thể nào đó chúng
ta có thể chia cả hai vế cho giá trị Ŷ ước lượng thu được từ mô hình. Mô hình này được gọi là
mô hình biến đổi (Transformed Model).
2. Chúng ta cũng có thể lấy logarit cơ số tự nhiên cho biến phụ thuộc. Chú ý rằng cách thức này
chỉ thực hiện được nếu biến phụ thuộc là không âm. Mô hình này gọi là mô hình loga biến phụ
thuộc (Logarithmic Model).
Để minh họa, mục này chúng ta sử dụng lại bộ số liệu ch4bt8.wf1 ở trên cho mô hình:
Giả sử rằng phương sai là tỉ lệ với EDUC2. Do vậy chúng ta chia cả hai vế của mô hình này cho EDUC
được mô hình mới là:
##
## Call:
## lm(formula = I(WAGE/EDUC) ~ I(1/EDUC) + I(AGE/EDUC), data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -56.650 -18.461 -3.043 15.508 171.162
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 62.347 5.904 10.560 < 2e-16 ***
## I(1/EDUC) 2001.362 150.608 13.289 < 2e-16 ***
## I(AGE/EDUC) 18.656 3.759 4.963 8.27e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 27.74 on 932 degrees of freedom
## Multiple R-squared: 0.5675, Adjusted R-squared: 0.5666
## F-statistic: 611.5 on 2 and 932 DF, p-value: < 2.2e-16
Chúng ta lại sử dụng một trong các kiểm định, chẳng hạn BP Test bằng hồi quy phụ cho mô hình thu
được sau biến đổi:
##
## Call:
## lm(formula = resids2 ~ I(1/EDUC) + I(AGE/EDUC), data = trang)
##
## Residuals:
## Min 1Q Median 3Q Max
## -800.0 -693.6 -463.8 102.4 28551.7
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 742.15 377.77 1.965 0.0498 *
## I(1/EDUC) -2035.19 9637.07 -0.211 0.8328
## I(AGE/EDUC) 71.26 240.55 0.296 0.7671
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1775 on 932 degrees of freedom
## Multiple R-squared: 0.0001022, Adjusted R-squared: -0.002043
## F-statistic: 0.04764 on 2 and 932 DF, p-value: 0.9535
Do Fqs = 0.04764 ứng với p-value = 0.9535 > 5% nên chúng ta kết luận rằng không tồn tại phương
sai sai số thay đổi trong mô hình 2.
Chúng ta cũng không cần phải thực hiện hồi quy phụ mà có thể làm trực tiếp như sau:
bptest(hello2)
##
## studentized Breusch-Pagan test
##
## data: hello2
## BP = 0.095586, df = 2, p-value = 0.9533
Do giá trị p-value = 0.9533 > 5% nên chúng ta có bằng chứng thống kê chấp nhận Ho của cặp giả
thuyết sau:
Ho: phương sai là không đổi; H1: phương sai là thay đổi.
Như vậy, bằng ít nhất hai cách khác nhau chúng ta có kết luận rằng mô hình 2 có phương sai sai số
không đổi. Đến đây bạn dễ dàng bị lôi cuốn với ý tưởng rằng mô hình 2 là một mô hình tốt để miêu tả
mối liên hệ giữa mức lương và các biến khác. Tuy nhiên như các bạn có thể thấy: rất khó có thể mô tả
mối liên hệ, chẳng hạn, quan hệ giữ giáo dục và mức lương ở mô hình 2. Trong khi mối liên hệ này lại
vô cùng dễ hiểu và dễ diễn đạt ở mô hình 1: cứ tăng 1 năm học thì mức lương tăng β3 đơn vị. Còn mô
hình 2, nếu giáo dục tăng 1 năm thì mức lương biến động ra sao? Điều này một lần nữa nhắc nhở bạn
về sự đánh đổi trong việc xây dựng mô hình kinh tế lượng: bạn có một mô hình mà xử lý đươc vấn đề
phương sai sai số thay đổi nhưng bạn rất khó (và trong nhiều trường hợp là không thể) diễn đạt được
các kết quả của chính mình. Ngoài ra, cách đổi biến số như vậy cũng còn có hạn chế khác. Thực vậy,
chúng ta không thể nào xác định đượng dạng thức của phương sai, chưa kể nếu mô hình có nhiều biến
độc lập thì vấn đề ở đây là, chẳng hạn, chia hai vế của phương trình ban đầu cho biến số nào? Đây
cũng là nhược điểm chung của các phương pháp đổi biến (Transformed Model) khi thực hiện các mô
hình hồi quy.
𝑦𝜆 − 1
𝘨𝜆 (𝑦) = { 𝜆 , 𝜆≠0
lo𝗀𝑦, 𝜆=0
Trong đó tham số λ được ước lượng theo phương pháp xác suất hợp lý cực đại (maximum likelihood)
để đạt giá trị lớn nhất cho hàm:
𝑛
𝐿(𝜆) = − lo𝗀(RSS𝜆 /𝑛) + (𝜆 − 1) ∑ lo𝗀𝑦𝑖
2
Trong đó RSSλ là tổng phần dư bình phương với gλ(y) là biến độc lập. Chi tiết của biến đổi Box – Cox
bạn có thể xem thêm ở nhiều tài liệu khác nhau. Ở đây chúng ta chỉ quan tâm đến khía cạnh thực hành
của việc áp dụng phép biến đổi này cho xử lý vấn đề phương sai sai số thay đổi. Theo Sheather (2009)
và Faraway (2015), biến đổi Box – Cox có thể áp dụng cho: (1) biến độc lập, (2) biến phụ thuộc, và (3)
cả biến phụ thuộc lẫn biến độc lập.
Với R chúng ta có thể sử dụng nhiều gói khác nhau để thực hiện biến đổi này. Tuy nhiên trong tài liệu
này chúng ta sẽ sử dụng gói caret (gói này cũng được sử dụng trong nhiều áp dụng ở các chương
sau). Dưới đây chúng ta sẽ sử dụng biến đổi Box – Cox cho bộ dữ liệu ở mục 9.3.1. Biến số bị biến đổi
là WAGE với tên gọi mới là luong:
setwd("D:/KTLR")
library(hexView)
trang <- readEViews("ch4bt8.wf1", as.data.frame = TRUE)
luong <- trang[, 14] # Lấy biến thứ 14 từ trang.
dung <- data.frame(luong) # Tạo một data frame tên dung với chỉ một biến là
luong (thực chất là WAGE)
library(caret)
chuanbi <- preProcess(dung, method = c("BoxCox"))
chuanbi # Xem các thông số của Box - Cox Transformation.
## Pre-processing:
## - Box-Cox transformation (1)
## - ignored (0)
##
## Lambda estimates for Box-Cox transformation:
## -2
Dung <- predict(chuanbi, dung) # Thực hiện Box - Cox Transformation cho data
frame dung. Thực chất là chỉ có một biến WAGE mà thôi.
# Dưới đây là các câu lệnh so sánh Histogram trước và sau đổi biến. Chúng ta
thấy Histogram sau khi biến đổi là đối xứng hơn so với ban đầu.
par(mfrow=c(1, 2))
hist(dung$luong, col = "green", prob = T, main = "Histogram cua luong")
hist(trang$WAGE, col = "green", prob = T, main = "Histogram cua WAGE")
par(mfrow=c(1, 1))
trang$luong <- dung$luong # Ghép luong vào data frame tên trang.
love <- lm(data = trang, luong ~ AGE + EDUC)
library(lmtest)
bptest(love) # Thực hiện kiểm định Breusch-Pagan.
##
## studentized Breusch-Pagan test
##
## data: love
## BP = 5.2506, df = 2, p-value = 0.07242
Do giá trị p-value = 0.07242 > 5% nên chúng ta có bằng chứng thống kê chấp nhận Ho của cặp giả
thuyết sau:
Ho: phương sai là không đổi; H1: phương sai là thay đổi.
Nghĩa là mô hình hồi quy sau khi thực hiện biến đổi Box – Cox cho biến WAGE có phương sai sai số
ngẫu nhiên là không đổi.
Biến đổi Box – Cox chỉ có thể thực hiện nếu biến số bị biến đổi là dương. Trong tình huống biến số bị
biến đổi ngoài giá trị dương còn có giá trị âm hoặc có giá trị 0, theo Weisberg (2001) chúng ta có thể
sử dụng một phiên bản mạnh hơn của biến đổi Box – Cox là biến đổi Jeo – Johnson. Lý thuyết cho biến
đổi này là rất mới –lý thuyết của phương pháp biến đổi này xuất phát từ nghiên cứu có tên “A new
family of power transformations to improve normality or symmetry “ đăng trên tạp chí Biometrika
năm 2001 của Yeo và Johnson – nhưng đã chứng tỏ sức mạnh của nó trong nhiều tình huống. Để thực
hiện biến đổi này, tất cả các câu lệnh ở trên giữ nguyên nhưng method=c("BoxCox") sẽ được thay
bằng method=c("YeoJohnson"). Bằng cách biến đổi này, thực hiện Breusch-Pagan test cho mô hình
hồi quy mới sẽ có p-value = 0.08286 > 5% nên chúng ta có bằng chứng thống kê đủ mạnh chỉ ra rằng
mô hình mới có phương sai sai số không đổi.
Trong các biến đổi Box – Cox và Jeo – Johnson ở trên, chúng ta mới chỉ áp dụng cho biến phụ thuộc.
Trong thực tế, chúng ta có thể áp dụng cho biến độc lập hoặc cả biến phụ thuộc cũng như biến độc lập
trong mô hình. Dưới đây là các lệnh thực hiện trong R với Box – Cox Transformation cho cả biến độc
lập lẫn phụ thuộc cho mô hình gốc:
##
## Call:
## lm(formula = WAGE ~ ., data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.579e-08 -5.453e-09 3.079e-10 5.931e-09 2.968e-08
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.000e-01 1.866e-08 2.680e+07 < 2e-16 ***
## AGE 1.691e-08 2.949e-09 5.734e+00 1.33e-08 ***
## EDUC 1.482e-07 1.391e-08 1.065e+01 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 8.464e-09 on 932 degrees of freedom
## Multiple R-squared: 0.1323, Adjusted R-squared: 0.1304
## F-statistic: 71.03 on 2 and 932 DF, p-value: < 2.2e-16
library(lmtest)
bptest(hoiquy)
##
## studentized Breusch-Pagan test
##
## data: hoiquy
## BP = 4.4442, df = 2, p-value = 0.1084
Do giá trị p-value = 0.1084 > 5% nên chúng ta có bằng chứng thống kê chấp nhận giả thuyết rằng
phương sai sai số ngẫu nhiên của mô hình sau khi đổi biến là không đổi.
Hai phép biến đổi mà chúng ta sử dụng nhằm xử lý hiện tượng phương sai sai số thay đổi ở trên dù
có nền tảng lý thuyết vững chắc nhưng nó vẫn còn một nhược điểm. Chẳng hạn, với biến đổi Box –
Cox cho biến phụ thuộc WAGE thì λ = -2. Nghĩa là WAGE được biến đổi thành luong = (1 – WAGE-2)/2
và do vậy rất khó diễn giải các kết quả hồi quy thu được ở mô hình mới. Đây là nhược điểm chung của
phương pháp đổi biến. Tuy nhiên, so với các cách thức đổi biến khác thì biến đổi Box – Cox và Yeo –
Johnson thường được sử dụng hơn.
Chú ý rằng các biến đổi Box – Cox và Yeo – Johnson còn được sử dụng nhằm biến đổi một biến có
phân phối không đối xứng thành biến có phân phối đối xứng hơn.
Chương này chúng ta sẽ nghiên cứu các lỗi định dạng mô hình (Model Specification Errors) bao gồm lỗi
dạng hàm sai, thêm biến không cần thiết, bỏ sót biến quan trọng, lỗi đo lường biến số và một số vấn đề
khác mà sách giáo trình không đề cập như sự tồn tại của các quan sát bất thường (Outliers) trong mô
hình. Ngoài ra chương này cũng đề cập đến tiêu chuẩn thông tin Akaike, Schwarz, và Mallows cho việc
lựa chọn mô hình cũng như các kiểm định chẩn đoán lỗi định dạng mô hình.
1. Các dự đoán thu được từ mô hình phải là logic và hợp lý (be data admissible).
2. Phải phù hợp với lý thuyết (be consistent with theory). Nghĩa là mô hình phải có ý nghĩa kinh
tế (economic sense). Chẳng hạn, nếu hàm tiêu dùng của Keynes là đúng thì hệ số hồi quy của
thu nhập phải bé hơn 1 và dương.
3. Có các biến độc lập là nội sinh yếu (have weakly exogenous regressors). Nghĩa là biến giải
thích phải không tương quan với sai số ngẫu nhiên. Ngoài ra, trong một số tình huống thì yêu
cầu này còn cao hơn: chúng phải là các biến nội sinh chặt (strictly exogenous) – là các biến số
mà độc lập với sai số ngẫu nhiên hiện tại, quá khứ, và tương lai.
4. Ổn định về tham số (parameter constancy). Nghĩa là các giá trị của tham số nên là ổn định .
Nếu điều này không thoản mãn thì sử dụng mô hình cho dự báo là rất khó khăn.
5. Các sai số ngẫu nhiên thu được từ mô hình phải là ngẫu nhiên thuần túy (purely random) –
hay nhiễu trắng (white noise).
6. Có khả năng giải thích được kết quả của các mô hình cạnh tranh.
Chúng ta lại giả sử rằng một nhà nghiên cứu khác lại sử dụng mô hình sau:
𝑌𝑖∗ = 𝛽1∗ + 𝛽2∗ 𝑋𝑖∗ + 𝛽3∗ 𝑋𝑖∗2 + 𝛽4∗ 𝑋𝑖∗3 + 𝑢𝑖∗ (7)
Trong đó:
Y*i =Yi +εi và X*i =Xi +wi với εi và wi là sai số của phép đo (errors of measurement). Nếu mô hình (1) là
mô hình đúng thì:
Mô hình (2) gọi là bỏ sót biến quan trọng (omitting a relevant variable).
Mô hình (4) gọi là thêm biến không cần thiết (including an irrelevant variable).
Mô hình (6) gọi là dạng hàm sai (wrong functional form).
Mô hình (7) gọi là lỗi đo lường (errors of measurement bias).
1. Nếu biến bỏ sót là tương quan với một (hay một số) biến độc lập trong mô hình thì các hệ hồi
quy của mô hình sẽ là các ước lượng chệch (Biased). Ngoài ra, tính chất này còn không biến
mất khi kích cỡ mẫu được tăng lên. Nghĩa là các ước lượng còn là không vững (Inconsistent).
2. Nếu các biến bỏ sót là không tương quan với một (hay một số) biến trong mô hình thì hệ số
chặn là ước lượng chệch.
3. Ước lượng cho σ2 là không chính xác.
4. Phương sai ước lượng của các hệ số hồi quy là chệch dẫn đến các sai số chuẩn ước lượng là
chệch dẫn đến các méo mó về khoảng tin cậy và các tham số được ước lượng.
5. Các dự báo về khoảng tin cậy từ mô hình bỏ sót biến là không thực tế.
năm 1995 với mẫu là 1289 người. Chúng ta chỉ thị cho R nhập vào bộ dữ liệu này ở dạng data.frame
với tên gọi table1:
setwd("D:/KTLR")
library(foreign)
table1<-read.dta("Table1_1.dta")
attach(table1)
Để minh họa, trước hết chúng ta chạy mô hình có tên mse1 như sau:
##
## Call:
## lm(formula = wage ~ female + nonwhite + union + education + exper,
## data = table1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -20.781 -3.760 -1.044 2.418 50.414
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -7.18334 1.01579 -7.072 2.51e-12 ***
## female -3.07488 0.36462 -8.433 < 2e-16 ***
## nonwhite -1.56531 0.50919 -3.074 0.00216 **
## union 1.09598 0.50608 2.166 0.03052 *
## education 1.37030 0.06590 20.792 < 2e-16 ***
## exper 0.16661 0.01605 10.382 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.508 on 1283 degrees of freedom
## Multiple R-squared: 0.3233, Adjusted R-squared: 0.3207
## F-statistic: 122.6 on 5 and 1283 DF, p-value: < 2.2e-16
##
## Call:
## lm(formula = wage ~ female + nonwhite + union + education + exper +
Như chúng ta đã biết theo kinh tế học lao động thì kinh nghiệm và mức lương có mối quan hệ hình
chữ U ngược. Điều này được thể hiện qua hệ số hồi quy của exper và I(exper^2). Như vậy, giả sử rằng
mse2 là mô hình đúng thì mô hình mse1 là mô hình thiếu biến quan trọng là I(exper^2). Nói cách
khác, nếu mse2 là mô hình đúng thì hệ số hồi quy của I(exper^2) khác không (Gujarati, 2011). Như
vậy, chúng ta có thể sử dụng kiểm định Wald. Thực hiện trong R như sau:
library(AER)
linearHypothesis(mse2, "I(exper^2) = 0")
Chúng ta có Pr(>F) = 0 (ứng với F = 25.396) nên chúng ta có bằng chứng thống kê cho thấy mse1 là
mô hình bỏ sót biến I(exper^2).
Nếu sử dụng kiểm định F thì mse1 là mô hình bị giới hạn còn mse2 là mô hình không bị giới hạn. Áp
dụng công thức trên ta có giá trị của thống kê F là:
## [1] 25.62411
## [1] 3.848723
Do 25.624 > 3.845 nên chúng ta có bằng chứng thống kê chấp nhận H1. Nghĩa là mô hình mse1 là mô
hình thiếu biến.
Tất nhiên, chúng ta có thể sử dụng một số câu lệnh khác để ra kết quả này (xem lại mục 6.4). Chẳng
hạn:
anova(mse2, mse1)
1. Chạy mô hình thiếu biến mse1 để thu được các ước lượng của wage với tên biến là fit.
2. Chạy một hồi quy phụ (chúng ta gọi là ramsey) với các biến như ở mô hình mse1 nhưng có
thêm fit2, fit3. Nếu cần, có thể thêm cả các lũy thừa cao hơn nữa của fit.
3. Tính thống kê F với mse1 là mô hình giới hạn, ramsey là mô hình không bị giới hạn. Nếu thống
kê F này lớn hơn Fα(m,n-k) thì chúng ta bắc bỏ giả thuyết rằng mse1 là mô hình đúng (không
thiếu biến) và chấp nhận giả thuyết rằng mô hình ramsey là mô hình đúng.
Ý tưởng của kiểm định này là đơn giản và rõ ràng. Nếu mô hình mse1 là mô hình đúng thì các hệ số
hồi quy của các biến thêm vào fit2, fit3 (hay các lũy thừa cao hơn của fit) tất cả chúng phải bằng 0
(không có ý nghĩa thống kê) . Nếu một trong số chúng khác không (có ý nghĩa thống kê) thì mse1 là
mô hình thiếu biến.
##
## Call:
## lm(formula = wage ~ female + nonwhite + union + education + exper +
## I(fit^2) + I(fit^3), data = table1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -25.769 -3.483 -0.997 2.324 50.870
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.4129809 2.4536171 1.799 0.0723 .
## female -0.0590166 0.7975349 -0.074 0.9410
## nonwhite -0.1954657 0.6316463 -0.309 0.7570
## union 0.1241080 0.5641605 0.220 0.8259
## education 0.0801244 0.3023952 0.265 0.7911
## exper 0.0009687 0.0424703 0.023 0.9818
## I(fit^2) 0.0447380 0.0207669 2.154 0.0314 *
## I(fit^3) -0.0003106 0.0006007 -0.517 0.6052
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.413 on 1281 degrees of freedom
## Multiple R-squared: 0.344, Adjusted R-squared: 0.3404
## F-statistic: 95.94 on 7 and 1281 DF, p-value: < 2.2e-16
anova(ramsey, mse1)
Chúng ta có Pr(>F) = 2.483*10-9 (ứng với thống kê F = 20.124) là rất bé nên chúng ta chấp nhận giả
thuyết rằng mse1 là mô hình thiếu biến.
Cách tiếp cận dùng thống kê F như trên cần thực hiện hồi quy phụ với lắm thủ tục lằng nhằng. Chúng
ta có thể tính trực tiếp thống kê F này cũng như p-value tương ứng của nó bằng lệnh resettest() của
gói lmtest:
library(lmtest)
resettest(mse1)
##
## RESET test
##
## data: mse1
## RESET = 20.124, df1 = 2, df2 = 1281, p-value = 2.483e-09
Tuy dễ thực hiện nhưng kiểm định này có hai nhược điểm. Thứ nhất, nếu kiểm định chỉ ra rằng mô
hình là thiếu biến thì nó không chỉ ra mô hình thay thế. Thứ hai, kiểm định này không đưa ra bất kì
chỉ dẫn nào cho việc thêm số biến là dừng ở lũy thừa bao nhiêu của fit mặc dù trong thực tế chúng ta
có thể thực hiện bằng quá trình thử - làm lại dựa trên các tiêu chuẩn thông tin như Akaike, Schwarz.
1. Chúng ta chạy mô hình mse1 nhằm thu được phần dư với tên gọi resids.
2. Nếu mse1 là mô hình đúng thì phần dư này sẽ không liên quan gì đến bất kì biến số bị bỏ sót
nào, chẳng hạn, là biến I(exper^2).
3. Chúng ta chạy một hồi quy phụ với tên gọi lmt với biến phụ thuộc là resids theo các biến độc
lập xuất hiện ở mse1 cộng với biến bỏ sót I(exper^2).
4. Nếu kích cỡ mẫu là lớn thì nR2 (với R2 thu được từ hồi quy phụ) sẽ tuân theo phân phối χ2(m)
với m bậc tự do (m là số biến bỏ sót). Nếu nR2 lớn hơn χ2(m) với mức ý nghĩa α chọn trước
chẳng hạn, thì chúng ta kết luận mse1 là mô hình bị thiếu biến I(exper^2). Ngược lại thì mse1
là mô hình không thiếu biến.
##
## Call:
## lm(formula = resids ~ female + nonwhite + union + education +
## exper + I(exper^2), data = table1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -19.883 -3.751 -0.855 2.455 50.125
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.235697 1.035710 -1.193 0.233
## female 0.065516 0.361432 0.181 0.856
## nonwhite 0.029237 0.504448 0.058 0.954
## union -0.068997 0.501521 -0.138 0.891
## education -0.046556 0.065937 -0.706 0.480
## exper 0.257856 0.053580 4.813 1.67e-06 ***
## I(exper^2) -0.006183 0.001227 -5.039 5.34e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.447 on 1282 degrees of freedom
## Multiple R-squared: 0.01943, Adjusted R-squared: 0.01484
## F-statistic: 4.233 on 6 and 1282 DF, p-value: 0.0003152
Kết tiếp chúng ta: (1) tính nR2 , và (2) χ2(m) với m = 1 (số biến thiếu) ứng với α = 5%:
0.01943*1289
## [1] 25.04527
qchisq(0.95, 1)
## [1] 3.841459
Chúng ta có thể thấy rằng 25.045 > 3.841 nên chúng ta bắc bỏ giả thuyết rằng mse1 là mô hình đúng
và kết luận rằng mse1 là mô hình thiếu biến exper2.
Khi chúng ta ước lượng hai mô hình này trong R chúng ta thấy mse1 có R2 là 0.323 còn mse3 có R2 là
0.346. Mặc dù sức mạnh giải thích của mse3 lớn hơn mse1 nhưng chúng ta nếu chỉ dựa vào so sánh
hai R2 để đi đến kết luận mse3 là mô hình tốt hơn thì chưa đủ vì các biến phụ thuộc ở hai mô hình là
khác nhau. Để đưa ra quyết định lựa chọn mô hình đúng (thực chất là dạng hàm đúng), Koop (2008)
đề xuất kiểm định như sau:
1. Tính toán trung bình trung bình hình học GM (Geometric Mean) của wage theo công thức GM
= (wage1⨉wage2⨉… wagen)1/n . Trong tình huống của chúng ta, trung bình hình học của lương
là 10.406.
2. Chúng ta tính các biến số mới wage*i = wagei/10.406. Nghĩa là lấy các wagei chia cho trung
bình hình học của nó.
3. Ở các mô hình mse1 và mse3, thay wage bằng wage* chúng ta lần lượt thu được RSS1 và RSS2.
4. Kế tiếp chúng ta tính:
𝑛 𝑅𝑆𝑆1
𝜆= 𝑙𝑛 ( ) ~ χ12
2 𝑅𝑆𝑆2
Nếu λ (tuân theo phân phối χ2 với 1 bậc tự do) có ý nghĩa thống kê thì chúng ta kết luận mse1 là mô
hình phù hợp hơn. Ngược lại, mse3 là mô hình phù hợp hơn.
Để thực hiện kiểm định này theo cách tiếp cận của Koop, chúng ta làm như sau trong R. Trước hết
chúng ta tìm trung bình hình học của wage với sự trợ giúp của gói psych:
library(psych)
geometric.mean(table1)
Kế tiếp chúng ta tính các wage*i và gán cho chúng tên biến là gmw:
attach(table1)
table1$gmw <- wage / 10.406343
Ta thu được RSS1 = 501.820 , RSS2 = 289.766 . Kế tiếp ta tính thống kê λ và so sánh nó với χ2(0.05,
df=1):
## [1] 353.9386
qchisq(0.95, 1)
## [1] 3.841459
Do 353.938 > 3.841 nên chúng ta có thể kết luận mse3 là mô hình phù hợp.
Ngoài cách tiếp cận theo kiểu Koop như trên, theo Nguyễn & Nguyễn (2012) thì chúng ta còn có thể
sử dụng cách tiếp cận do Ramsey (1969) và Davidson & MacKinnon (1981) đề xuất dưới đây.
Để trả lời câu hỏi dạng hàm ở mô hình là đúng hay không ta xét mô hình sau:
CT = γ1+ γ2TN+ γ3TS+ γ4TN2+ γ5TS2+ γ6TN3+ γ7TN3+ γ8TN*TS (Mô hình 2)
Cách tiếp cận này giống như đã được trình bày ở mục 10.3.4. Theo đó nếu mô hình 1 là đúng thì tương
đương với việc chúng ta đưa ra bằng chứng thống kê chấp nhận giả thiết gốc ở cặp giả thuyết sau:
Như vậy, chúng ta có thể sử dụng kiểm định F để thực hiện việc bắc bỏ (hay chấp nhận) Ho. Chúng ta
chỉ thị cho R đọc bộ số liệu này dưới dạng một data.frame có tên gọi là dung. Trong R chúng ta thực
hiện kiểm định này nhanh chóng như sau:
library(hexView)
dung <- readEViews("ch2vd5.WF1", as.data.frame = TRUE)
attach(dung)
mohinh1 <- lm(data = dung, CT ~ TN + TS)
mohinh2 <- lm(data = dung, CT ~ TN + TS + I(TN^2) + I(TS^2) + I(TN^3) +
I(TS^3) + I(TN*TS))
anova(mohinh1, mohinh2)
Thống kê F = 1.322 ứn với Pr(>F) = 0.2868 >5% nên chúng ta có bằng chứng thống kê đủ mạnh để
chấp nhận Ho. Nghĩa là dạng hàm ở mô hình 1 là đúng.
Tuy nhiên, cũng theo Nguyễn & Nguyễn (2012) thì việc thêm nhiều lũy thừa bậc cao sẽ tiêu tốn nhiều
bậc tự do, nhất là với các mô hình có nhiều biến độc lập. Một giải pháp đưa ra là chúng ta có thể sử
dụng lũy thừa bậc hai và ba ước lượng chi tiê u CT̂ (kì kiệu là CTpre trong R) từ mô hình 1 cho mô hình
dưới đây:
Lúc này, nếu mô hình 1 là mô hình đúng thì tương đương với việc chúng ta đưa ra bằng chứng thống
kê chấp nhận giả thiết gốc ở cặp giả thuyết sau:
Chúng ta thực hiện một loạt lệnh sau trong R để thực hiện kiểm định F:
Thống kê F = 0.511 ứn với Pr(>F) = 0.480 >5% nên chúng ta có bằng chứng thống kê đủ mạnh để chấp
nhận Ho. Nghĩa là dạng hàm ở mô hình 1 là đúng.
Ngoài cách sử dụng thống kê F như trên, chúng ta cũng có thể sử dụng lệnh resettest() như đã trình
bày ở mục trên:
resettest(mohinh1)
##
## RESET test
##
## data: mohinh1
## RESET = 2.3879, df1 = 2, df2 = 28, p-value = 0.1103
Ở đây p-value = 0.1103 > 5% nên chúng ta có bằng chứng thống kê đủ mạnh để chấp nhận Ho.
Ý tưởng của cách kiểm định này như sau: nếu dạng hàm ở mô hình 1 là đúng thì khi đưa thêm biến
ước lượng của CT từ mô hình 2 (kí hiệu trong R là CTpre4) vào mô hình 1 thì hệ số ước lượng của
CTpre4 sẽ không có ý nghĩa thống kê (và ngược lại). Do vậy, việc xác định mô hình nào trong hai mô
hình (hay cả hai mô hình) quy về việc kiểm định hai cặp giả thuyết sau:
Căn cứ vào các bằng chứng thống kê thu được chúng ta có 4 tình huống sau:
1. Không bắc bỏ cả Ho lẫn Jo: cả hai mô hình ( hay 2 dạng hàm) đều chấp nhận được.
2. Không bắc bỏ Ho và bắc bỏ Jo: chỉ có dạng hàm ở mô hình 4 là dạng hàm đúng.
3. Bắc bỏ Ho và không bắc bỏ Jo: chỉ có dạng hàm ở mô hình 1 là dạng hàm đúng.
4. Bắc bỏ cả Ho lẫn Jo: Không dạng hàm nào là dạng hàm đúng.
Chúng ta thực hiện ý tưởng kiểm định dạng hàm này như sau trong R:
##
## Call:
## lm(formula = CT ~ TN + TS + CTpre4, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -17.156 -9.970 0.236 5.247 32.893
##
## Coefficients:
##
## Call:
## lm(formula = CT ~ I(TN^2) + I(TS^2) + CTpre, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -17.100 -9.988 0.338 5.140 32.788
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.637e+01 3.517e+01 1.034 0.310
## I(TN^2) 5.519e-06 6.344e-06 0.870 0.391
## I(TS^2) 2.684e-07 2.857e-07 0.939 0.355
## CTpre 9.506e-01 4.645e-02 20.466 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 12.24 on 29 degrees of freedom
## Multiple R-squared: 0.9996, Adjusted R-squared: 0.9995
## F-statistic: 2.209e+04 on 3 and 29 DF, p-value: < 2.2e-16
Căn cứ vào các kết quả thu được kết luận của chúng ta ở đây là: dạng hàm ở mô hình 1 là dạng hàm
đúng (Ho bị bắc bỏ và không bắc bỏ Jo).
Thay vì thực hiện dài dòng như trên chúng ta có thể sử dụng lệnh jtest của gói lmtest:
jtest(mohinh1, mohinh4)
## J test
##
## Model 1: CT ~ TN + TS
## Model 2: CT ~ I(TN^2) + I(TS^2)
Chúng ta thấy rằng hệ số hồi quy của CTpre4 và CTpre có Pr(>|t|) lần lượt là 2.934 và 0 nên chúng ta
vẫn có kết luận tương tự như trên.
Có cùng ý tưởng như cách tiếp cận của Davidson & Mac Kinnon là cách tiếp cận do Mizon & Richard
(1986) đề xuất. Bạn đọc quan tâm đến cách tiếp cận này có thể xem tại trang 214 sách giáo trình kinh
tế lượng của NEU.
Nếu lỗi đo lường xẩy ra với các biến phụ thuộc. Khi đó, mặc dù các ước lượng OLS cũng như phương
sai của các ước lượng thu được vẫn có tính chất không chệch (Unbiased) nhưng các phương sai ước
lượng thu được là lớn hơn so với các phương sai thu được nếu không tồn tại lỗi này (Ipso Factor
Variances).
Nếu lỗi đo lường xẩy ra với các biến độc lập. Lúc này các ước lượng OLS thu được sẽ là các ước lượng
chệnh và không hiệu quả. Nó nghiêm trọng đến mức, mặc dù lỗi đo lường có thể xẩy ra ở một biến số
nhưng nó có thể làm cho các ước lượng thu được ứng với các biến số khác là chệch và không hiệu quả
(Gujarati, 2011). Để xử lý vấn đề này, chúng ta có thể sử dụng phương pháp biến công cụ
(Instrumental Variables) cho những biến số mà chúng ta nghi ngờ là có lỗi đo lường – một vấn đề mà
chúng ta sẽ nghiên cứu kĩ trong các chương sau.
10.7 Lỗi do các quan sát bất thường, đòn bẩy cao, quan sát gây ảnh hưởng
Ngoài các lỗi trên, sự méo mó của mô hình thu được so với mô hình thực tế (Ipso Factor Model) còn
đến từ một trong ba hoặc một sự kết hợp nào đó trong số các nguyên nhân sau:
1. Các quan sát bất thường (Outliers). Đó là những quan sát mà phần dư ứng với chúng quá lớn
về giá trị tuyệt đối so với phần dư của các quan sát còn lại. Nếu bạn nào từng đọc cuốn sách
có tên “Những Kẻ Xuất Chúng” – cuốn sách về những người phi thường (nhưng trong số họ
nhiều người không thành công về mặt tài chính) của Malcolm Gladwell thì chắc chắn nhớ cái
tên này: Outliers.
2. Một quan sát được gọi là có đòn bẩy cao (High Leverage) nếu điểm dữ liệu này quá “khác biệt”
theo một thước đo thống kê nào đó so với dữ liệu còn lại. Một trong các tiêu chí (thước đo)
đánh giá là khoảng cách Cook (Cook’s Distance) mà chúng ta sẽ nghiên cứu ngay sau đây.
Các quan sát có đòn bẩy cao có thể gây ra méo mó đối với các hệ số hồi quy.
3. Quan sát ảnh hưởng (Influence Point). Nếu quan sát có đòn bẩy cao thực tế kéo đường hồi
quy về phía mình thì chúng lúc này có tên gọi mới: điểm dữ liệu ảnh hưởng hay quan sát ảnh
hưởng.
Trên đây chúng ta đã xét đến các quan sát bất thường, quan sát có đòn bẩy cao, quan sát gây ảnh
hưởng. Ước lượng vững (Robust Regression) là một cách tiếp cận thay thế cho ước lượng OLS khi dữ
liệu được phân tích có chứa các quan sát bất thường (Outliers) hoặc các quan sát gây ảnh hưởng
(influential observations) và cũng có thể được sử dụng cho mục đích điều tra các quan sát gây ảnh
hưởng cũng như bất thường.
Để sử dụng ước lượng vững trong R, cần sử dụng đến hai gói là foreign và MASS. Nếu chưa cài đặt hai
gói này trước đó trên máy tính của bạn, cần cài đặt hai gói bằng cách gõ lần lượt hai câu lệnh
install.packages(“foreign”) và install.packages(“MASS”). Kế tiếp, để sử dụng cho phân tích gõ liên
tiếp hai câu lệnh library(foreign), library(MASS). Gói đầu tiên sử dụng để đọc file dữ liệu Stata vào R.
Gói thứ hai gồm các lệnh cho phép chúng ta thực hiện ước lượng vững.
Chúng ta sẽ sử dụng lại bộ số liệu ch2_health.wf1 đã được sử dụng trong chương 4 với kết quả hồi
quy là:
##
## Call:
## lm(formula = HEALTH ~ INCOME, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10396.3 -1272.7 -361.3 1088.0 9019.5
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.264e+03 5.554e+02 2.275 0.0273 *
## INCOME 1.295e-01 2.514e-03 51.514 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3006 on 49 degrees of freedom
## Multiple R-squared: 0.9819, Adjusted R-squared: 0.9815
## F-statistic: 2654 on 1 and 49 DF, p-value: < 2.2e-16
Trong R, chúng ta có thể tìm ra các quan sát bất thường chỉ bằng một vài dòng lệnh đơn giản:
library("ggfortify")
autoplot(hoiquy, which = 1:4, ncol = 2, label.size = 3)
Những quan sát bất thường sẽ được đánh số. Trong tình huống của chúng ta, 4 Graphs chỉ ra rằng các
quan sát, ví dụ, thứ 33, 39, 10 và 5 là các quán sát bất thường căn cứ vào một tiêu chuẩn thống kê
được gọi là khoảng cách Cook (Cook’s Distance). Nghĩa là sự xuất hiện của chúng trong mô hình hồi
quy sẽ có tác động rất mạnh lên các kết quả thu được. Chúng ta có thể xem lại những quan sát này:
Về mặt kĩ thuận, khoảng cách Cook (thường kí hiệu là D) ứng với quan sát thứ i được tính toán bằng
cách loại bỏ quan sát đó ra khỏi mẫu ban đầu, chạy mô hình hồi quy khi không có quan sát đó và tính
toán biểu thức sau:
Trong đó Di là khoảng cách Cook ứng với quan sát thứ i, ŷ j là giá trị dự báo của quan sát thứ j khi mô
hình hồi quy có đầy đủ cac quan sat, con ŷ j(i) là giá trị dự báo của quan sát thứ j khi mô hình hồi quy
được bỏ đi quan sát thứ i, p là số hệ số hồi quy có trong mô hình còn MSE là sai số trung bình bình
phương mà chúng ta đã biết.
R cho phép chúng ta tính toán các Di này bằng hàm cooks.distance() một cách nhanh chóng. Căn
cứ vào khoảng cách Cook thì bất kì quan sát nào có khoảng cách Cook lớn hơn 4/n (với n là số quan
sát trong mẫu ban đầu) thì nó sẽ là một quan sát bất thường. Chúng ta có thể hiểu rõ hơn kết quả vừa
thu được ở trên bằng cách gõ 3 lệnh sau trong R:
Lệnh đầu tiên tạo ra các khoảng cách Cook cho 51 quan sát. Lệnh thứ hai hợp nhất các khoảng cách
này vào data.frame sẵn có dung nhằm tạo ra data.frame mới có tên dung1. Lệnh cuối cùng liệt kê bất
cứ quan sát nào có khoảng cách Cook lớn hơn 4/51.
Khi thực hiện hồi quy OLS thông thường , chúng ta có thể thấy một số quan sát bất thường (hoặc có
đòn bẩy cao). Nếu chúng ta quyết định rằng các bất thường này không phải đến từ nguyên nhân lỗi
vào dữ liệu và do vậy chúng ta không có lý do thuyết phục nào để loại bỏ chúng khỏi mô hình nghiên
cứu. Trong bối cảnh đó, chúng ta có thể sử dụng ước lượng vững cho phân tích. Ý tưởng của phương
pháp này là gán cho các quan sát những trọng số khác nhau dựa trên mức độ ảnh hưởng của chúng.
Lệnh rlm() của gói MASS có thể thực hiện kiểu ước lượng này bằng phương pháp M (M-Estimation)
với trọng số Huber trong tình huống mẫu có những quan sát bất thường hoặc gây ảnh hưởng.
Cách tiếp cận này thuộc về một nhóm được gọi là ước lượng vững (Robust Regression).
Để sử dụng ước lượng vững trong R, cần sử dụng đến gói MASS. Nếu chưa cài đặt gói này trước đó
trên máy tính của bạn, cần cài đặt MASS bằng cách gõ câu lệnh install.packages(“MASS”). Chúng ta
thực hiện hồi quy vững với trọng số Huber như sau trong R:
library(MASS)
robustHuber <- rlm(data = dung, HEALTH ~ INCOME)
summary(robustHuber)
##
## Call: rlm(formula = HEALTH ~ INCOME, data = dung)
## Residuals:
## Min 1Q Median 3Q Max
## -14469.4 -910.9 -181.7 1008.7 6647.3
##
## Coefficients:
## Value Std. Error t value
## (Intercept) 696.3860 350.9770 1.9841
## INCOME 0.1345 0.0016 84.6946
##
## Residual standard error: 1491 on 49 degrees of freedom
Với phương pháp ước lượng này, hệ số hồi quy của INCOME tăng, thống kê t tăng, phương sai ước
lượng của hồi quy giảm từ 3006 xuống còn 1491.
Trên đây tôi đã giới thiệu lệnh rlm với trọng số Huber nhằm xử lý tình huống khi dữ liệu của chúng
ta có các qua sát bất thường. Tuy nhiên, nếu các quan sát này có nguyên nhân là lỗi vào số liệu (Data
Entry Error) thì cách xử lý là .. loại chúng ta khỏi mẫu và chạy OLS bình thường. Trong R chúng ta
thực hiện một loạt lệnh sau:
##
## Call:
## lm(formula = HEALTH ~ INCOME, data = dung, subset = (ID != 5 &
## 10 & 33 & 39))
##
## Residuals:
## Min 1Q Median 3Q Max
## -6322.6 -703.9 98.6 1097.0 5130.2
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.734e+02 4.576e+02 0.379 0.706
## INCOME 1.396e-01 2.524e-03 55.292 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2280 on 48 degrees of freedom
## Multiple R-squared: 0.9845, Adjusted R-squared: 0.9842
## F-statistic: 3057 on 1 and 48 DF, p-value: < 2.2e-16
Chúng ta thấy rằng việc loại các quan sát này ra khỏi mẫu nghiên cứu làm thay đổi đáng kể, ví dụ hệ
số hồi quy và thống kê t của INCOME. Ngoài ra phương sai của hồi quy giảm mạnh từ 3006 xuống chỉ
còn 2280.
R có nhiều gói có thể thực hiện nhiều phương pháp ước lượng vững khác nhau nhưng trong tài liệu
này chúng ta chỉ xét một phương pháp là ước lượng vững với trọng số Huber mà thôi.
Chương 11: Hồi quy với biến công cụ và hồi quy hai giai đoạn 2SLS
Chương này chúng ta sẽ nghiên cứu việc sử dụng các biến công cụ (Instrumental Variables) cũng như
hồi quy hai giai đoạn 2SLS (tên đầy đủ là Two Stage Least Squares – ước lượng bình phương nhỏ nhất
hai giai đoạn) nhằm xử lý hiện tượng biến nội sinh vốn rất phổ biến trong các mô hình kinh tế lượng.
11.1 Nguyên nhân của việc sử dụng biến công cụ cho mô hình hồi quy
Chúng ta xét mô hình đơn giản sau:
Trong đó wage là mức lương, educ là số năm đi học và abil là biến đại diện cho tiềm năng trí tuệ của
người lao động. Chúng ta biết rằng dưới một số giả định của mô hình hồi quy tuyến tính cổ điển thì
chúng ta có thể chọn chỉ số thông minh IQ là một đại diện (proxy) cho tiềm năng trí tuệ của người lao
động và do vậy mô hình trên trở thành:
Lúc đó ước lượng thu được của β1 từ (2) là ước lượng vững (consistent).
Tuy nhiên, vì một lý do nào đó chúng ta không thể tìm được bất kì một biến số nào đại diện cho abil
thì lúc đó ta buộc phải “nhóm” abil vào e và do vậy (1) trở thành:
Trong tình huống này, ước lượng của β1 thu được từ (3) sẽ là ước lượng chệch (biased) và không
vững nếu như biến educ và abil (hay educ và u) là tương quan với nhau. Lúc này chúng ta có thể nói
educ là biến nội sinh (endogenous) với ý nghĩa rằng biến này có tương quan với sai số ngẫu nhiên u.
Chúng ta vẫn có thể sử dụng mô hình (3) nhằm tìm ước lượng cho β1 miễn là chúng ta tìm được một
biến đại diện (proxy) cho educ. Tổng quát hơn chúng ta xét mô hình:
y = β0 + β1x + u (4)
Nếu chúng ta tin rằng x và u là tương quan, tức là Cov(x,u) ≠ 0 thì để có được các ước lượng vững cho
các hệ số hồi quy chúng ta tìm một đại diện z của biến x sao cho hai điều kiện sau thỏa mãn:
Cov(z,u) = 0 (5)
Cov(z,x) ≠ 0 (6)
Biến z thỏa mãn hai điều kiện này thì z được gọi là biến công cụ (Intrumental Variable, viết tắt là IV)
của x. Trong nhiều tình huống có thể gọi tắt là công cụ của x.
Theo Wooldridge (2013), điều kiện (5) liên quan đến việc đánh giá tương quan giữa z và sai số ngẫu
nhiên không thể quan sát được u nên chúng ta gần như không thể nào kiểm tra được điều kiện này.
Thay vào đó, trong hầu hết các trường hợp chúng ta phải chấp nhận điều kiện (5) là thỏa mãn. Riêng
điều kiện (6) thì chúng ta có thể dễ dàng kiểm tra bằng nhiều cách, chẳng hạn, thực hiện hồi OLS giữa
hai biến số này.
Trong tình huống chúng ta tìm được biến công cụ (là z) cho x thì ước lượng OLS và ước lượng thu
được từ việc thay x bằng biến công cụ z của nó được tính như sau:
Để thực hiện hồi quy với biến công cụ chúng ta sử dụng lệnh ivreg của gói AER (Kleiber & Zeileis,
2008) theo cú pháp sau:
ivreg(y~x|z)
Để minh họa cho hồi quy biến công cụ, chúng ta sử dụng bộ số liệu MROZ.DTA. Ở đây chúng ta đánh
giá tác động của giáo dục (biến educ) lên mức lương (biến lwage) của phụ nữ trong đó biến fatheduc
(số năm đi học của cha) được chọn là IV cho biến educ. Dưới đây là các dòng lệnh tính trực tiếp ước
lượng cho hệ số hồi quy theo công thức (7) và (8) đồng thời so sánh kết quả thu được từ OLS và IV:
setwd("D:/KTLR")
library(foreign)
trang <- read.dta("MROZ.DTA")
trang <- na.omit(trang) # Xử lý dữ liệu thiếu cho data frame tên trang.
attach(trang)
cov(educ, lwage) / var(educ) # Tính trực tiếp ước lượng OLS theo (7).
## [1] 0.1086487
## [1] 0.05917348
library(AER); library(stargazer)
OLS <- lm(data = trang, lwage ~ educ)
IV <- ivreg(data = trang, lwage ~ educ|fatheduc)
stargazer(OLS, IV, type = "text") # So sánh ước lượng OLS và IV.
##
## ===================================================================
## Dependent variable:
## ------------------------------------
## lwage
## OLS instrumental
## variable
## (1) (2)
## -------------------------------------------------------------------
## educ 0.109*** 0.059*
## (0.014) (0.035)
##
## Constant -0.185 0.441
## (0.185) (0.446)
##
## -------------------------------------------------------------------
## Observations 428 428
## R2 0.118 0.093
## Adjusted R2 0.116 0.091
## Residual Std. Error (df = 426) 0.680 0.689
## F Statistic 56.929*** (df = 1; 426)
## ===================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
So sánh các kết quả chúng ta thấy trước hết các ước lương thu được từ sử dụng trực tiếp công thức
(7) và (8) là trùng với các kết quả thu được từ ước lượng OLS và IV. Ngoài ra so sánh các ước lượng
thu được từ OLS và IV chúng ta thấy khoảng tin cậy 95% thu được từ IV là chứa khoảng tin cậy 95%
thu được từ OLS. Nói cách khác khoảng tin cậy 95% từ OLS là hẹp hơn. Mặc dù sự khác biệt từ hai
ước lượng này là đủ lớn nhưng chúng ta chưa thể nói khác biệt này có ý nghĩa thống kê hay không.
Chúng ta sẽ nghiên cứu vấn đề này ở các mục sau.
Khi sử dụng biến công cụ cho các phân tích chúng ta có thể thấy rằng, chẳng hạn, có thể có nhiều lựa
chọn biến công cụ làm cho educ. Một ứng cử viên khác có thể lựa chọn làm biến công cụ cho educ là
số năm đi học của người mẹ (motheduc). Điều này ngụ ý một vấn đề sâu xa hơn của việc lựa chọn biến
công cụ: một biến công cụ tốt thì được đặc trưng, hay được mô tả, bởi những tiêu chí nào? Theo
Wooldridge (2013) và Greene (2008), biến công cụ cho educ được lựa chọn phải thỏa mãn: (1) không
tương quan với biến abil (khả năng) hay bất cứ nhân tố không quan sát nào được “nhóm” và sai số
ngẫu nhiên u, và (2) tương quan cao nhất có thể được với educ. Nếu chúng ta chọn số chứng minh
nhân dân làm biến công cụ cho educ thì rõ ràng điều kiện thứ nhất được thỏa mãn vì số chứng minh
được lựa chọn ngẫu nhiên và không tương quan gì đến abil tuy nhiên nó cũng không tương quan gì
với educ. Do vậy, chọn số chứng minh làm biến công cụ cho educ thì đây là một biến công cụ yếu
(weak instrumental variable). Chúng ta sẽ nghiên cứu chi tiết việc đánh giá chất lượng của một biến
công cụ được sử dụng bởi các kiểm định chính thức ở các mục sau.
Đối với điều kiện biến được chọn làm biến công cụ phải tương quan với educ (điều kiện 2), ngoài việc
chú ý đến ý nghĩa thống kê chúng ta còn phải chú ý đến dấu, thậm chí là độ lớn của hệ số hồi quy.
Chẳng hạn, ở ví dụ trên chúng ta chọn fatheduc làm biến công cụ cho educ. Rõ ràng trình độ giáo dục
của người cha chắc chắn có ảnh hưởng tích cực lên trình độ giáo dục của con, nghĩa là hệ số hồi quy
của fatheduc phải dương. Để minh họa chúng ta trở lại với việc lựa chọn fatheduc làm biến công cụ
cho educ:
##
## Call:
Kết quả này cho thấy rằng fatheduc có tác động dương (hệ số hồi quy là 0.27), và có ý nghĩa thống kê,
đến educ. Nghĩa là căn cứ vào điều kiện 2, thì việc lựa chọn fatheduc làm biến đại diện cho educ có
thể là hợp lý. Nếu hệ số này mà là âm thì rõ ràng điều này là phi thực tế và do vậy, fatheduc là một lựa
chọn không phù hợp để làm biến công cụ cho educ và chúng ta cần tìm kiếm biến công cụ khác cho
educ.
11.2 Sử dụng đồng thời nhiều biến công cụ cho một biến số
Chúng ta mở rộng mô hình (3) bằng cách đưa vào biến exper:
Ở đây chúng ta giả thiết rằng không giống như educ, biến exper là không tương quan với sai số ngẫu
nhiên w. Bên cạnh đó, ngoài chọn fatheduc, chúng ta còn chọn biến motheduc – giáo dục của người
mẹ làm biến đại diện cho educ. Nghĩa là biến educ được đại diện bởi đồng thời cả hai biến công cụ là
fatheduc và motheduc. Dưới đây là các câu lệnh thực hiện trong R với chú ý rằng biến ngoại sinh xuất
hiện ở cả hai vế của dấu gạch thẳng đứng:
##
## Call:
## ivreg(formula = lwage ~ educ + exper | exper + fatheduc + motheduc)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.03043 -0.32963 0.03599 0.39554 2.24339
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.147841 0.402215 0.368 0.713378
## educ 0.066389 0.031252 2.124 0.034219 *
## exper 0.015488 0.004064 3.811 0.000159 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6762 on 425 degrees of freedom
## Multiple R-Squared: 0.1298, Adjusted R-squared: 0.1257
## Wald test: 9.258 on 2 and 425 DF, p-value: 0.0001159
Tất nhiên chúng ta có thể chọn nhiều hơn hai biến công cụ cho một biến nội sinh.
11.3 Kiểm định biến công cụ yếu, kiểm định Wu-Hausman và Sargan
Như đã trình bày ở phần trước, chúng ta có thể sử dụng một số kiểm định chính thức nhằm đánh giá
sự hợp lý của việc sử dụng biến công cụ. Chúng ta có thể thực hiện đồng thời cả ba kiểm định như sau
(dạng rút gọn):
##
## Diagnostic tests:
## df1 df2 statistic p-value
## Weak instruments 2 424 50.810 <2e-16 ***
## Wu-Hausman 1 424 2.234 0.136
## Sargan 1 NA 0.384 0.536
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Thứ nhất là kiểm định biến công cụ yếu (Test for Weak Instruments) với cặp giả thuyết:
Nếu chúng ta có bằng chứng thống kê bắc bỏ H0 thì việc sử dụng biến công cụ cho mô hình là hợp lý.
Trong tình huống của chúng ta thì p-value là bằng 0 nên chúng ta có thể kết luận rằng việc sử dụng
biến công cụ là phù hợp.
Thứ hai là kiểm định Wu – Hausman. Cặp giả thuyết của kiểm định này có thể được phát biểu ở nhiều
dạng thức khác nhau nhưng trong tình huống của chúng ta sẽ là thuận lợi hơn khi phát biểu cặp giả
thuyết của kiểm định này như sau:
Nghĩa là, nếu chúng ta có bằng chứng chấp nhận giả thuyết gốc thì vấn đề nội sinh không phải là
nghiêm trọng và chúng ta không cần thiết phải sử dụng ước lượng biến công cụ. Ngược lại, nếu chúng
ta bắc bỏ giả thuyết gốc thì có nghĩa là việc sử dụng biến công cụ là cần thiết. Trong tình huống của
chúng ta thì p-value là 0.136 > 5% nên chúng ta có bằng chứng thống kê chấp nhận giả thuyết gốc.
Chú ý rằng trong một số tài liệu (như sách của NEU) cũng như nghiên cứu, kiểm định Wu – Hausman
còn được sử dụng cho kiểm tra tính nội sinh cho một biến số.
Thứ ba là kiểm định Sargan được sử dụng cho cặp giả thuyết thuyết sau:
Kiểm định này được sử dụng cho trường hợp chúng ta sử dụng từ hai biến công cụ trở lên đại diện
cho chỉ một biến nội sinh như trường hợp của chúng ta ở trên. Do p-value = 0.536 > 5% nên có thể
nói fatheduc và motheduc là những biến công cụ phù hợp cho educ.
Thực hiện ước lượng biến công cụ cũng như các phân tích và kiểm định liên quan ngoài sử dụng gói
AER chúng ta còn có thể sử dụng các gói sem (Fox et al., 2014) hoặc lfe (Gaure, 2013). Gần đây nhất
vào tháng 5 năm 2016 xuất hiện gói ivmodel (Jiang et al., 2016) cho thực hiện ước lượng biến công
cụ với nỗ lực tính đến những phát triển mới nhất về lý thuyết liên quan đến ước lượng biến công cụ.
Bạn đọc nào quan tâm có thể tìm hiểu việc sử dụng những gói này cho những phân tích chuyên sâu
nâng cao liên quan đến biến công cụ.
Trong đó lbwght là logarit cơ số tự nhiên trọng lượng (tính theo gam) của trẻ sơ sinh, packs là số gói
thuốc tiêu thụ bởi người mẹ mỗi ngày. Số liệu được sử dụng là BWGHT.DTA. Nếu chúng ta tin rằng
tồn tại hiện tượng nội sinh ở mô hình này, nghĩa là biến packs có tương quan với u và do vậy chúng
ta chọn, chẳng hạn, biến cigprice (giá của một bao thuốc) làm biến công cụ đại diện cho biến packs.
Chúng ta đánh giá lượng biến công cụ cho lựa chọn biến công cụ này:
##
## Call:
## ivreg(formula = lbwght ~ packs | cigprice, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -7.4200 0.1368 0.3055 0.4194 1.1540
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.4481 0.9082 4.898 1.08e-06 ***
## packs 2.9887 8.6989 0.344 0.731
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.9389 on 1386 degrees of freedom
## Multiple R-Squared: -23.23, Adjusted R-squared: -23.25
## Wald test: 0.118 on 1 and 1386 DF, p-value: 0.7312
Như chúng ta có thể thấy hệ số R2 là âm. Nguyên nhân chính là vì chúng ta sử dụng biến cigprice làm
IV cho biến packs là không hợp lý. Nói chính xác hơn cigprice là một biến công cụ yếu như chúng ta
có thể thấy:
##
## Call:
## lm(formula = packs ~ cigprice, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.1106 -0.1061 -0.1032 -0.1015 2.4016
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0674257 0.1025384 0.658 0.511
## cigprice 0.0002829 0.0007830 0.361 0.718
##
## Residual standard error: 0.2987 on 1386 degrees of freedom
## Multiple R-squared: 9.417e-05, Adjusted R-squared: -0.0006273
## F-statistic: 0.1305 on 1 and 1386 DF, p-value: 0.7179
Kết quả này chỉ ra rằng cigprice và packs có tương quan rất thấp. Nói chính xác hơn chúng ta có thể
kết luận giữa hai biến này không có tương quan.
Tất nhiên chúng ta cũng có thể sử dụng kiểm định biến công cụ yếu để đưa kết luận chính thức:
##
## Diagnostic tests:
## df1 df2 statistic p-value
## Weak instruments 1 1386 0.121 0.728
## Wu-Hausman 1 1385 3.489 0.062 .
## Sargan 0 NA NA NA
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Giá trị p-value = 0.728 > 5% nên chúng ta có thể kết luận rằng cigprice là biến công cụ yếu. Chú ý rằng
trong trường hợp này kiểm định Sargan không tồn tại nên có kí hiệu là NA.
11.5 Ước lượng bình phương nhỏ nhất hai giai đoạn 2SLS
Ước lượng bình phương nhỏ nhất 2SLS (còn gọi là hồi quy hai giai đoạn 2SLS) là một cách tiếp cận
tổng quát hơn cho hai tình huống sau.
Tình huống thứ nhất là mô hình của chúng ta có một biến nội sinh nhưng chúng ta sử dụng từ hai biến
công cụ trở lên làm đại diện cho nó. Tình huống này chúng ta đã xét ở mục 11.2 trước.
Tình huống thứ hai là mô hình của chúng ta có từ hai biến nội sinh trở lên. Để minh họa chúng ta xét
mô hình sau:
Trong đó y2 và y3 là các biến nội sinh (tức là có tương quan với u) và các biến z1, z2, và z3 không tương
quan với u (ngoại sinh). Vì chúng ta có hai biến nội sinh nên chúng ta cần ít nhất hai biến công cụ đại
diện cho y2 và y3. Giả sử hai biến công cụ ấy là z4 và z5. Tên gọi hồi quy hai giai đoạn 2SLS bắt nguồn
từ thực tế sau khi thực hiện hồi quy cho mô hình trên.
Giai đoạn 1 (Stage1) chúng ta lần lượt thực hiện hai hồi quy OLS cho y2 và y3 đối với các biến từ z1
đến z5 nhằm thu được các giá trị ước lượng ŷ 2 va ŷ 3.
Giai đoạn 2 (Stage2) chúng ta thực hiện hồi quy OLS cho y1 đối với các biến ŷ 2 , ŷ 3 và các biến từ z1
đến z3.
Để thực hiện hồi quy hai giai đoạn 2SLS chúng ta sử dụng lệnh ivreg như đã từng làm ở mục 11.2.
Tuy nhiên, để làm sáng tỏ hơn bản chất của hồi quy hai giai đoạn chúng ta trở lại với ví dụ ở mục 11.2
theo hai cách làm khác nhau: sử dụng lệnh lm và lệnh ivreg. Chú ý rằng ở đây chúng ta chỉ có một biến
nội sinh là educ và hai biến công cụ là fatheduc và motheduc:
So sánh chúng ta có thể thấy các giá trị ước lượng cho các hệ số là không khác biệt (có một số kết quả,
chẳng hạn sai số chuẩn của hệ số tự do là có khác biệt chừng 5% nhưng đây chỉ là kết quả của việc
làm tròn số trong tính toán của R). Ở đây các bạn cũng cần chú ý rằng chúng ta không thể so sánh R2
từ lệnh lm và ivreg. Nguyên nhân là đối với ước lượng IV, công thức R2 =1 - SSR/SST có thể tạo ra kết
quả âm vì có thể xẩy ra tình huống SSR lớn hơn SST như chúng ta có thể thấy ở mục 11.4. Điều này
cũng có nghĩa là khi thực hiện các nghiên cứu sử dụng ước lượng IV, báo cáo R2 là không có ý nghĩa.
Bạn đọc quan tâm có thể đọc tại trang 523 cuốn Introductory Econometrics: A Modern Approach
ấn bản lần thứ 5 của Wooldridge. Một số nghiên cứu ở Việt Nam mà tôi có dịp đọc, nhiều tác giả không
chú ý đến chi tiết này nên vẫn trình bày tiêu chí R2 cho các mô hình của mình.
Chương này chúng ta sẽ nghiên cứu một số mô hình cơ bản với dữ liệu bảng (Panel Data) – là một
nhóm dữ liệu được sử dụng nhiều trong nghiên cứu kinh tế - tài chính cũng như một số lĩnh vực khác.
Dữ liệu mảng còn được gọi với các tên gọi khác như dữ liệu mảng, dữ liệu tổng hợp. Các mô hình được
nghiên cứu trong chương này là Pooled OLS, FEM, REM, LSDV cùng một số kiểm định lựa chọn và chẩn
đoán lỗi của mô hình. Các mô hình nâng cao là ước lượng GMM, Hausman – Taylor, biến công cụ IV và
FGLS.
Dữ liệu mảng và phân tích dữ liệu mảng ra đời từ khá sớm và bắt đầu xuất hiện tầm khoảng hơn 50
năm trước của Kuh (1959) về đầu tư, của Mundlak (1961) và Hoch (1962) về hàm sản xuất. Một trong
những bộ dữ liệu mảng nối tiếng (và cũng là nguồn số liệu cho rất nhiều nghiên cứu khác nhau) là bộ
dữ liệu PSID được thu thập và phân tích bởi Đại Học Michigan từ năm 1968
(http://psidonline.isr.umich.edu ) với hơn 4800 hộ gia đình. Tới năm 2003, bộ dữ liệu này đã thu
thập rất nhiều các thông tin về thu nhập, trình độ học vấn, các thông tin về nhân chủng học.. của 7000
hộ gia đình với hơn 65.000 cá nhân (Baltagi, 2005). Tương tự như bộ số liệu PSID của Hoa Kì là bộ dữ
liệu UKHLS của Viện Nghiên Cứu kinh Tế và Xã Hội thuộc Đại Học Essex ở Anh Quốc với thông tin về
40.000 hộ gia đình và xấp xỉ 100.000 các nhân. Vai trò của hai bộ dữ liệu PSID và UKHLS trong việc
nghiên cứu các xu hướng kinh tế, xã hội ở Mĩ và Anh là rất quan trọng và tương đương với bộ dữ liệu
VHLSS được thu thập và tính toán bởi Tổng Cục Thống Kê ở Việt Nam.
Có nhiều cách phân loại Panel Data tùy theo mức độ đầy đủ của bảng dữ liệu và kích thước của bảng
dữ liệu cũng như kích thước giữa tương đối giữa N và T. Việc phân loại này là cần thiết và quan trọng
cho việc lựa chọn mô hình cũng như phương pháp phân tích dữ liệu (Cameron & Trivedi ; Baltagi,
2005) vì chúng có các đặc điểm thống kê khác nhau.
Nếu căn cứ vào mức độ đầy đủ của dữ liệu (Gujarati & Porter, 2009; Cameron & Trivedi, 2009) chúng
ta có dữ liệu bảng cân bằng (Balanced Panel) và dữ liệu bảng không cân bằng (Unbalanced Panel).
Chẳng hạn, nếu như bộ số liệu ở trên, vì một lí do nào đó một trong số 80 công ti ở trên chúng ta không
thể thu được dữ liệu của nó ở năm 2012 thì trong tình huống này chúng ta có dữ liệu bảng không cân
bằng.
Nếu căn cứ vào kích thước tương đối giữa N và T. Nếu T là rất lớn so với N chúng ta có chúng ta có
dữ liệu mảng loại dài (Long Panel Data). Ngược lại, nếu T là rất bé so với N thì chúng ta có dữ liệu
mảng loại ngắn (Short Panel Data). Một điển hình về sử dụng dữ liệu mảng loại ngắn là nghiên cứu
về cấu trúc vốn có tên “Testing trade-off and pecking order theories financing SMEs” của López-
Gracia và Sogorb-Mira (2007). Trong nghiên cứu này, hai tác giả sử dụng các thông tin tài chính của
N= 3,569 doanh nghiệp vừa và nhỏ trong khoảng thời gian nghiên cứu T = 10 năm. Như vậy tỉ số giữa
N và T là 357 lần.
Bằng việc kết hợp cả các đặc điểm của dữ liệu chéo (Cross Sections) và dữ liệu chuỗi thời gian (Time
Series), Baltagi (2005) nêu ra một số lợi thế dưới đây của việc sử dụng Panel Data trong các nghiên
cứu:
1. Vì Panel Data chứa các cá thể khác nhau nên các phân tích có tính đến sự khác biệt đặc trưng
(heterogeneity) cho các cá thể ấy. Nghiên cứu nếu chỉ sử dụng thuần túy dữ liệu chéo hoặc dữ
liệu chuỗi thời gian không kiểm soát khác biệt đặc trưng này vào các mô hình nghiên cứu. Ví
dụ, trong nghiên cứu của Baltagi và Levin (1992) về cầu đối với thuốc lá ở 46 bang của Mĩ
trong giai đoạn 1963 – 1988, cầu được mô hình hóa như là một hàm biến trễ của tiêu dùng,
giá của thuốc, và thu nhập. Những biến số này thay đổi theo từng bang (chiều không gian) và
cả theo thời gian (chiều thời gian). Tuy vậy. có thể có nhiều biến khác là không thay đổi theo
các bang (gọi là individual-invariant) cũng như không thay đổi theo thời gian (time-invariant)
nhưng có ảnh hưởng đến tiêu dùng. Ví dụ, trình độ giáo dục hay tôn giáo. Bỏ qua các biến số
này có thể dẫn đến các ước lượng chệch. Dữ liệu mảng có khả năng kiểm soát các biến số
không đổi theo chiều không gian và thời gian này vào mô hình – điều mà sử dụng dữ liệu chéo
hay dữ liệu thời gian không làm được.
2. Bằng việc kết hợp cả chiều không gian và thời gian lại với nhau, panel data cung cấp “nhiều
thông tin hơn, nhiều bậc tự do hơn, hiệu quả hơn, nhưng ít đa cộng tuyến hơn giữa các biến số”.
3. Sử dụng Panel Data là phù hợp hơn cho các nghiên cứu những động lực (hay nhân tố) của
thay đổi (dynamics of change). Chẳng hạn các nghiên cứu thu nhập, sự di chuyển của lao động
sẽ là tốt hơn nếu sử dụng dữ liệu mảng.
4. Sử dụng Panel Data có thể đánh giá tốt hơn những tác động mà không thể quan sát thấy nếu
sử dữ liệu chéo hay dữ liệu thời gian thuần túy. Chẳng hạn, tác động của mức lương tối thiểu
lên công ăn việc làm và thu nhập có thể được nghiên cứu chính xác hơn khi chúng ta tính đến
sự gia tăng mức lương tối thiểu một cách liên tiếp
5. Panel Data cho phép chúng ta nghiên cứu các mô hình có hành vi phức tạp. Chẳng hạn trong
nghiên cứu kinh tế, các hiện tượng như hiệu quả theo qui mô (economies of scale) hay các
thay đổi về mặt công nghệ có thể được đánh giá tốt hơn nếu sử dụng dữ liệu mảng so với sử
dụng thuần túy dữ liệu chéo hay dữ liệu thời gian (Cornwell, Schmidt & Sickles, 1990;
Kumbhakar & Lovell, 2000; Koop & Steel, 2001).
12.2 Giới thiệu bộ số liệu sử dụng và package cần thiết cho phân tích
Phần này chúng ta sẽ nghiên cứu bộ dữ liệu có tên panel1.dta – ban đầu được thu thập bởi giáo sư
Moshe Kim và được sử dụng lại bởi Greene (2008). Dữ liệu này bao gồm các thông tin về 6 hãng hàng
không (N=6) trong khoảng thời gian 15 năm từ 1970 đến 1984 (T = 15). Như vậy dữ liệu của chúng
ta thuộc loại Long Panel Data. Chúng ta nghiên cứu tổng chi phí C có mối liên hệ như thế nào so với
doanh thu Q, giá nhiên liệu PF, và số chỗ ngồi bình quân của mỗi một chuyến bay LF qua mô hình sau:
Trong đó i chạy từ 1 đến 6, t chạy từ 1 đến 15. Như vậy tổng cộng chúng ta có 6⨉15 = 90 quan sát.
Chúng ta cần sử dụng gói plm cho các phân tích dữ liệu mảng. Trong R chúng ta cài đặt gói này bằng
lệnh install.packages(“plm”).
Chúng ta nhập dữ liệu từ file panel1.dta (Stata file) vào R và gán cho nó tên file mới là dung như sau:
setwd("D:/KTLR")
library(foreign)
library(car)
dung <- read.dta("Panel1.dta")
head(dung) # Xem 6 quan sát đầu tiên.
## i t C Q PF LF
## 1 1 1 1140640 0.952757 106650 0.534487
## 2 1 2 1215690 0.986757 110307 0.532328
## 3 1 3 1309570 1.091980 110574 0.547736
## 4 1 4 1511530 1.175780 121974 0.540846
## 5 1 5 1676730 1.160170 196606 0.591167
## 6 1 6 1823740 1.173760 265609 0.575417
## i t C Q PF LF
## 85 6 10 276797 0.092749 564867 0.554276
## 86 6 11 381478 0.112640 874818 0.517766
## 87 6 12 506969 0.154154 1013170 0.580049
## 88 6 13 633388 0.186461 930477 0.556024
## 89 6 14 804388 0.246847 851676 0.537791
## 90 6 15 1009500 0.304013 819476 0.525775
Các bạn có thể đánh giá xu hướng của chi phí C cho cả 6 hãng theo thời gian:
Từ hình 1 các bạn có thể thấy chi phí C nhìn chung là tăng nhưng hãng 1 và 2 là tăng mạnh hơn cả
(căn cứ vào độ dốc của các đường).
Chúng có thể tìm bảng hệ số tương quan cho các biến số:
cor(dung)
## i t C Q PF LF
## i 1.00000000 0.0000000 -0.7086242 -0.8679359 0.01329393 -0.3399570
## t 0.00000000 1.0000000 0.5000271 0.2711141 0.93118760 0.6001491
## C -0.70862418 0.5000271 1.0000000 0.9263269 0.47904374 0.4143377
## Q -0.86793588 0.2711141 0.9263269 1.0000000 0.22761248 0.4248100
## PF 0.01329393 0.9311876 0.4790437 0.2276125 1.00000000 0.4867001
## LF -0.33995702 0.6001491 0.4143377 0.4248100 0.48670008 1.0000000
Bảng này cho thấy chi phí C có quan hệ cùng chiều với t (hệ số tương quan là +0.5) với ngụ ý rằng chi
phí C tăng theo thời gian. Tương tự, chi phí C là tương quan mạnh nhất với Q, tương quan yếu nhất
với LF. Ngoài ra các hệ số tương quan giữa các biến độc lập với nhau (Q, PF, và LF) là bé hơn 0.8 nên
khó có thể xẩy ra hiện tượng đa cộng tuyến trong mô hình 1.
Các hệ số chặn cũng như hệ số góc là không đổi theo chiều không gian (giữa các hãng) và thời
gian và sai số ngẫu nhiên bao gồm các khác biệt giữa các hãng cũng như theo thời gian.
Hệ số góc là không đổi nhưng hệ số chặn thì thay đổi giữa các hãng (hay hệ số chặn thay đổi
theo chiều không gian) nhưng không đổi theo thời gian.
Hệ số góc là không đổi nhưng hệ số chặn thì thay đổi theo thời gian nhưng không đổi giữa các
hãng.
Hệ số góc là không đổi nhưng hệ số chặn thì thay đổi theo cả chiều không gian lẫn thời gian.
Cả hệ số chặn lẫn hệ số góc thay đổi theo chiều không gian (giữa các hãng) nhưng không thay
đổi theo thời gian.
Cả hệ số chặn lẫn hệ số góc thay đổi theo chiều không gian và thời gian.
Phần dưới đây chúng ta sẽ nghiên cứu một số mô hình đơn giản dựa trên các giả định này.
##
## Call:
## lm(formula = C ~ Q + PF + LF, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -520654 -250270 37333 208690 849700
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.159e+06 3.606e+05 3.213 0.00185 **
## Q 2.026e+06 6.181e+04 32.781 < 2e-16 ***
## PF 1.225e+00 1.037e-01 11.814 < 2e-16 ***
## LF -3.066e+06 6.963e+05 -4.403 3.06e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 281600 on 86 degrees of freedom
## Multiple R-squared: 0.9461, Adjusted R-squared: 0.9442
## F-statistic: 503.1 on 3 and 86 DF, p-value: < 2.2e-16
Nếu căn cứ theo các tiêu chuẩn quy ước thì mô hình thu được có kết quả rất đẹp. Thể hiện ở R2 là cao,
các hệ số hồi quy có dấu phù hợp với kì vọng và có ý nghĩa thống kê ở mức cao. Dựa vào kết quả phân
tích này chúng ta có:
Mặc dù vậy, giả thiết rằng cả 6 hãng có cùng hệ số chặn và hệ số góc không đổi theo thời gian có thể
rất phi thực tế. Chẳng hạn, chúng ta có lí do để tin rằng mỗi một hãng có chi phí ban đầu (initial cost)
là khác nhau, nghĩa là chúng có hệ số chặn khác nhau. Ngoài ra, rất có thể sai số ngẫu nhiên là thay
đổi giữa các hãng hoặc thay đổi theo thời gian. Hoặc vừa thay đổi theo các hãng cũng như theo thời
gian. Chúng ta sẽ nghiên cứu vấn đề này ở các chương sau.
Như đã đề cập ở trên, điểm yếu nhất của Pooled OLS là mô hình này không nói cho chúng ta biết phản
ứng (hay hành vi) của chi phí C có thay đổi giữa các hãng và thay đổi theo thời gian hay không. Nguyên
nhân là bằng cách nhóm tất cả cá quan sát lại bất kể sự khác biệt giữa các hãng và sự thay đổi về hành
vi của chi phí C chúng ta đã bỏ qua sự khác biệt đặc trưng (uniqueness) của các hãng. Nếu chúng ta
xử lý vấn đề này bằng cách “gộp” các đặc trưng cá nhân này vào sai số ngẫu nhiên thì lại dẫn đến tình
huống khó xử khác: sai số ngẫu nhiên có thể tương quan (correlated) ở một mức độ nào đó với biến
độc lập và do vậy là vi phạm các giả định về mô hình hồi quy tuyến tính cổ điển. Điều này có thể làm
cho các ước lượng thu được là chệch (biased) và không vững (inconsistent).
Chú ý rằng kết quả ở trên là tương đương với sử dụng câu lệnh sau:
12.3.2 Mô hình tác động cố định biến giả SLDV và kiểm định gộp
Như đã phân tích ở trên, chúng ta có thể giả định rằng mỗi hãng hàng không có chi phí ban đầu của
riêng nó và không thay đổi theo thời gian. Nghĩa là chúng ta cần ước lượng mô hình sau:
Trong đó, i chạy từ 1 đến 6, t chạy từ 1 đến 15. Theo mô hình này chúng ta có thể thấy dù mỗi một
hãng hàng không có hệ số chặn của riêng mình (đặc trưng cho chi phí ban đầu khác nhau giữa các
hãng) nhưng các hệ số chặn này cố định theo thời gian (time-invariant). Trong tình huống này, hệ số
chặn của mỗi một hãng là không đổi theo thời gian (time invariant). Chú ý rằng, nếu chúng ta kí hiệu
βit thì điều này có nghĩa là các hệ số chặn là thay đổi theo thời gian (time variant).
Để ước lượng mô hình trong đó chúng ta muốn đưa vào các hệ số chặn khác nhau cho mỗi hãng, chúng
ta sử dụng hồi quy với biến giả và (2) được viết thành:
Cit. = β1 + β2D2 + β3D3 + β4D4 + β5D5 + β6D6 + b1itQit. + b2itPFit. + b3itLFit + uit (3)
Trong đó các D2 đến D6 là các biến giả đặc trưng cho hãng cụ thể. Ví dụ, D2 = 1 nếu là hãng thứ 2, bằng
0 nếu không phải. Ước lượng mô hình (3) trong R:
##
## Call:
## lm(formula = C ~ Q + PF + LF + factor(i), data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -551783 -159259 1796 137226 499296
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.312e+05 3.508e+05 -0.374 0.709
## Q 3.319e+06 1.714e+05 19.369 < 2e-16 ***
## PF 7.731e-01 9.732e-02 7.944 9.70e-12 ***
## LF -3.797e+06 6.138e+05 -6.187 2.37e-08 ***
## factor(i)2 6.017e+05 1.009e+05 5.964 6.17e-08 ***
## factor(i)3 1.337e+06 1.862e+05 7.183 2.99e-10 ***
## factor(i)4 1.778e+06 2.132e+05 8.339 1.61e-12 ***
## factor(i)5 1.828e+06 2.312e+05 7.907 1.15e-11 ***
## factor(i)6 1.706e+06 2.283e+05 7.475 8.07e-11 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 210400 on 81 degrees of freedom
## Multiple R-squared: 0.9716, Adjusted R-squared: 0.9688
## F-statistic: 346.9 on 8 and 81 DF, p-value: < 2.2e-16
Căn cứ vào kết quả này chúng ta có thể đưa ra phương trình hồi quy cho hãng thứ nhất và hãng thứ
hai lần lượt là:
Các bạn chú ý rằng hệ số hồi quy của D2 là 601700, hệ số hồi quy của D6 là 1706000. Qua đây chúng
ta cũng có thể thấy R thực hiện LSDV nhanh hơn so với Eviews hay Stata do chúng ta không cần thực
hiện thao tác tạo biến giả do R tự động thực hiện thao tác này khi chạy.
Kết quả này cũng cho thấy: (1) ngoại từ hệ số chặn của hãng thứ nhất thì tất cả các hệ số chặn của 5
hãng còn lại đều có ý nghĩa thống kê, (2) các tiêu chí đánh giá độ phù hợp của mô hình tốt hơn thể
hiện ở tổng bình phương phần dư SSE giảm từ 6.82⨉1012 xuống 3.59⨉1012 và R2 tăng. Mô hình có
biến giả như vậy có thể được gọi bằng một cái tên khác là mô hình tác động cố định bình phương
nhỏ nhất với biến giả (Fixed Effect Least-Squares Dummy Variable (LSDV) Model) hay nói gọn là mô
hình LSDV. Chú ý rằng kết quả ở trên có thể thu đượng bằng cách gõ:
##
## Call:
## lm(formula = C ~ Q + PF + LF + factor(i) - 1, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -551783 -159259 1796 137226 499296
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## Q 3.319e+06 1.714e+05 19.369 < 2e-16 ***
## PF 7.731e-01 9.732e-02 7.944 9.70e-12 ***
## LF -3.797e+06 6.138e+05 -6.187 2.37e-08 ***
## factor(i)1 -1.312e+05 3.508e+05 -0.374 0.709286
## factor(i)2 4.705e+05 3.091e+05 1.522 0.131839
## factor(i)3 1.206e+06 3.324e+05 3.628 0.000497 ***
## factor(i)4 1.646e+06 3.183e+05 5.172 1.64e-06 ***
## factor(i)5 1.697e+06 3.348e+05 5.069 2.48e-06 ***
## factor(i)6 1.575e+06 3.073e+05 5.126 1.98e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 210400 on 81 degrees of freedom
## Multiple R-squared: 0.985, Adjusted R-squared: 0.9834
## F-statistic: 593 on 9 and 81 DF, p-value: < 2.2e-16
Chúng ta có thể đưa ra kiểm định chính thức nhằm xác định xem có thể “gộp” các hệ số chặn đặc trưng
cho từng hãng ở mô hình LSDV bằng kiểm định F mà trong nhiều tài liệu còn gọi là kiểm định tính
gộp - Poolability Test cho mô hình LSDV với cặp giả thuyết sau:
Nếu chúng ta đưa ra bằng chứng thống kê bắc bỏ H0 thì có nghĩa mô hình LSDV là mô hình phù hợp.
Ngược lại thì Pooled OLS là mô hình phù hợp hơn. Trong tình huống của chúng ta thì mô hình có kết
quả ở mục 12.3.1 gọi là mô hình giới hạn (restricted model) vì nó áp đặt một hệ số chặn chung duy
nhất cho cả 6 hãng còn mô hình có kết quả ở mục 11.3.2 là mô hình không giới hạn (unrestricted
model). Áp dụng kiểm định F giới hạn (restricted F test ) chúng ta có:
(0.971642 − 0.946093)/5
𝐹= ≈ 14.59
(1 − 0.971642)/81
So sánh giá trị tới hạn của F0.95,5/81 = 2.373 chúng ta đi đến kết luận là bắc bỏ giả thuyết H0. Kết luận
của chúng ta là tồn tại sự khác biệt về hệ số chặn giữa các hãng hàng không. Trong tình huống ngược
lại – nghĩa là chúng ta có bằng chứng thống kê đủ mạnh để chấp nhận H0 thì chúng ta có thể sử dụng
Pooled OLS để thực hiện phân tích số liệu.
Chúng ta cũng có thể sử dụng kiểm định Wald để kiểm định tính gộp của cho mô hình LSDV (Hill et
al., 2008) trong R:
library(AER)
linearHypothesis(lsdv, c("factor(i)2 = 0", "factor(i)3 = 0", "factor(i)4 = 0"
, "factor(i)5 = 0", "factor(i)6 = 0" ))
Chúng ta có thể tìm lại kiểm định F = 14.595 như ở trên ứng với Pr(>F) = 0 nên chúng ta có thể bắc
bỏ giả thuyết gốc.
Những mô hình được mô tả ở (2 hoặc viết cụ thể hơn ở dạng 3) còn được gọi là mô hình tác động cố
định một chiều (one-way fixed effects) và được hiểu theo nghĩa là mặc dù mỗi hãng có một hệ số chặn
của riêng nó nhưng hệ số chặn này không đổi theo thời gian. Nói cách khác, chúng ta đã tính đến tác
động cá thể (The Individual Effect) đặc trưng cho từng hãng khi nghiên cứu hành vi của chi phí C.
Tương tự như vậy, chúng ta có thể tính đến tác động thời gian (The Time Effect) khi nghiên cứu với
giả định rằng hệ số góc của các hãng là không đổi theo thời gian nhưng hệ số chặn lại biến đổi theo thời
gian bằng cách đưa vào biến giả thời gian như sau:
Trong đó T2 = 1 ứng với năm nghiên cứu thứ 2, bằng 0 nếu khác. Chú ý rằng khoảng thời gian nghiên
cứu của chúng ta là 15 năm và do vậy chúng ta đưa vào 14 biến giả thời gian.
Lập luận như trên, chúng ta có thể nghiên cứu hành vi của chi phí C với giả định rằng hệ số góc của
các hãng là không đổi nhưng hệ số chặn thay đổi theo từng hãng và theo thời gian. Lúc này mô hình
của chúng ta có tất cả 5 + 14 = 19 biến giả như sau:
Cit. = a1 + (λ2T2 +…+ λ15T15) +( β2D2 +…+ β6D6) + b1itQit. + b2itPFit. + b3itLFit + uit (5)
Chúng ta cũng có thể nghiên cứu mô hình với giả định rằng tất cả các hệ số hồi quy (hệ số chặn lẫn hệ
số góc) là khác nhau giữa các hãng nhưng không thay đổi theo thời gian:
Cit. = a1 + (β2D2 +…+ β6D6) + b1itQit. + b2itPFit. + b3itLFit + (D2b1itQit. + D2b2itPFit. + D2b3itLFit) +…+(
D6b1itQit. + D6b2itPFit. + D6b3itLFit)+ uit (6)
Mô hình (6) sẽ bao gồm 5+3+3*5 = 23 biến số và con số sẽ tăng nhanh chóng nếu số lượng các biến
độc lập trong mô hình là nhiều và số cá thể nghiên cứu lên đến hàng trăm. Chẳng hạn, nếu nghiên cứu
vẫn lấy thời gian nghiên cứu là 15 năm nhưng có 10 biến số độc lập với 100 cá thể (một con số còn
quá khiêm tốn trong các nghiên cứu định lượng thực tế) thì các biến số ở vế phải của phương trình
(5) lên đến 99+10+10*99 = 1109 biến số. Qua đây bạn cũng có thể hình dung ra hạn chế rõ ràng của
phương pháp LSDV. Ngoài ra, theo Gujarati & Porter (2009), việc đưa quá nhiều biến giả vào mô hình
cũng gây ra một số vấn đề sau.
Thứ nhất, mỗi khi chúng ta đưa thêm biến giả vào mô hình, thì chúng ta lại phải hi sinh bặc tự do dẫn
đến khả năng chúng ta không có đủ các quan sát để thực hiện các phân tích thống kê có ý nghĩa.
Thứ hai, nguy cơ xẩy ra hậu quả nghiêm trọng do đa cộng tuyến.
Thứ ba và cũng là nhược điểm cốt lõi của các mô hình LSDV là trong một số tình huống nó không thể
xác định tác động của các biến số không đổi theo thời gian (time-invariant variables). Ví dụ, nếu chúng
ta muốn nghiên cứu hàm lương của một mẫu nghiên cứu sử dụng dữ liệu mảng theo kinh nghiệm. Rõ
ràng, ngoài kinh nghiệm thì chúng ta cũng có thể thấy các nhân tố như giới tính, chủng tộc cũng có
ảnh hưởng đến lương nhưng rõ ràng các nhân tố này là không thay đổi theo thời gian. Do vậy, các mô
hình LSDV không có thể không tính đến được tác động của những biến số không đổi theo thời gian
này lên mức lương.
Thứ tư, giả định về sai số ngẫu nhiên có phân phối chuẩn với trung bình bằng 0, độc lập, và phương
sai không đổi là một giả định khó có thể đáp ứng trong thực tế. Ví dụ, tại một thời điểm nào đó, sai số
ngẫu nhiên ứng với hãng thứ nhất có thể tương quan với sai số ngẫu nhiên của hãng thứ hai.
library(plm)
FEM <- plm(C ~ Q + PF + LF, data = dung, index = c("i", "t"), model = "within
")
summary(FEM)
Cũng như Stata, trước khi phân tích thì R cần nhận diện dữ liệu mà nó đang xử lý là dữ liệu mảng.
Trong câu lệnh trên chúng ta đã “gộp” định dạng dữ liệu mảng bằng lựa chọn. Tương tự lệnh xtset của
Stata, chúng ta có thể bỏ lựa chọn này với điều kiện là trước khi phân tích chúng ta chỉ định dữ liệu
được phân tích là dữ liệu mảng. Điều này được trình bày chi tiết ở mục 12.6 của chương này.
Chú ý rằng không như các phần mềm khác (Eviews, Stata), R không đưa ra hệ số chặn chung cho mô
hình (2) vì mô hình FEM bản thân nó đã ngụ ý rằng mỗi một hãng có một hệ số chặn riêng đặc trưng
(như ta đã thấy trong mô hình LSDV). Tuy nhiên nếu muốn chúng ta cũng có thể chỉ ra hệ số chặn
(hay tác động cố định) ứng với mỗi hãng:
fixef(FEM)
## 1 2 3 4 5 6
## -131236.0 470497.3 1205944.6 1646356.2 1697016.5 1575238.4
Đây chính là kết quả mà chúng ta đã thu được ở mô hình LSDV. Chú ý rằng mô hình LSDV ở mục
12.3.2, để tiện so sánh với kết quả vừa thu được chúng ta có thể gõ như sau trong R:
##
## Call:
## lm(formula = C ~ Q + PF + LF + factor(i) - 1, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -551783 -159259 1796 137226 499296
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## Q 3.319e+06 1.714e+05 19.369 < 2e-16 ***
## PF 7.731e-01 9.732e-02 7.944 9.70e-12 ***
## LF -3.797e+06 6.138e+05 -6.187 2.37e-08 ***
## factor(i)1 -1.312e+05 3.508e+05 -0.374 0.709286
## factor(i)2 4.705e+05 3.091e+05 1.522 0.131839
## factor(i)3 1.206e+06 3.324e+05 3.628 0.000497 ***
## factor(i)4 1.646e+06 3.183e+05 5.172 1.64e-06 ***
## factor(i)5 1.697e+06 3.348e+05 5.069 2.48e-06 ***
## factor(i)6 1.575e+06 3.073e+05 5.126 1.98e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 210400 on 81 degrees of freedom
Sử dụng câu lệnh như vậy cho phép chúng ta có thể thấy trực tiếp hệ số chặn của các hãng mà không
cần thực hiện các phép tính trung gian cộng hoặc trừ thường gây nhầm lẫn với những con số dài dòng.
Chú ý rằng hệ số chặn Intercept ở 8.3.2 chính là factor(i)1 ở câu lệnh này và đây cũng là hệ số chặn
của hãng thứ nhất. Còn hãng thứ hai hệ số chặn tương ứng là factor(i)2 = 470500.
Chúng ta cũng có thể thực hiện kiểm định tính gộp của mô hình FEM theo một cách khác:
pFtest(FEM, ols)
##
## F test for individual effects
##
## data: C ~ Q + PF + LF
## F = 14.595, df1 = 5, df2 = 81, p-value = 3.467e-10
## alternative hypothesis: significant effects
Ở đây giá trị của kiểm định F = 14.595 (đã thấy ở các kiểm định mà chúng ta đã thực hiện ở trước đó)
ứng với P-value = 0 nên mô hình FEM là mô hình phù hợp so với Pooled OLS. Các giá trị kiểm định
thu được cũng như kết luận là không có gì thay đổi so với các kết luận ở mục 12.3.2.
Ý tưởng của cách tiếp cận này như sau. Nếu các biến giả trong thực tế là đại diện cho những hiểu biết
chưa đầy đủ của chúng ta về mô hình thật thế thì tại sao chúng ta lại không biểu diễn các hệ số chặn
βi thành hai bộ phận như sau:
Nghĩa là, thay vì coi hệ số chặn βi của các hãng là cố định thì chúng ta coi hệ số chặn này là một biến
ngẫu nhiên gồm hai bộ phận với trung bình β1 (không có kí hiệu i ở đây) và sai số ngẫu nghiên εi với
phương sai không đổi σ2ε . Như vậy phương trình (6) trở thành:
Trong đó wit = εi + uit . Nghĩa là chúng ta tách sai số ngẫu nhiên wit thành hai bộ phận: đại diện cho
bộ phận sai số ngẫu nhiên đặc trưng cho từng hãng riêng biệt và uit đại diện cho bộ phận sai số ngẫu
nhiên kết hợp theo cả chiều không gian và thời gian. Chính vì thế cách tiếp cận này còn được gọi là
mô hình sai số bộ phận ECM (Gujarati & Porter, 2009) với các giả định sau:
𝜀𝑖 ~𝑁(0, 𝜎𝜀2 )
𝑢𝑖𝑡 ~𝑁(0, 𝜎𝑢2 )
𝐸(𝑤𝑖𝑡 ) = 0
var(𝑤𝑖𝑡 ) = 𝜎𝜀2 + 𝜎𝑢2
Nếu σ2ε = 0 thì có nghĩa là chúng ta có thể hiện hồi quy gộp cho (8). Ngoài ra chúng ta có thể thấy rằng
wit và wis là tương quan với nhau với t ≠ s. Nghĩa là sai số ngẫu nhiên của một cá thể bất kì là tương
quan với nhau tại hai thời điểm khác nhau theo chiều thời gian. Lúc này, tương quan giữa wit và wis
được tính theo công thức sau:
𝜎𝜀2
corr(𝑤𝑖𝑡 , 𝑤𝑖𝑠 ) = 2 (10)
𝜎𝜀 + 𝜎𝑢2
Gujarati & Porter (2009), Baltagi (2005) đưa ra các kết luận sau về tương quan giữa wit và wis . Thứ
nhất, đối với một cá thể nhất định (trong tình huống của chúng ta là hãng) thì tương quan này không
đổi bất kể khoảng cách giữa hai quãng thời gian là bao nhiêu. Thứ hai, tương quan này là như nhau
cho mọi cá thể. Nếu chúng ta bỏ qua tương quan này trong phân tích thì chúng ta áp dụng OLS và các
ước lượng thu được là không hiệu quả (inefficient). Để giải quyết vấn đề này chúng ta sử dụng mô
hình tác động ngẫu nhiên REM (Random Effect Model). Trong R chúng ta thực hiện như sau:
REM <- plm(C ~ Q + PF + LF, data = dung, index = c("i", "t"), model="random")
summary(REM)
## theta: 0.3754
##
## Residuals :
## Min. 1st Qu. Median 3rd Qu. Max.
## -531000 -242000 50200 204000 783000
##
## Coefficients :
## Estimate Std. Error t-value Pr(>|t|)
## (Intercept) 1.0952e+06 3.7697e+05 2.9052 0.004665 **
## Q 2.1446e+06 8.8171e+04 24.3228 < 2.2e-16 ***
## PF 1.1757e+00 1.0356e-01 11.3531 < 2.2e-16 ***
## LF -3.0261e+06 7.2713e+05 -4.1616 7.466e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Total Sum of Squares: 8.0306e+13
## Residual Sum of Squares: 6.2698e+12
## R-Squared: 0.92193
## Adj. R-Squared: 0.88095
## F-statistic: 338.508 on 3 and 86 DF, p-value: < 2.22e-16
Ngoài sử dụng REM, theo Greene (2012), Maddala & Lahiri (2006), Davidson & MacKinnon (1993),
và Judge et al. (1985), chúng ta có thể áp dụng áp dụng phương pháp bình phương tổng quát nhỏ
nhất GLS (Generalized Least Squares). Chúng ta sẽ nghiên cứu ước lượng GLS cho dữ liệu mảng ở
phần sau.
Tương tự như sử dụng gói outreg2 của Stata cho so sánh kết quả của những mô hình khác nhau chúng
ta cũng có thể sử dụng gói cho so sánh, chẳng hạn, các ước lượng thu được từ FEM và REM như sau:
library(stargazer)
stargazer(FEM, REM, title = "So sánh FEM và REM", type = "text")
##
## So sánh FEM và REM
## ============================================================
## Dependent variable:
## -----------------------------------------------
## C
## (1) (2)
## ------------------------------------------------------------
## Q 3,319,023.000*** 2,144,561.000***
## (171,354.100) (88,170.630)
##
## PF 0.773*** 1.176***
## (0.097) (0.104)
##
## LF -3,797,368.000*** -3,026,060.000***
## (613,773.100) (727,130.000)
##
## Constant 1,095,172.000***
## (376,967.000)
##
## ------------------------------------------------------------
## Observations 90 90
## R2 0.929 0.922
## Adjusted R2 0.836 0.881
## F Statistic 355.254*** (df = 3; 81) 338.508*** (df = 3; 86)
## ============================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Ước lượng mô hình tác động ngẫu nhiên mà chúng ta vừa thực hiện ở trên là sử dụng cách tiếp cận
của Swamy & Arora (1972) và nếu không tuyên bố rõ thì R sẽ mặc định thực hiện ước lượng này.
Ngoài cách tiếp cận này còn có ba cách tiếp cận khác để thực phân tích tác động ngẫu nghiên với lựa
chọn random.method khi thực hiện lệnh plm() là:
random.method ="walhus”: theo các tiếp cận của Wallace & Hussain (1969)
random.method = "amemiya”: theo cách tiếp cận của Amemiya (1971)
random.method = "nerlove”: theo cách tiếp cận của Nerlove (1971).
Chẳng hạn chúng ta thực hiện ước lượng theo cách tiếp cận của Wallace và Hussain đồng thời so sánh
kết quả thu được với cách tiếp cận của Swamy và Arora:
##
## So sánh ket qua uoc luong tu hai phuong phap
## ============================================================
## Dependent variable:
## -----------------------------------
## C
## (1) (2)
## ------------------------------------------------------------
## Q 2,144,561.000*** 2,064,662.000***
## (88,170.630) (71,926.720)
##
## PF 1.176*** 1.208***
## (0.104) (0.104)
##
## LF -3,026,060.000*** -3,031,366.000***
## (727,130.000) (714,311.000)
##
## Constant 1,095,172.000*** 1,126,674.000***
## (376,967.000) (369,943.300)
##
## ------------------------------------------------------------
## Observations 90 90
## R2 0.922 0.935
## Adjusted R2 0.881 0.894
## F Statistic (df = 3; 86) 338.508*** 415.028***
## ============================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Chúng ta có thể thấy rằng hai cách tiếp cận tạo ra những ước lượng không khác biệt đáng kể với bộ
dữ liệu được phân tích.
effect = “time” : Thực hiện ước lượng tác động ngẫu nhiên theo chiều thời gian.
effect = “twoways” : Thực hiện ước lượng tác động ngẫu nhiên theo cả hai chiều.
Dưới đây là ước lượng mô hình tác động ngẫu nhiên hai chiều theo cách tiếp cận của Amemiya:
##
## So sánh ket qua uoc luong tu hai phuong phap
## ============================================================
## Dependent variable:
## -----------------------------------
## C
## (1) (2)
## ------------------------------------------------------------
## Q 2,064,662.000*** 3,278,658.000***
## (71,926.720) (175,834.900)
##
## PF 1.208*** 0.754***
## (0.104) (0.237)
##
## LF -3,031,366.000*** -3,245,771.000***
## (714,311.000) (899,997.100)
##
## Constant 1,126,674.000*** 799,095.900
## (369,943.300) (579,471.800)
##
## ------------------------------------------------------------
## Observations 90 90
## R2 0.935 0.831
## Adjusted R2 0.894 0.794
## F Statistic (df = 3; 86) 415.028*** 141.216***
## ============================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Có thế thấy rằng hệ số ướng lượng của PF thu được từ hai mô hình có sự khác biệt rất lớn trong khi
hệ số của LF thì không thay đổi nhiều.
12.4 Một số kiểm định lựa chọn và chẩn đoán lỗi của mô hình
Phần này các bạn sẽ thực hành với một số kiểm định nhằm lựa chọn và chấn đoán lỗi mô hình khi
phân tích dữ liệu mảng.
12.4.1 Kiểm định lựa chọn giữa FEM , Pooled OLS và REM
Theo Gujarati & Porter (2009), Baltagi (2005) và Greene (2013), chúng ta có thể thực hiện một số
kiểm định lựa chọn cách tiếp cận phù hợp cho phân tích dữ liệu mảng theo sơ đồ sau:
(Hình 2: Các kiểm định lựa chọn mô hình cho phân tích dữ liệu mảng)
Có thể tìm trên Internet một số nghiên cứu sử dụng khung phân tích này. Các nghiên cứu mà chúng
ta có thể tìm thấy ở Việt Nam là:
Luận văn thạc sĩ 2013 của tác giả Nguyễn Thị Ngọc Quỳnh bảo vệ tại Vietnam National
University – Ho Chi Minh City (đại học quốc gia Thành Phố Hồ Chí Minh) có tên “Impact of
Capital Structure on Firm Performance: A Case Study of Listed Manufacturing Companies
on Ho Chi Minh Stock (HOSR) Exchange”. Nghiên cứu này sử dụng các thông tin tài chính của
62 doanh nghiệp thuộc lĩnh vực sản xuất trong giai đoạn 2007 – 2011.
Nghiên cứu trình bày cho World Business and Social Science Research Conference tháng 10
năm 2013 của hai tác giả Phùng Đức Nam và Hoàng Thị Phương Thảo (công tác tại đại học
kinh tế thành phố Hồ Chí Minh – UEH) có tên “Corporate Ownership and Firm Performance
i n Emerging Market: A Study of Vietnamese Listed Firms” với dữ liệu tài chính của các
công ti niêm yết trên sàn HOSE và HNX từ 2007 đến 2012.
Trong số các kiểm định này thì kiểm định F và Wald đã được trình bày ở các mục trên. Trong phần
này chúng sẽ nghiên cứu kiểm định Hausman nhằm lựa chọn giữa REM và FEM.
Rõ ràng, một trong những thách thức của chúng ta khi phân tích dữ liệu mảng là lựa chọn REM hay
FEM khi phân tích? Về vấn đề này, Judge et al. (2007) chỉ ra một số dấu hiệu như cho việc lựa chọn
mô hình như sau:
1. Nếu T là lớn và N là nhỏ thì rất có thể không tồn tại khác biệt lớn giữa các ước lượng thu được
từ REM và FEM. Sự lựa chọn mô hình lúc này chỉ đơn thuần là căn cứ vào sự thuận tiện khi
tính toán. Theo tiêu chí này thì FEM thường được ưu tiêu hơn.
2. Khi T là nhỏ và N là lớn thì các ước lượng thu được từ hai phương pháp có thể khác biệt đáng
kể. Nhắc lại rằng trong mô hình REM, βi =γ1 + εi với đại diện cho bộ phận sai số ngẫu nhiên
ứng với cá thể thứ i trong mẫu nghiên cứu. Trong khi đó, ở mô hình FEM thì ta coi βi là bộ
phận cố định chứ không phải là biến ngẫu nhiên. Cách tiếp cận FEM là phù hợp nếu chúng ta
tin tưởng mạnh mẽ rằng các cá thể trong mẫu nghiên cứu không được lựa chọn ngẫu nhiên
từ một tổng thể lớn hơn. Ngược lại, nếu các cá thể trong mẫu được lựa chọn ngẫu nhiên thì
REM là phù hợp hơn. Vì trong tình huống này các thống kê suy luận là không có điều kiện
(unconditional).
3. Nếu bộ phận sai số ngẫu nhiên εi và một hay một số biến độc lập là tương quan thì các ước
lượng thu được từ FEM là các ước lượng chệch (biased) trong khi đó các ước lượng thu được
từ FEM là các ước lượng không chệch (unbiased).
4. Nếu T nhỏ và N là lớn và các giả định nền tảng cho REM là đúng thì các ước lượng thu được
từ REM là hiệu quả hơn so với các ước lượng thu được từ FEM (Taylor, 1980).
Tuy nhiên, trong các nghiên cứu, thay vì dựa vào các dấu hiệu ở trên chúng ta nên dựa vào các kiểm
định chính thức để lựa chọn mô hình. Một trong những kiểm định đó là Hausman Test (1978) với cặp
giả thuyết được kiểm định như sau:
H0: Các ước lượng thu được từ hai phương pháp không khác biệt.
H1: Các ước lượng thu được từ hai phương pháp là khác biệt.
Kiểm định được xây dựng bởi Hausman có phân phối χ2 . Nếu giả thuyết H0 bị bắc bỏ thì chúng ta đi
đến kết luận FEM là mô hình phù hợp hơn. Trong R chúng ta thực hiện kiểm định Hausman như sau:
phtest(FEM, REM)
##
## Hausman Test
##
## data: C ~ Q + PF + LF
## chisq = 63.785, df = 3, p-value = 9.126e-14
## alternative hypothesis: one model is inconsistent
Do p-value = 0.0000 < 5% (ứng với χ2 = 63.785) nên chúng ta đi đến kết luận mô hình FEM là mô
hình phù hợp hơn cho phân tích dữ liệu.
12.4.2 Kiểm định Breusch-Pagan cho lựa chọn giữa REM và Pooled OLS
Ngoài kiểm định Hausman, chúng ta có thể thực hiện kiểm định Breusch-Pagan Lagrange Multiplier
(thường gọi tắt là Breusch-Pagan LM Test) cho việc lựa chọn giữa REM và Pooled OLS bằng cách gõ
các lệnh sau trong R:
##
## Lagrange Multiplier Test - (Breusch-Pagan)
##
## data: C ~ Q + PF + LF
## chisq = 0.61309, df = 1, p-value = 0.4336
## alternative hypothesis: significant effects
Kiểm định này có p-value = 0.4336 > 5% do đó chúng ta có thể chạy Pooled OLS cho dữ liệu. Trong
tình huống ngược lại, nếu p-value mà nhỏ hơn 5% thì mô hình REM là phù hợp hơn cho phân tích dữ
liệu.
12.4.3 Một số kiểm định khác chẩn đoán lỗi mô hình sử dụng dữ liệu mảng
Ngoài các kiểm định lựa chọn mô hình ở trên chúng ta có thể thực hiện một số kiểm định nhằm chẩn
đoán các lỗi (Diagnotic Tests) có thể có của mô hình. Các kiểm định này được thực hiện sau khi chúng
ta đã lựa chọn một mô hình cụ thể nhất định cho phân tích dữ liệu.
##
## Breusch-Pagan LM test for cross-sectional dependence in panels
##
## data: formula
## chisq = 70.675, df = 15, p-value = 3.386e-09
## alternative hypothesis: cross-sectional dependence
Căn cứ vào kết quả kiểm định chúng ta thấy p-value = 0.0000 < 5% (với χ2 = 70.67) nên chúng ta
bắc bỏ H0. Kết luận của chúng ta ở đây là phần dư giữa các hãng có tương quan.
Chúng ta thực hiện như sau trong R để thực hiện kiểm định này cho mô hình FEM:
pbgtest(FEM)
##
## Breusch-Godfrey/Wooldridge test for serial correlation in panel
## models
##
## data: C ~ Q + PF + LF
## chisq = 52.863, df = 15, p-value = 4.064e-06
## alternative hypothesis: serial correlation in idiosyncratic errors
Do p-value = 0 <5% nên chúng ta kết luận có bằng chứng thống kê chỉ ra rằng tồn tạo hiện tượng
tương quan chuỗi trong mô hình FEM.
pbgtest(REM)
##
## Breusch-Godfrey/Wooldridge test for serial correlation in panel
## models
##
## data: C ~ Q + PF + LF
## chisq = 61.756, df = 15, p-value = 1.256e-07
## alternative hypothesis: serial correlation in idiosyncratic errors
Do p-value = 0 <5% nên chúng ta kết luận có bằng chứng thống kê chỉ ra rằng tồn tại hiện tượng
tương quan chuỗi trong mô hình REM.
12.4.3.3 Kiểm định phương sai sai số thay đổi cho FEM
Chúng ta có thể sử dụng Studentized Breusch-Pagan Test nhằm kiểm tra hiện tượng phương sai sai
số thay đổi ở mô hình FEM với cặp giả thuyết sau:
##
## Breusch-Pagan test
##
## data: C ~ Q + PF + LF + factor(i)
## BP = 37.83, df = 8, p-value = 8.092e-06
Kết quả kiểm định cho ta p-value = 0 < 5% nên chúng ta đi đến kết luận là phương sai sai số ngẫu
nhiên thay đổi (bắc bỏ H0).
Chú ý rằng trong Stata thực hiện kiểm định này bằng Modified Wald Test với câu lệnh xttest3.
12.5 Một số phân tích hình ảnh – đồ thị cho dữ liệu bảng
Để đơn giản hóa việc minh họa các câu lệnh trong R, phần này chúng ta chỉ nghiên cứu hành vi của
chi phí C với một biến độc lập là doanh thu Q mà thôi. Chúng ta xét mô hình LSDV:
##
## Call:
## lm(formula = C ~ Q + factor(i), data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -937342 -72283 2219 77797 790626
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2611747 244754 -10.671 < 2e-16 ***
## Q 3723326 165063 22.557 < 2e-16 ***
## factor(i)2 954145 125136 7.625 3.62e-11 ***
## factor(i)3 1799520 196388 9.163 3.08e-14 ***
## factor(i)4 2458376 224768 10.937 < 2e-16 ***
## factor(i)5 2481172 239227 10.372 < 2e-16 ***
## factor(i)6 2537253 240642 10.544 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 292900 on 83 degrees of freedom
## Multiple R-squared: 0.9437, Adjusted R-squared: 0.9396
## F-statistic: 231.9 on 6 and 83 DF, p-value: < 2.2e-16
Chúng ta có thể thấy ngay là các hệ số hồi quy của D4, D5, và D6 khá sát nhau. Điều này gợi ý cho chúng
ta rằng nếu chúng ta biểu diễn 6 đường hồi quy ứng với 6 hãng trên cùng một đồ thị thì các đường
hồi quy của hãng 4, 5, và 6 là sát nhau. Chúng ta có thể sử dụng đồ thị để kiểm tra nhận định này:
Chat <-trangtrang$fitted
library(car)
scatterplot(Chat ~ dung$Q|dung$i, xlab = "Q", ylab = "Chat")
Quan phân tích đồ thị chúng ta có thể thấy rằng rất có thể mô hình Pooled OLS có thể phù hợp hơn so
với LSDV. Chúng ta xét mô hình Pooled OLS:
##
## Call:
## lm(formula = C ~ Q, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -944933 -265773 9185 180057 1338676
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -5336 68243 -0.078 0.938
## Q 2069488 89717 23.067 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 451600 on 88 degrees of freedom
## Multiple R-squared: 0.8581, Adjusted R-squared: 0.8565
## F-statistic: 532.1 on 1 and 88 DF, p-value: < 2.2e-16
Chúng ta có thể vẽ đường hồi quy cho mô hình Pooled OLS (màu vàng) cùng với 6 đường hồi quy ứng
với 6 hãng trên cùng một đồ thị:
Tất nhiên nhận định rằng Pooled OLS có thể phù hợp hơn so với LSDV chỉ dựa trên trực quan của
chúng ta khi phân tích 6 đường hồi quy cho 6 hãng trên. Để đưa ra quyết định chính thức về việc lựa
chọn LSDV hay Pooled OLS chúng ta phải sử dụng các kiểm định đã trình bày ở các mục trên.
12.6 Một số lưu ý về định dạng dữ liệu và công thức cho mô hình
Cũng như khi sử dụng Stata cho dữ liệu mảng, việc đầu tiên cần làm là chỉ thị cho R hiểu rằng “bạn
đang xử lý dữ liệu mảng”. Với Stata bạn sử dụng lệnh xtset. Tuy nhiên, có vẻ như tất cả những ví dụ ở
trên, chúng ta đã bỏ qua thao tác định dạng dữ liệu mảng cho R.
Sự thực không phải vậy, là vì chúng ta đã “ẩn” thao tác định dạng dữ liệu mảng trong các câu lệnh.
Trở lại với các dòng lệnh ở mục 12.3.3, chúng ta có thể làm cách khác như sau:
dung <- plm.data(dung, index = c("i", "t")) # Định dạng data frame dung là dữ
liệu mảng.
FEM <- plm(C ~ Q + PF + LF, data = dung, model = "within") # Chạy mô hình.
summary(FEM)
Kết quả thu được là không có gì thay đổi. Ở đây câu lệnh đầu tiên chúng ta sử dụng để định dạng dung
là một dữ liệu mảng để R thực hiện phân tích.
Ngoài cách thức trình bày dữ liệu như ở dung, còn có những cách thức trình bày dữ liệu kiểu khác.
Chúng ta xét bộ dữ liệu không cân bằng (unbalanced panel data) có tên Wages về 595 cá thể xuất
hiện trong nghiên cứu của Cornwell & Rupert (1988). Có nhiều cách để có bộ dữ liệu này. Một trong
những cách nhanh nhất là các bạn cài đặt gói Ecdat bằng lệnh install.packages(“Ecdat”). Chúng ta
thấy cách trình bày của bộ dữ liệu này như sau:
## exp wks bluecol ind south smsa married sex union ed black lwage
## 1 3 32 no 0 yes no yes male no 9 no 5.56068
## 2 4 43 no 0 yes no yes male no 9 no 5.72031
## 3 5 40 no 0 yes no yes male no 9 no 5.99645
## 4 6 39 no 0 yes no yes male no 9 no 5.99645
## 5 7 42 no 1 yes no yes male no 9 no 6.06146
## 6 8 35 no 1 yes no yes male no 9 no 6.17379
Các bạn nên tự so sánh với data frame dung để tìm ra sự khác biệt về cách trình bày của bộ dữ liệu
này. Chúng ta sử dụng câu lệnh sau để thiết lập bộ dữ liệu này là dữ liệu mảng trước khi thực hiện bất
kì phân tích nào với tên gọi là nghiyeu:
## id time exp wks bluecol ind south smsa married sex union ed black
## 1 1 1 3 32 no 0 yes no yes male no 9 no
## 2 1 2 4 43 no 0 yes no yes male no 9 no
## 3 1 3 5 40 no 0 yes no yes male no 9 no
## 4 1 4 6 39 no 0 yes no yes male no 9 no
## 5 1 5 7 42 no 1 yes no yes male no 9 no
## 6 1 6 8 35 no 1 yes no yes male no 9 no
## lwage
## 1 5.56068
## 2 5.72031
## 3 5.99645
## 4 5.99645
## 5 6.06146
## 6 6.17379
Lúc này bạn có thể thấy xuất hiện hai cột “biến” mới là id và time. Bộ số liệu này sẽ được sử dụng
trong mục 12.7.
Một vấn đề khác là biểu diễn các mô hình định lượng sử dụng dữ liệu mảng. Với các mô hình động
(Dynamic Model) thường có cả biến trễ và sai phân các bậc trong mô hình. Với bộ số liệu EmplUK ,
xét mô hình động sau đây:
Nghĩa là chúng ta đang nghiên cứu sự phụ thuộc của biến emp theo: (1) biến trễ bậc 1 và 2 của
ln(emp), (2) biến trễ bậc 2 và 3 của ln(wage), và (3) sai phân bậc 2 và 3 của capital. Trong R chúng ta
có thể biểu diễn công thức mô hình này như sau:
Mô hình này có thể được diễn đạt theo một cách khác bằng sử dụng hàm dynformula():
Chúng ta có thể thấy hai cách diễn đạt mô hình này cùng mô tả một mô hình mà thôi:
mohinhc1
mohinhc2
Cách thức diễn đạt mô hình bằng sử dụng hàm dynformula() là rất thuận tiện (bằng cách tiết kiệm
thời gian đánh máy) cho những trường hợp mô hình nghiên cứu của chúng ta có nhiều biến trễ và sai
phân.
12.7 Một số mô hình nâng cao cho phân tích dữ liệu mảng
Trong mục này chúng ta sẽ thực hiện một số ước lượng nâng cao khi phân tích dữ liệu mảng là ước
lượng biến công cụ IV, ước lượng Hausman – Taylor, moment tổng quá GMM và FGLS. Lý thuyết
những cách tiếp cận này cho phân tích dữ liệu mảng các bạn có thể tìm thấy ở nhiều giáo trình kinh
tế lượng.
data(EmplUK)
head(EmplUK)
Từ hình ảnh trên chúng ta thấy rằng đa phần các hãng có khoảng thời gian nghiên cứu là 7 năm. Một
số hãng có thời gian nghiên cứu là 8 hoặc 9 năm. Rõ ràng đây là một bảng dữ liệu không cân bằng. Cụ
thể:
##
## 7 8 9
## 103 23 14
Như vậy có 103 công ti với thời gian nghiên cứu là 7 năm, 23 công ti có thời gian nghiên cứu là 8 năm
và 14 công ti có thời gian nghiên cứu là 9 năm. Ngoài ra chúng ta còn có thể thấy khoảng thời gian từ
1978 đến 1982 xuất hiện với tần suất như nhau và nhiều nhất, năm 1984 số quan sát là ít nhất:
iu <- table(EmplUK$year)
library(fBasics)
mausac <- qualiPalette(12, "Set3")
barplot(iu, col = mausac)
Chúng ta có thể có thông tin chi tiết hơn về số quan sát xuất hiện tương ứng với các năm:
iu
##
## 1976 1977 1978 1979 1980 1981 1982 1983 1984
## 80 138 140 140 140 140 140 78 35
Giả sử chúng ta sử dụng trễ bậc 1 của wage làm biến công cụ cho wage. Việc thực hiện ước lượng biến
công cụ có thể được thực hiện theo hai cách tiếp cận với lựa chọn inst.method như sau:
Thực hiện ước lượng biến công cụ với cách tiếp cận của của Balestra và Varadharajan-Krishnakumar
sẽ được thực hiện theo cú pháp sau (xem lại chương 9 nếu cần):
Chú ý rằng, kết quả sẽ không có gì thay đổi nếu chúng ta không gõ inst.method="bvk" vì R sẽ mặc
định cách tiếp cận này. Chú ý rằng biến số độc lập nào xuất hiện ở cả hai vế của dấu | thì được hiểu là
chúng “triệt tiêu” nhau và biến số còn lại ở vế phải của dấu | sẽ là biến công cụ cho biến còn lại ở vế
trái. Câu lệnh này tương đương với sử dụng lệnh xtivreg của Stata.
Vừa rồi chúng ta thực hiện biến công cụ cho bộ dữ liệu bảng không cân bằng. Dưới đây chúng ta sẽ
thực hiện ước lượng biến công cụ cho bộ dữ liệu bảng cân bằng có tên psi.dta lấy từ nghiên cứu của
Baltagi & Khanti-Akom (1990) xuất hiện trong nhiều giáo trình khác nhau về dữ liệu mảng. Đây là dữ
liệu được sử dụng để đánh giá vài trò của các biến định lượng (như kinh nghiệm exp) cũng như định
tính (như giới tính fem) lên logarit cơ số tự nhiên (lwage). Số liệu được thu nhập từ 595 lao động
trong giai đoạn 1976 – 1982:
setwd("D:/KTLR")
library(foreign)
trang <- read.dta("psi.dta")
dim(trang)
## [1] 4165 22
head(trang)
## exp wks occ ind south smsa ms fem union ed blk lwage id t tdum1 tdum2
## 1 3 32 0 0 1 0 1 0 0 9 0 5.56068 1 1 1 0
## 2 4 43 0 0 1 0 1 0 0 9 0 5.72031 1 2 0 1
## 3 5 40 0 0 1 0 1 0 0 9 0 5.99645 1 3 0 0
## 4 6 39 0 0 1 0 1 0 0 9 0 5.99645 1 4 0 0
## 5 7 42 0 1 1 0 1 0 0 9 0 6.06146 1 5 0 0
## 6 8 35 0 1 1 0 1 0 0 9 0 6.17379 1 6 0 0
## tdum3 tdum4 tdum5 tdum6 tdum7 exp2
## 1 0 0 0 0 0 9
## 2 0 0 0 0 0 16
## 3 1 0 0 0 0 25
## 4 0 1 0 0 0 36
## 5 0 0 1 0 0 49
## 6 0 0 0 1 0 64
table(trang$t)
##
## 1 2 3 4 5 6 7
## 595 595 595 595 595 595 595
Dưới đây chúng ta thực hiện ước lượng biến công cụ cho lwage theo exp và exp2 (bình phương của
exp) và wks trong đó chúng ta chọn ms (trạng thái hôn nhân) là biến công cụ cho wks:
## Coefficients :
## Estimate Std. Error t-value Pr(>|t|)
## exp 0.1408101 0.0547014 2.5742 0.01009 *
## exp2 -0.0011207 0.0014052 -0.7975 0.42520
## wks -0.1149742 0.2316926 -0.4962 0.61976
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Total Sum of Squares: 240.65
## Residual Sum of Squares: 946.63
## R-Squared: 0.094827
## Adj. R-Squared: 0.081212
## F-statistic: -886.733 on 3 and 3567 DF, p-value: 1
So với thực hiện trong Stata thì điểm khác biệt là R không báo cáo hệ số chặn của mô hình.
congthuc <- lwage ~ occ + south + smsa + ind + exp + I(exp^2) + wks + ms + un
ion + fem + blk + ed | exp + I(exp^2) + wks + ms + union + ed
hausmantaylor <- plm(congthuc, data = trang, model = "ht") # Tương đương với
câu lệnh xthtaylor
summary(hausmantaylor)
R chỉ ra danh sách các biến nội sinh ở dòng T.V. exo : exp, I(exp^2), wks, ms, union và
hệ số hồi quy ước lượng của những biến số này được chú ý phân tích hơn. Từ kết quả của mô hình có
thể thấy kinh nghiệm và mức lương tuân theo quy luật cận biên giảm dần. Kết quả của ước lượng này
tương đương với sử dụng lệnh xthtaylor của Stata.
Chú ý nếu chúng ta không tạo ra đối tượng congthuc thì chúng ta phải gõ câu lệnh kiểu như sau:
hausmantaylor <- plm(lwage ~ occ + south + smsa + ind + exp + I(exp^2) + wks
+ ms + union + fem + blk + ed | exp + I(exp^2) + wks + ms + union + ed, data
= trang, model = "ht")
Tất nhiên kết quả vẫn không có gì thay đổi. Việc mô tả trước mô hình như chúng ta vừa thấy là cách
thức thường được sử dụng khi mô hình của chúng ta buộc phải mô tả bằng một dãy dài các kí tự.
Lý thuyết của của phương pháp ước lượng này cũng như diễn giải các kết quả các bạn có thể xem một
cách chi tiết từ nghiên cứu trên.
Chúng ta cũng có thể đánh giá tác động cố định bằng lệnh sau:
Nhìn chung kết quả thu được từ ước lượng FGLS không khác biệt nhiều so với sử dụng hàm plm().
12.8 Vài kết luận cuối cùng về phân tích dữ liệu mảng
Trong chương này chúng ta đã khái quát và xem xét một số mô hình cơ bản cho dữ liệu mảng.
Các chủ đề khác chưa được đề cập cho dữ liệu mảng là:
1. Các mô hình nhiều phương trình (Simultaneous Equation Models) với dữ liệu mảng.
Các chủ đề này và một số khía cạnh khác về phân tích dữ liệu mảng khó có thể trình bày chỉ trong
một chương được vì theo truyền thống, phân tích dữ liệu mảng thường được tách hẳn ra thành một
nhánh của kinh tế lượng. Bạn đọc quan tâm có thể tìm hiểu sâu hơn ở những giáo trình chuyên về
dữ liệu mảng. Một số cuốn hay và chi tiết là sách của Baltagi, Greene, và Wooldridge.
Chương 13: Các mô hình với biến phụ thuộc là rời rạc
Các chương trước chúng ta nghiên cứu các mô hình mà ở đó biến phụ thuộc là các biến liên tục. Tuy
nhiên trong nhiều tình huống trong thực tế, biến phụ thuộc có thể là biến rời rạc, biến phân hạng, hoặc
biến định tính. Những mô hình hồi quy áp dụng cho tình huống này thuộc về một lớp gọi là các mô hình
hồi quy với biến phản ứng là định tính (Qualitative Response Regression Models). Chương này chúng
ta chỉ xét tình huống đơn giản nhất của lớp mô hình này với biến phụ thuộc chỉ nhận hai giá trị 0 hoặc
1 (còn gọi là biến nhị phân binary variable) và biến phụ thuộc nhận nhiều hơn hai giá trị 0 và 1. Trước
hết, chúng ta sẽ nghiên cứu tại sao ước lượng OLS (hay mô hình xác suất tuyến tính LPM) là không phù
hợp cho các tình huống như vậy. Kế tiếp, chúng ta sẽ nghiên cứu và thực hành các mô hình Logistic,
Logistic đa cấp độ và Probit và mô hình cây phân loại.
Mô hình này còn có tên gọi khác là mô hình xác suất tuyến tính LPM (Linear Probability Model) vì
rằng kì vọng của biến phụ thuộc (trạng thái hút thuốc) có thể được hiểu như xác suất có điều kiện
xuất hiện sự kiện hút thuốc. Ước lượng OLS thu được là:
setwd("D:/KTLR")
library(foreign)
dung <- read.dta("Table8_1.dta")
lmp <- lm(smoker ~ age + educ + income + pcigs79, data = dung)
summary(lmp)
##
## Call:
## lm(formula = smoker ~ age + educ + income + pcigs79, data = dung)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.6417 -0.3880 -0.2782 0.5563 0.8405
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.123e+00 1.884e-01 5.963 3.27e-09 ***
## age -4.726e-03 8.290e-04 -5.701 1.50e-08 ***
## educ -2.061e-02 4.616e-03 -4.465 8.76e-06 ***
## income 1.026e-06 1.632e-06 0.629 0.5298
Mô hình này chỉ ra rằng tuổi tác, giáo dục, và giá của thuốc lá quan hệ ngược chiều với biến phụ thuộc.
Đây là một kết quả không có gì bất ngờ. Chúng ta diễn giải các kết quả thu được như sau: nếu các biến
khác không đổi, xác suất quan sát thấy hành vi hút thuốc là giảm 0.005 khi tuổi tăng lên 1 (có lẽ bởi
vì các ảnh hưởng tiêu cực của hút thuốc đối với sức khỏe). Giá trị R2 = 0.038 có vẻ là thấp nhưng chúng
ta cần chú ý rằng kết quả này không có ý nghĩa quá quan trọng vì biến phụ thuộc chỉ nhận một trong
hai giá trị 0 hoặc 1.
Tuy nhiên, mô hình LMP trên có một số nhược điểm đáng chú ý. Thứ nhất, LPM cho rằng xác xuất
quan sát thấy hành vi hút thuốc là quan hệ tuyến tính với các biến giải thích bất kể quy mô về giá trị
của các biến số này. Thứ hai, xác suất của một sự kiện phải nằm giữa 0 và 1 nhưng LPM không đảm
bảo rằng các giá trị xác suất ước lượng sẽ nằm trong khoảng này. Thứ ba, giả định về sai số ngẫu nhiên
tuân theo phân phối chuẩn có thể không còn đúng nữa khi biến phụ thuộc chỉ nhận một trong hai giá
trị 0 và 1. Thứ tư, phương sai của sai số ngẫu nhiên là thay đổi, làm cho các kiểm định truyền thống
là không đáng tin.
Vì những lí do trên, các mô hình Probit và Logistic thường được sử dụng cho các tình huống mà biến
phụ thuộc là các biến nhị phân.
2. Mặc dù log[p/(1-p)] là tuyến tính với các biến giả thích nhưng các xác suất thì không như vậy.
Điều này ngược lại với mô hình LPM.
3. Nếu log[p/(1-p)] là dương thì khi giá trị của biến giải thích tăng dẫn đến khả năng quan sát
thấy hành vi hút thuốc tăng (và ngược lại).
4. Nếu chúng ta thu được các ước lượng cho các α và β thì chúng ta có thể ước lượng xác suất p̂
cho bất kì quan sát nào theo công thức 2.
Việc ước lượng các hệ số của mô hình Logit được thực hiện bằng phương pháp ước lượng hợp lí cực
đại (maximum likelihood). Với R chúng ta có thể thực hiện ước lượng này lệnh glm (viết tắt của
generalized linear models – các mô hình tuyến tính tổng quát):
logit <- glm(smoker ~ age + educ + income + pcigs79,
family = binomial, data = dung)
summary(logit)
##
## Call:
## glm(formula = smoker ~ age + educ + income + pcigs79, family = binomial,
## data = dung)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.4608 -0.9829 -0.8055 1.2769 1.8384
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 2.745e+00 8.292e-01 3.311 0.000931 ***
## age -2.085e-02 3.739e-03 -5.577 2.44e-08 ***
## educ -9.097e-02 2.067e-02 -4.402 1.07e-05 ***
## income 4.720e-06 7.170e-06 0.658 0.510356
## pcigs79 -2.232e-02 1.247e-02 -1.789 0.073538 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1588.9 on 1195 degrees of freedom
## Residual deviance: 1541.7 on 1191 degrees of freedom
## AIC: 1551.7
##
## Number of Fisher Scoring iterations: 4
Chúng ta diễn giải các kết quả thu được như sau. Ví dụ, hệ số của age = -2.085⨉10-2 có nghĩa là khi
giáo dục tăng 1 (năm) thì xác suất quan sát thấy hành vi hút thuốc của người này giảm xuống 100[1-
exp(-2.085⨉10-2] = 100(1 – 0.979) = 2.06%:
100*(1 - exp(logit$coef[2]))
## age
## 2.063728
Các diễn giải về các hệ số như trên là một cách thức phổ biến. Tuy nhiên, có một cách thức khác diễn
giải các hệ số của mô hình Logistic là diễn giải theo tỉ số khả năng (Nguyễn, 2015) hoặc theo cách gọi
của giáo trình NEU là tỉ số OR (odd ratio). Chúng ta có thể tính các hệ số OR của mô hình như sau:
Nghĩa là, chẳng hạn, khi tuổi tăng một đơn vị thì khả năng người này thuộc nhóm hút thuốc tăng
0.9793627 lần. Nói cách khác, là giảm 2.06% như chúng ta đã tính toán ở trên.
Chúng ta có thể ước lượng xác xuất quan sát thấy người thứ hai trong mẫu nghiên cứu là thuộc nhóm
hút thuốc là bao nhiêu:
## (Intercept)
## 0.3782652
Giá trị xác suất ước lượng này là 0.3782. Thực tế thì quan sát thứ 2 này là người hút thuốc. Nên chúng
ta có thể nói mô hình phân loại (hay ước lượng) sai cho quan sát thứ hai này. Trong diễn giải các kết
quả của mô hình logistic (hay bất kì mô hình phân loại nào) nếu một người là hút thuốc và giá trị xác
suất ước lượng ứng với người này mà lớn hơn 0.5 thì ta nói mô hình dự báo đúng và gán cho nó giá
trị 1 và ngược lại (Gujarati, 2011). Trong tình huống của chúng ta mô hình ước lượng xác suất hút
thuốc ứng với quan sát thứ hai là 0.3782 trong khi thực tế anh ta hút thuốc do đó đây là một ước
lượng sai và do vậy được gán giá trị 0.
Sai khác giữa giá trị p thực tế và ước lượng p̂ gọi là deviance – một tiêu chí tương tự như phần dư
(residuals). Sai khác này càng bé càng tốt. Tương tự như tiêu chí R2 đối với ước lượng OLS, với mô
hình Logit chúng ta có chỉ tiêu R2 của MacFadden (MacFadden’s R2) để đo lường mức độ phù hợp của
mô hình với gói pscl (cài đặt gói này bằng lệnh install.packages(“pscl”)). Trong R chúng ta có thể
tìm MacFadden’s R2 với sự trợ giúp của gói pscl như sau:
library(pscl)
pR2(logit)
Giá trị này là 2.97% và chính là được tính theo công thức sau:
𝑙𝑓𝐿
𝑝𝑠𝑒𝑢𝑑𝑜 − 𝑅 2 = 1 −
𝑙𝑓𝐿0
Trong đó lfL = -770.841 và lfL0 = -794.474 (lần lượt ở cột llh và llhNull). Tương tự như kiểm định F
chúng ta có thể sử dụng thống kê tỉ số xác suất LR (likehood ratio statistic) theo công thức sau:
𝜆 = 2(𝑙𝑓𝐿 − 𝑙𝑓𝐿0 )
Để kiểm định cặp giả thuyết:
H0: Tất cả các hệ số hồi quy của biến độc lập bằng không
H0: Có ít nhất một hệ số hồi quy của biến độc lập khác không.
Thống kê này tuân theo phân phối χ2 với (k-1) bậc tự do (cũng chính là số biến độc lập trong mô
hình). Giá trị của thống kê λ = 47.268 là rất lớn nên chúng ta bắc bỏ giá thuyết H0.
Với mô hình logistic, chỉ tiêu R2 của MacFadden mà chúng ta đề cập là rất khó sử dụng để diễn giải
sức mạnh giải thích của mô hình logistic nói riêng và các mô hình phân loại nói chung. Chúng ta sử
dụng một cách tiếp cận khác cho vấn đề này như sau: lấy số lượng các quan sát mà mô hình dự báo
đúng – tức là các quan sát được gán giá trị 1 chia cho tất cẩ các quan sát trong mô hình (Gujarati,
2011) . Nếu tỉ số này bằng 1 thì ta nói mô hình dự báo đúng 100% (rất hiếm khi xẩy ra). Trong thực
tế, tỉ số này sẽ là một con số nằm giữ 0 và 1. Tất nhiên một mô hình tốt thì tỉ số này càng gần 1 càng
tốt. Những câu lệnh dưới đây cho phép chúng ta tính tỉ số này.
Dưới đây là R code tính toán mức độ chính xác trong phân loại:
## Smoker
## Nonsmoker 0
## Smoker 1
glm.probs <- predict(logit, type = "response") # Xác suất dự báo cho tất cả
các quan sát.
glm.probs[1:10] # Xem XS dự báo cho 10 quan sát đầu bao gồm cả giá trị 0.3782
mà ta đã tính.
## 1 2 3 4 5 6 7
## 0.4757920 0.3782652 0.2983162 0.4857104 0.4324134 0.3122390 0.3171300
## 8 9 10
## 0.4361007 0.4237071 0.4737278
##
## glm.pred Nonsmoker Smoker
## Nonsmoker 669 394
## Smoker 72 61
mean(glm.pred == dung$smoker)
## [1] 0.6103679
## [1] 0.6293509
61 / (72 + 61)
## [1] 0.4586466
## [1] 0.6103679
Kết quả chỉ ra rằng có tất cả (669 + 394) quan sát là không hút thuốc và mô hình xác định đúng 669
quan sát đạt tỉ lệ chính xác 62.93%. Có (72+61) quan sát hút thuốc nhưng mô hình chỉ xác định đúng
72 người hút thuốc và do vậy đạt mức chính xác 45.86%. Tỉ lệ dự báo chính xác của mô hình chính là
bằng (669+61)/1196 = 61.03%. Chú ý rằng (1 - 61.03%) = 38.97% được gọi là tỉ lệ sai sót huấn luyện
– một khái niệm mà chúng ta đã biết ở chương 4. Để biết tỉ lệ 61.3% đã đủ để kết luận mô hình logistic
là đáng tin cậy không trước hết ta tính tỉ lệ những nhóm khác nhau thuộc biến phụ thuộc:
##
## 0 1
## 61.96 38.04
Có thể thấy nhóm chiếm ưu thế là không hút thuốc với 61.96%. Một trong những tiêu chuẩn để đánh
giá mô hình logistic nói riêng và các mô hình phân loại nói chung là mức độ chính xác trong dự báo
của mô hình tối thiểu phải lớn hơn lớp có tỉ lệ cao nhất ở biến phụ thuộc. Vì chẳng cần xây dựng
mô hình nào chúng ta cũng có thể đoán ngẫu nhiên với mức độ chính xác là 61.96% - con số này chính
bằng tỉ trọng của nhóm chiếm ưu thế (nhóm không hút thuốc).
Để thuận tiện cho các phân tích, chúng ta nên đổi lại cách biểu thị cho biến định tính smoker. Cụ thể,
gán Nonsmoker cho người không hút thuốc (ứng với smoker = 0) và Smoker cho người hút thuốc
(ứng với smoker =1) rồi thực hiện lại mô hình logistic với hàm glm() như đã làm ở trên:
# Chuyển biến smoker ở dạng số sang dạng factor với 0 ứng với
# không hút thuốc (Nonsmoker) và ngược lại:
library(tidyverse)
Tất nhiên chúng ta có thể thấy kiểu gán giá trị này cho biến định tính không làm thay đổi kết quả của
mô hình (không hiển thị kết quả):
summary(logitdoibien)
Ngoài sử dụng hàm glm() như vừa làm chúng ta cũng nên sử dụng hàm train() của gói caret để thực
hiện hồi quy logistic vì những thuận tiện của gói này (không hiển thị kết quả):
library(caret)
# Thực hiện logistic bằng gói caret:
logitdungTrain <- train(smoker ~ age + educ + income + pcigs79,
data = dung, method = "glm", family = "binomial")
summary(logitdungTrain)
Sử dụng gói caret chúng ta có thể nhanh chóng có được các thông tin về khả năng dự báo của mô hình
bằng hàm confusionMatrix():
## Prevalence : 0.6196
## Detection Rate : 0.5594
## Detection Prevalence : 0.8888
## Balanced Accuracy : 0.5184
##
## 'Positive' Class : Nonsmoker
Bảng kết quả này được gọi là ma trận nhầm lẫn (confusion matrix) và sẽ được giải thích rõ hơn ở
các phần sau. Có thể thấy mức độ chính xác trong phân loại là 61.04%. Kết quả này là trùng với các
tính toán thủ công khi dùng hàm glm().
Tỉ lệ sai sót huấn luyện ở trên càng bé càng tốt tuy nhiên nó chưa phản ánh đúng sức mạnh giải thích
của mô hình vì chúng ta xây dựng mô hình dựa trên toàn bộ các quan sát và sau đó chúng ta sử dụng
lại toàn bộ các quan sát này để thẩm định (testing) mô hình. Để có bức tranh chính xác hơn về sức
mạnh giải thích của mô hình chúng ta phân chia toàn bộ dữ liệu thành hai phần. Phần thứ nhất là dữ
liệu huấn luyện (training data). Phần thứ hai là dữ liệu kiểm định (testing data). Chúng ta sử dụng dữ
liệu huấn luyện để xây dựng mô hình và sử dụng dữ liệu kiểm định để đánh giá mức độ chính xác
trong dự báo của mô mình (James et al., 2013).
Các câu lệnh dưới đây chúng ta lấy 1000 quan sát đầu làm dữ liệu huấn luyện và 192 quan sát còn lại
làm dữ liệu kiểm định để đánh giá sức mạnh giải thích của mô hình logistic với sự trợ giúp của gói
caret. Tỉ lệ dữ liệu kiểm định và huấn luyện thể hiện ở lựa chọn p=1000/1196:
dung <- dung[, c(1:4, 6)] # Chỉ lấy các biến sử dụng cho phân tích.
set.seed(123) # Dùng lệnh này để tái lập kết quả.
Train <- createDataPartition(dung$smoker, p = 1000 / 1196, list = FALSE)
training <- dung[ Train, ]
testing <- dung[ -Train, ]
# Chạy mô hình Logistic với dữ liệu huấn luyện bằng lệnh train():
mod_fit <- train(smoker ~., data = training,
method = "glm", family = "binomial")
summary(mod_fit)
## Call:
## NULL
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.5129 -0.9819 -0.8040 1.2749 1.8671
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 3.300e+00 9.122e-01 3.618 0.000297 ***
## educ -1.052e-01 2.275e-02 -4.621 3.82e-06 ***
## age -1.814e-02 4.081e-03 -4.446 8.76e-06 ***
## income 6.776e-06 7.931e-06 0.854 0.392917
## pcigs79 -3.110e-02 1.377e-02 -2.259 0.023895 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1330.1 on 1000 degrees of freedom
## Residual deviance: 1289.6 on 996 degrees of freedom
## AIC: 1299.6
##
## Number of Fisher Scoring iterations: 4
Chúng ta có thể đánh giá sức mạnh phân loại của mô hình trên dữ liệu kiểm định (không hiện kết
quả):
Chúng ta thấy rằng mức độ dự báo chính xác toàn cục bây giờ là 60% = (107+10)/196 – thấp hơn một
chút so với kết quả trước đó là 61.03% nhưng nó phản ánh chính hơn xác sức mạnh giải thích (hay
dự báo) của mô hình. Ở đây ta cũng tính được tỉ lệ sai sót kiểm định (training error rate) là 1 – 60% =
40%.
Chúng ta cũng có thể tính tỉ lệ sai sót huấn luyện với mẫu huấn luyện 1000 quan sát. Đương nhiên
con số này không trùng với kết quả 38.97% vì lúc này chúng ta chỉ sử dụng 1000 chứ không phải toàn
bộ các quan sát. Trong R chúng ta thực hiện như sau (không hiển thị kết quả):
Kết quả này chỉ ra rằng tỉ lệ sai sót huấn luyện là 1 - 0.6104 = 38.96%. Con số này thấp hơn một chút
so với việc sử dụng toàn bộ dữ liệu.
Khi nói đến tỉ lệ sai sót huấn luyện và tỉ lệ sai sót kiểm định, ở chương 4 chúng đã biết đến hiện tượng
gọi là quá khớp (overfiting). Theo James et al. (2013), đây là hiện tượng xẩy ra khi mô hình của chúng
ta rất phù hợp với dữ liệu huấn luyện (tức tỉ lệ sai sót huấn luyện rất thấp) nhưng lại không phù hợp
với dữ liệu kiểm định (tức tỉ lệ sai sót kiểm định là cao). Thông thường chúng ta kì vọng rằng nếu tồn
tại một mô hình mà tỉ lệ sai sót huấn luyện rất thấp thì cũng sẽ dẫn đến tỉ lệ sai sót kiểm định cũng
thấp. Thật đáng tiếc là không có gì đảm bảo cho sự tương quan này cả và gần như không có quy tắc
vàng hay chỉ dẫn cụ thể nào cho ta tìm được một mô hình tối ưu cho tất cả các tình huống.
Gói caret còn cung cấp cho ta một số hàm có thể chỉ ra những manh mối để cải thiện khả năng dự báo
của mô hình bằng lệnh varImp(). Lệnh này cho biết tầm quan trọng của các biến số đối với mô hình
mà chúng ta xây dựng:
varImp(mod_fit)
Chúng ta cũng có thể hình ảnh hóa tầm quan trọng của các biến số này:
plot(varImp(mod_fit))
Như đã nói, lệnh varImp()cho biết mức độ quan trọng và vai trò của các biến độc lập đối với khả năng
phân loại của mô hình. Chúng ta thử lại xem mô hình với hai chỉ biến age và educ thì sức mạnh giải
thích của mô hình thay đổi ra sao (không hiển thị kêt quả):
Việc loại bỏ các biến không quan trọng ở mô hình Logistic có thể làm tăng mức độ chính xác của mô
hình dự báo như chúng ta có thể thấy: từ 60% lên 62.56%.
Chúng ta cũng có thể đánh giá tỉ lệ sai sót huấn luyện cho mô hình mới (không hiện kết quả):
Chúng ta có thể thấy rằng tỉ lệ sai sót huấn luyện tăng lên một chút so với mô hình có 4 biến ban đầu.
Tình huống này một lần nữa nhắc nhở bạn về vấn đề overfiting: mô hình sau có tỉ lệ sai sót huấn luyện
tăng nhưng tỉ lệ sai sót kiểm định lại giảm. Nghĩa là mức độ dự báo (hút thuốc hay không hút thuốc)
có tính chính xác tăng lên. Thực tế, nếu công việc của chúng ta là tập trung vào dự báo một quan sát
cụ thể có hút thuốc hay không thì chúng ta nên ưu tiên mô hình mà tối thiểu hóa tỉ lệ sai sót kiểm
định.
Một vấn đề khác là việc lựa chọn dữ liệu huấn luyện có ảnh hưởng đến mức độ chính xác trong dự
báo. Câu hỏi là cần lấy tỉ lệ nào cho dữ liệu huấn luyện? Nếu dữ liệu là lớn thì tỉ lệ phân chia là 50/50.
Nếu dữ liệu là bé thì tỉ lệ này là 80/20 hoặc 70/30. Tất nhiên còn nhiều chi tiết tinh tế của việc chọn
tỉ lệ nhưng vấn đề này vượt quá khuôn khổ của tài liệu này. Bạn đọc có thể tìm hiểu thêm trong tài
liệu về gói caret và đặc biệt là cuốn Applied Predictive Modeling của Max Kuhn.
Ở trên chúng ta đã thấy rằng mô hình chỉ có hai biến là age và educ tạo cho tỉ lệ chính xác trong dự
báo cao hơn so với sử dụng toàn bộ bốn biến số age, educ, income và pcigs79. Vậy phải chăng với mục
đích dự báo chúng ta nên sử dụng mô hình hai biến số là age và educ hay một sự kết hợp nào đó từ 4
biến số age, educ, income và pcigs79 ?.
Để trả lời câu hỏi này, chúng ta cần trả lời câu hỏi sau: phải chăng tỉ lệ chính xác cao hơn ở trên mang
tính phổ quát chứ không phải chỉ là một trường hợp ngẫu nhiên?. Để giải thích rõ hơn điều này chúng
ta hãy xem xét một ví dụ mang tính giả thuyết dưới đây.
Tại Hà Nội có hai trường kinh tế lớn là NEU và Đại Học Ngoại Thương (FTU). Là một trường được
tách ra từ NEU nhưng giới sinh viên truyền tai nhau rằng sinh viên FTU ra trường làm việc sẽ được
ưu ái hơn và lương cao hơn. Để kiểm tra nhận định này, một nghiên cứu chọn 10 sinh viên mỗi trường
và tính mức lương trung bình của họ. Dưới đây là hai mẫu khảo sát của 10 sinh viên đến từ hai trường
cùng trung bình mức lương của hai nhóm:
## [1] 10
## [1] 4.9
Như vậy mức lương trung bình dựa trên mẫu khảo sát của 10 sinh viên NEU chỉ là 4.9 – con số chưa
bằng một nửa so với sinh viên đến từ FTU. Phải chăng nhận định rằng tốt nghiệp FTU thì sẽ có mức
lương trung bình cao hơn? Câu tra lời, theo quan điểm thống kê, là ngược lại. Thực vậy, sử dụng kiểm
định t để đánh giá khác biệt trung bình ta có:
t.test(ftu, neu)
## Welch Two Sample t-test
##
## data: ftu and neu
## t = 0.5664, df = 9.017, p-value = 0.5849
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -15.26318 25.46318
## sample estimates:
## mean of x mean of y
## 10.0 4.9
Vì p-value = 0.5849 > 5% nên chúng ta có thể thấy rằng sự chênh lệnh về mức lương trung bình trên
là không có ý nghĩa thống kê. Giải thích như thế này là dễ hiểu hơn: nếu chọn từng cặp 1 – 1 sinh viên
đến từ hai trường thì chúng ta sẽ có 9 tình huống mức lương của của sinh viên NEU cao hơn sinh viên
FTU so với 1 tình huống mức lương của sinh viên FTU cao hơn sinh viên NEU. Nguyên nhân là mức
lương trùng bình 10 triệu được quyết định bởi một quan sát rất bất thường có giá trị 91 trong khi 9
sinh viên FTU khac có mức lương chỉ 1 triệu mà thôi.Ví dụ trực quan này một lần nữa nhắc nhở các
bạn về suy nghĩ thống kê (statistical thinking).
Trở lại với câu hỏi ban đầu của chúng ta. Mức dự báo của mô hình có 2 biến số cao hơn mô hình 4
biến số như chúng ta vừa thấy ở trên chỉ là một tình huống cá biệt. Chúng ta cần đánh giá xem liệu
điều này có mang tính phổ quát hay không. Dưới đây là R code để đánh giá có có hay không tồn tại
tính chất phổ quát này. Trước hết ta chạy hai mô hình:
Ở đây chúng ta chạy cả hai mô hình với 1196 các quan sát đồng thời sử dụng kiểm tra chéo 10 lớp
(number=10), lặp lại 10 lần (repeats=10) với lựa chọn method="repeatedcv". Lựa chọn
classProbs=TRUE áp dụng cho mô hình phân loại và lựa chọn summaryFunction=defaultSummary để
chỉ thị R tính toán chỉ 2 thông tin về phầm chất của mô hình là Accuracy và Kappa. Với những lựa
chọn này chúng ta biết rằng sẽ có tất cả 100 bộ dữ liệu kiểm định, 100 bộ dữ liệu huấn luyện, 100
mô hình con cho mỗi mô hình 2 và 4 biến và chúng sẽ được sử dụng để chạy và đánh giá hai mô
hình.
Kế tiếp ta lấy ra các data frame gồm các thông tin về phẩm chất của mô hình (bao gồm Accuracy và
trị số Kappa). Tuy nhiên ở đây chúng ta chỉ quan tâm đến mức độ chính xác toàn cục Accuracy mà
thôi:
a <- logit2bien$resample # Lấy các thông tin về Accuracy của mô hình 2 biến.
a <- a[, -3]
a$Mohinh="Logit2"
b <- logit4bien$resample
b <- b[, -3]
b$Mohinh <- "Logit4"
resamplemod <- rbind(a, b) # Hợp nhất hai data frame a và b.
Trước khi đi vào các phân tích sâu hơn chúng ta thực hiện một số phân tích hình ảnh:
Từ phân tích hình ảnh này chúng ta có hai nhận định sau:
Khả năng phân loại của cả hai mô hình đều kém. Thể hiện ở không một mô hình nào có mức
độ chính xác lớn hơn 61.96% (đường thẳng đứng màu xanh).
Mức độ chính xác cao hơn của mô hình 2 biến số so với mô hình 4 biến số chỉ là một tình
huống cá biệt và do vậy không có tính phổ quát thể hiện ở boxplot màu xanh (ứng với mô hình
4 biến) có Q2 lệnh về phía phải hơn so với boxplot màu hồng (ứng với mô hình 2 biến).
Để chắc chắc chắn hơn cho những nhận định trên chúng ta sử dụng kiểm định t để đánh giá sự khác
biệt về Accuracy (mức độ chính xác) của hai mô hình:
t.test(resamplemod$Accuracy ~ resamplemod$Mohinh)
##
## Welch Two Sample t-test
##
## data: resamplemod$Accuracy by resamplemod$Mohinh
## t = -1.35, df = 196.53, p-value = 0.1786
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -0.013396089 0.002508585
## sample estimates:
## mean in group Logit2 mean in group Logit4
## 0.5984358 0.6038795
Vì p-value = 0.1786 > 5% nên chúng ta thấy rằng không có bằng chứng thống kê cho thấy không có
sự khác biệt về mức độ chính xác trong phân loại của hai mô hình. Chú ý rằng mức độ chính xác trung
bình 59.84% ứng với mô hình 2 biến và 60.39% của mô hình 4 biến là được tính toán trên 100 trường
hợp khác nhau vì chúng ta thực hiện kiểm định chéo 10 lớp và thực hiện lại 10 lần. Những giá trị trung
bình này có thể tính theo một cách khác:
summary(a)
summary(b)
Cũng có thể thực hiện kiểm định t xem có sự khác biệt về tiêu chí Kappa giữa hai mô hình không theo
cách hoàn toàn tương tự.
Chúng ta cũng có thể sử dụng hiệu chỉnh Bonferroni (Bonferroni correction) một thủ tục thống kê
tương tự kiểm định t của gói caret để đánh đưa ra bằng chứng thống kê cho sự khác biệt về mức độ
chính xác của hai mô hình.
13.2.2 Một số tiêu chí đánh giá chất lượng của mô hình Logistic
13.2.2.1 Kiểm định Hosmer-Lemeshow
Kiểm định này còn có tên gọi là kiểm định sự phù hợp của mô hình (Goodness of fit test) và được diễn
giải rất trừu tượng tại trang 410 sách giáo trình của NEU. Kiểm định này có thể được diễn giải đơn
giản hơn như sau. Nó kiểm định có hay không các xác suất dự báo cho các quan sát (hút thuốc hay
không hút thuốc) là tương tự với các quan sát trong thực tế. Nếu kiểm định này có giá trị p-value bé
hơn, chẳng hạn, 5% thì mô hình của chúng ta có mức độ dự báo kém. Cặp giả thuyết của kiểm định
này là:
H0: Các xác suất dự báo là tương tự với các quan sát trong thực.
H1: Các xác suất dự báo là khác với các quan sát trong thực.
Chúng ta sử dụng gói Mkmisc để thực hiện kiểm định này như sau:
library(MKmisc)
HLgof.test(fit = fitted(logit), obs = dung$smoker) # Thực hiện kiểm định
Hosmer-Lemeshow về độ phù hợp của mô hình.
## $C
##
## Hosmer-Lemeshow C statistic
##
## data: fitted(logit) and dung$smoker
Giá trị p-value thu được là bé hơn 5% nên chúng ta có bằng chứng thống kê bắc bỏ H0. Nói cách khác
mô hình là không phù hợp. Đáng chú ý là với mô hình Logistic nói riêng và các mô hình phân loại khác,
kiểm định này ít được sử dụng vì nhiều lý do. Thay vào đó, với các mô hình phân loại, bao gồm mô
hình Logistic người ta hay sử dụng các tiêu chí được trình bày dưới đây.
13.2.2.2 Các tiêu chí khác đo lường khả năng phân loại của mô hình
Các tiêu chí đo lường khả năng phân loại (hay dự báo của mô hình), ngoài Accuracy mà chúng ta đã
tìm hiểu sơ bộ ở mục trên, thì còn có các tiêu chí khác là Sensitivity, Specificity, Pos Pred Value, Neg
Pred Value, AUC, và hệ số Gini. Các tiêu chí này không chỉ được sử dụng để đánh giá mô hình Logistic
nói riêng mà còn được sử dụng để đánh giá các mô hình phân loại nói chung.
Để diễn giải chi tiết hơn ý nghĩa của các tiêu chí này chúng ta trở lại với mô hình mod_fit ở mục 13.2.1
với một số thay đổi nhỏ sau: chúng ta dựng mô hình với toàn bộ dữ liệu. Mọi diễn giải sẽ không có gì
thay đổi nếu bạn áp dụng cho dữ liệu kiểm định hoặc dữ liệu huấn luyện:
## Specificity : 0.1604
## Pos Pred Value : 0.6344
## Neg Pred Value : 0.4834
## Prevalence : 0.6196
## Detection Rate : 0.5543
## Detection Prevalence : 0.8737
## Balanced Accuracy : 0.5276
##
## 'Positive' Class : Nonsmoker
Ý nghĩa của một số tiêu chí chính thu được từ ma trận nhầm lẫn này là:
Mô hình xác định đúng 663 người không hút thuốc và xếp nhầm 382 người không hút thuốc
thành hút thuốc, nghĩa là mức độ chính xác bằng 63.44%. Con số này có thể tìm thấy ở dòng
Pos Pred Value.
Mô hình xác định đúng 73 người hút thuốc và xếp nhầm 78 người hút thuốc thành không hút
thuốc, nghĩa là mức độ chính xác bằng 48.34%. Con số này có thể tìm thấy ở dòng Neg Pred
Value.
Mô hình phân loại đúng tất cả (663 + 73) trong tổng số (663 + 73 + 382 + 78) quan sát, đạt
mức độ chính xác toàn cục là 61.65 %. Con số này có thể tìm thấy ở dòng Accuracy.
Tỉ số giữa những người không hút thuốc mà mô hình xác định đúng chia cho số người không
hút thuốc thực tế trong mẫu là 663 / (663 +78) = 89.47%. Có thể nói mô hình xác định đúng
tới gần 90% người không hút thuốc – một con số ấn tượng. Giá trị này có thể tìm ở dòng
Sensitivity (còn gọi là độ nhạy).
Tỉ số giữa những người hút thuốc mà mô hình xác định đúng chia cho tổng số người hút thuốc
thực tế trong mẫu là 73 / (73+ 382) = 16.04%. Có thể nói mô hình tuy dự báo rất tốt người
không hút thuốc nhưng lại dự báo rất tồi người hút thuốc. Con số này có thể tìm thấy ở dòng
Specificity (còn gọi là độ đặc hiệu). Chúng ta có thể tính toán lại trực tiếp như sau:
table(dung$smoker)
##
## Nonsmoker Smoker
## 741 455
## [1] 0.8947368
## [1] 0.1604396
Ngoài các tiêu chí mà chúng ta có thể thấy trực tiếp từ ma trận nhầm lẫn khi sử dụng gói caret, chúng
ta còn sử dụng hai tiêu chí khác là AUC và hệ số Gini. Để hiểu ý nghĩa của hai đại lượng này trước hết
chúng ta cần hiểu về đường ROC (viết tắt của Receiver Operating Characteristics):
Ở đây các bạn chú ý hai điều: (1) trục hoành của đường là (1 – Specificcity) còn trục tung là Sensitivity
và chỉ nằm trong khoảng từ 0 đến 1. Một mô hình có khả năng phân loại tốt là mô hình mà có đường
ROC này càng lồi về phía trên. Chú ý rằng phần diện tích của hình nằm phía dưới đường ROC nằm từ
0 đến 1 và được gọi là AUC – viết tắt của Area Under the Curve. Căn cứ vào AUC, một mô hình phân
loại sẽ được đánh giá như sau:
Còn hệ số Gini, vốn ít sử dụng hơn, là một đại lượng phái sinh của AUC và được tính bằng:
Gini = 2AUC -1
library(pROC)
pred1 <- predict(mod_fit, newdata = dung, type = "prob")
trangyeu <- roc(dung$smoker, pred1$Smoker)
trangyeu$auc # Tính AUC
Do AUC là 0.637 nên mô hình của chúng ta được xếp là phân loại kém. Chúng ta cũng có thể vẽ đường
ROC cũng như biểu diễn phần diện tích này:
## Call:
## roc.default(response = dung$smoker, predictor = pred1$Smoker)
##
## Data: pred1$Smoker in 741 controls (dung$smoker Nonsmoker) < 455 cases (du
ng$smoker Smoker).
## Area under the curve: 0.6366
Chúng ta cũng có thể “làm trơn” đường ROC đồng thời tính xấp xỉ AUC ứng với đường làm trơn này.
Chú ý rằng AUC thực (không làm tròn) vẫn là 0.637 chứ không phải 0.631 như hình hiển thị:
## Call:
## smooth.roc(roc = trangyeu)
##
## Data: pred1$Smoker in 741 controls (dung$smoker Nonsmoker) < 455 cases (du
ng$smoker Smoker).
## Smoothing: binormal
## Area under the curve: 0.6315
2*(trangyeu$auc) - 1
## [1] 0.2732363
Tiêu chí AUC (đánh giá mức độ lồi về phía trên của đường ROC) cũng là một tiêu chuẩn thường sử
dụng khi so sánh các mô hình phân loại với nhau.
Chúng ta xét ví dụ sau đây. Sau khi tốt nghiệp phổ thông học sinh Mĩ có ba lựa chọn để học tiếp. Một
là và các trường danh giá như Harvard (gọi là academic), hai là và các trường nghề (vocation) và cuối
cùng là trường đại cương (general). Chúng ta sẽ nghiên cứu xem ảnh hưởng của điểm viết (write) và
tầng lớp xã hội (ses) ảnh hưởng như thế nào đến việc chọn trường (prog) của học sinh. Chúng ta sử
dụng bộ dữ liệu có tên nghiyeu.dta gồm 200 quan sát để phân tích. Đây là bộ dữ liệu được lấy từ
chương 3 cuốn Applied Logistic Regression của Hosmer và Lemeshow. Trước hết chúng ta cần cài đặt
gói nnet. Sau khi cài đặt chúng ta có thể thực hiện các phân tích cần thiết.
library(foreign); library(tidyverse); library(nnet)
dung <- read.dta("nghiyeu.dta")
Chúng ta có thể xem xu hướng chọn trường theo tầng lớp xã của họ:
table(dung$ses, dung$prog)
##
## general academic vocation
## low 16 19 12
## middle 20 44 31
## high 9 42 7
Chúng ta có thể tính điểm write trung bình cũng như độ lệch chuẩn của thí sinh ứng với từng nhóm
trường mà họ thi vào:
## # A tibble: 3 x 3
## prog write_mean write_sd
## <fctr> <dbl> <dbl>
## 1 general 51.33333 9.397775
## 2 academic 56.25714 7.943343
## 3 vocation 46.76000 9.318754
Đúng như kì vọng các thí sinh thi vào trường academic sẽ có điểm trung bình cho write cao và độ lệch
chuẩn bé. Các bạn có thể thấy điều này qua điểm thi vào bác sĩ đa khoa của Y Hà Nội và Y Thái Bình.
Dưới đây là câu lệnh thực hiện hồi quy Logistic đa cấp độ trong R. Mấu chốt của là chúng ta chọn một
trường làm mốc so sánh. Ở đây là chọn nhóm trường academic. Về nguyên tắc các bạn có thể chọn
bất kì nhóm trường nào làm chuẩn so sánh.
dung$nhom1 <- relevel(dung$prog, ref = "academic")
mohinh <- multinom(nhom1 ~ ses + write, data = dung) # Chạy Multinomial
Logistic Regression.
## # weights: 15 (8 variable)
## initial value 219.722458
## iter 10 value 179.982880
## final value 179.981726
## converged
summary(mohinh)
## Call:
## multinom(formula = nhom1 ~ ses + write, data = dung)
##
## Coefficients:
## (Intercept) sesmiddle seshigh write
## general 2.852198 -0.5332810 -1.1628226 -0.0579287
## vocation 5.218260 0.2913859 -0.9826649 -0.1136037
##
## Std. Errors:
## (Intercept) sesmiddle seshigh write
## general 1.166441 0.4437323 0.5142196 0.02141097
## vocation 1.163552 0.4763739 0.5955665 0.02221996
##
## Residual Deviance: 359.9635
## AIC: 375.9635
Chúng ta diễn giải một số kết quả thu được của mô hình như sau:
Khi write tăng lên 1 điểm thì khả năng học khối trường general (tính bằng log odds) giảm
0.058 với chuẩn so sánh là trường khối academic.
Khi write tăng lên 1 điểm thì khả năng học khối trường vocation (tính bằng log odds) giảm
0.1136 với chuẩn so sánh là trường khối academic.
Nếu thí sinh thuộc tâng lớp thượng lưu (seshigh) thì thì khả năng học khối trường general
(tính bằng log odds) giảm 1.163 với chuẩn so sánh là trường khối academic.
Chúng ta cũng có thể tính các giá trị p-value cho các hệ số:
z <- summary(mohinh)$coefficients / summary(mohinh)$standard.errors
pvalue <- (1 - pnorm(abs(z), 0, 1))*2
pvalue
Tỉ số giữa xác suất chọn một khối trường cụ thể so với xác suất lựa chọn trường khối academic (chúng
ta chọn khối trường này làm chuẩn) được gọi là rủi ro tương đối (relative risk). Chúng ta tính rủi ro
tương đối này:
exp(coef(mohinh))
Chúng ta cũng có thể tính xác suất ước lượng của việc học khối trường nào cho 6 quan sát cuối:
xs <- fitted(mohinh)
tail(xs)
Điều này nghĩa là xác suất ước lượng cho việc học trường khối academic đối với quan sát thứ 195 là
bằng 0.837.
Chúng ta cũng có thể tính các xác suất ước lượng trung bình (averaged predicted probabilities) của
việc học khối trường nào tương ứng với ba tầng lớp xã hội tương ứng với các giá trị khác nhau của
biến liên tục write:
ses <- rep(c("low", "middle", "high"), each = 41)
write <- rep(c(30:70), 3)
dulieumoi <- data.frame(ses, write)
## pp.write$ses: high
## academic general vocation
## 0.6164315 0.1808037 0.2027648
## --------------------------------------------------------
## pp.write$ses: low
## academic general vocation
## 0.3972977 0.3278174 0.2748849
## --------------------------------------------------------
## pp.write$ses: middle
## academic general vocation
## 0.4256198 0.2010864 0.3732938
Ngoài cách tính xác suất trung bình ước lượng ứng với ba tầng lớp xã hội như trên chúng ta cũng có
thể sử dụng công cụ hình ảnh:
lpp <- melt(pp.write, id.vars = c("ses", "write"), value.name = "Prob")
ggplot(lpp, aes(x = write, y = Prob, colour = ses)) + geom_line() +
facet_grid(variable ~ ., scales = "free")
Chúng ta có thể thấy rằng với nhóm high (màu đỏ) khi điểm write càng tăng thì khả năng học trường
khối acadamic cũng tăng theo và có mức xác suất cao nhất so với hai nhóm còn lại. Tuy nhiên tình
hình hoàn toàn đảo ngược nếu chúng ta xét khả năng học nhóm trường general và vocational. Đây là
một kết luận dễ đoán trước không những ở bối cảnh nước Mỹ mà cả ở Việt Nam.
Mô hình Logistic đa cấp độ như vừa trình bày ở trên trong thực tế ít được sử dụng hơn so với một số
mô hình khác. Một trong những nhược điểm của nó là việc diễn giải các kết quả thường phức tạp và
khó khăn. Một trong những tiếp cận thay thế và dễ hiểu hơn cho mô hình Logistic đa cấp độ là mô
hình cây phân loại được trình bày ở mục 13.8.
##
## Nonadmit Admit
## 273 127
table(prob$rank, prob$admit)
##
## Nonadmit Admit
## top1 28 33
## top2 97 54
## top3 93 28
## top4 55 12
## # A tibble: 4 × 3
## rank M SD
## <fctr> <dbl> <dbl>
## 1 top1 611.8033 120.2429
## 2 top2 596.0265 107.0083
## 3 top3 574.8760 121.1481
## 4 top4 570.1493 116.2220
prob %>%
group_by(admit) %>%
summarise_each(funs(M = mean, SD = sd), gre)
## # A tibble: 2 × 3
## admit M SD
## <fctr> <dbl> <dbl>
## 1 Nonadmit 573.1868 115.8302
## 2 Admit 618.8976 108.8849
## admit
## rank Nonadmit Admit
## top1 28 33
## top2 97 54
## top3 93 28
## top4 55 12
Ở trên là các câu lệnh phân tích sơ bộ số liệu. Sau khi phân tích sơ bộ chúng ta có thể chạy mô hình
Probit với lệnh glm tương tự như chạy mô hình Logit:
probit <- glm(admit ~ gre + gpa + rank,
family = binomial(link = "probit"), data = prob)
summary(probit)
##
## Call:
## glm(formula = admit ~ gre + gpa + rank, family = binomial(link = "probit")
,
## data = dung)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
Diễn đạt ý nghĩa của mô hình Probit là tương tự như đối với mô hình Logit. Cụ thể, nếu điểm GRE tăng
1 đơn vị thì xác suất được nhận học (tính theo Z-score) tăng 0.1376%. Riêng đối với các biến số cho
hạng của trường được diễn đạt hơi khác: xác suất nhận học vào trường nhóm 2 sẽ giảm 41.54% so
với trường nhóm 1 (là nhóm trường làm gốc so sánh).
Chúng ta có thể đánh giá tác động tổng thể thứ hạng của trường (overall effect of rank) có ảnh hưởng
hay không đến xác suất được nhận học bằng lệnh wald.test của gói oad. Chú ý rằng thứ tự hạng của
trường (hay thứ tự hệ số ứng với hạng của trường là từ 4 đến 6):
wald.test(b = coef(probit), Sigma = vcov(probit), Terms = 4:6)
## Wald test:
## Chi-squared test:
## X2 = 21.4, df = 3, P(> X2) = 8.9e-05
Giá trị của thống kê khi bình phương là 21.4 tương ứng với p-value rất bé nên chúng ta có kết luận
rằng tác động tổng thể về thứ hạng của trường lên khả năng được nhận học là tồn tại và có ý nghĩa
thống kê.
Tương tự chúng ta cũng có thể kiểm định xem liệu, chẳng hạn, trường thứ hạng 2 có tác động khác
biệt so với trường thứ hạng 3 lên xác suất được nhận học hay không:
kiemdinh <- cbind(0, 0, 0, 0, 1, -1)
wald.test(b = coef(probit), Sigma = vcov(probit), L = kiemdinh)
## Wald test:
## Chi-squared test:
## X2 = 0.31, df = 1, P(> X2) = 0.58
Do giá trị p-value = 0.58 > 5% nên chúng ta có thể đưa ra bằng chứng rằng tác động thứ hạng của hai
nhóm trường này là khác biệt và có ý nghĩa thống kê.
Chúng ta cũng có thể sử dụng phân tích hình ảnh để đánh giá vai trò, chẳng hạn như điểm GRE đối với
khả năng nhận học khi các biến số khác cố định. Các câu lệnh dưới đây vẽ đồ thị biểu diễn mức xác
suất (tính theo điểm Z-score) theo biến gre ứng với 4 mức điểm GPA là 2.5, 3, 3.5, và 4 ứng với 4 nhóm
trường:
gre <- rep(seq(from = 200, to = 800, length.out = 100), 16)
gpa <- rep(c(2.5, 3, 3.5, 4), each = 400)
rank <- rep(c("top1", "top2", "top3", "top4"), each = 100)
dulieumoi <- data.frame(gre, gpa, rank)
str(dulieumoi)
đặc biệt để ưu tiêu lựa chọn mô hình này so với mô hình kia. Tuy nhiên các nhà nghiên cứu thường
chọn mô hình Logit do nó có lợi thế đơn giản về mặt toán học và diễn đạt các kết quả thuận tiện hơn
(Gujarati, 2011) cho các nghiên cứu mô tả, diễn giải. Để tìm hiểu kĩ hơn về mặt lý thuyết của các mô
hình Logistic, Probit cũng như các mô hình tương tự có thể đọc cuốn Giáo Trình Kinh Tế Lượng NEU
hoặc một số sách về kinh tế lượng khác.
Một trong những tiêu chí hay sử dụng khi đánh giá, so sánh các mô hình phân loại khác nhau là AUC
hay phần diện tích nằm dưới đường cong ROC (viết tắt của receiver operating characteristic). Chúng
ta trở lại với bộ số liệu ở mục 13.2 và so sánh hai mô hình phân loại là Logistic và Probit căn cứ vào
tiêu chí này. Để thuận lợi chúng ta sẽ sử dụng gói caret. Khác biệt ở đây là chúng ta sẽ sử dụng toàn
bộ các quan sát để đánh giá theo cách tiếp cận 10-folds cross-validation và lặp lại 10 lần. Như thế có
nghĩa là chúng ta sử dụng 9/10 toàn bộ quan sát để dựng mô hình, sử dụng 1/10 quan sát để đánh
giá mô hình. Do vòng này lặp lại 10 lần nên thực tế chúng ta có 100 mô hình “con” ứng với 100 bộ dữ
liệu huấn luyện và kiểm định. Các kết quả có được từ 100 mô hình này sẽ được sử dụng để đánh giá
hiệu quả phân loại của mô hình Logistic và Probit. Tiêu chí đánh giá và so sánh ở đây là AUC/ROC và
được thể hiện bằng lựa chọn metric = "ROC":
set.seed(2611)
ctrl <- trainControl(method = "repeatedcv", number = 10, repeats = 10,
classProbs = TRUE, summaryFunction = twoClassSummary)
# Chạy mô hình Logistic:
logistic <- train(smoker~., data = dung, method = "glm", family = "binomial",
trControl = ctrl, metric = "ROC")
# Chạy mô hình Probit:
probit <- train(smoker~., data = dung, method = "glm", family = "binomial"(li
nk = "probit"),
trControl = ctrl, metric="ROC")
Kế tiết chúng ta tạo trích ra một data frame tên là love chứa các thông tin về chất lượng của hai mô
hình. Chú ý rằng với lựa chọn thì data frame này ngoài ROC còn chứa các thông tin khác là Sens (viết
tắt của Sensitivity) và Spec (viết tắt của Specitivity):
m <- logistic$resample # Lấy các thông tin về Accuracy của mô hình 2 biến.
m$Mohinh <- "LOGISTIC"
n <- probit$resample
n$Mohinh <- "PROBIT"
love <- rbind(m, n) # Hợp nhất hai data frame a và b.
Có thể thấy sự khác biệt về ROC là không đáng kể. Chúng ta sử dụng kiểm định t để đánh giá sự khác
biệt này:
t.test(love$ROC~love$Mohinh)
##
## Welch Two Sample t-test
##
## data: love$ROC by love$Mohinh
## t = -0.042881, df = 194.24, p-value = 0.9658
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -0.01463692 0.01401398
## sample estimates:
## mean in group LOGISTIC mean in group PROBIT
## 0.6115125 0.6118240
Kết quả kiểm định t có p-value = 0.9658 là rất lớn nên chúng ta thấy rằng sự khác biệt về chất lượng
phân loại khi căn cứ vào ROC là không có ý nghĩa thống kê.
Tương tự, nếu muốn đánh giá các tiêu chí Sensitivity và Specitivity (hoặc bất cứ tiêu chí nào khác)
chúng ta cũng thực hiện hoàn toàn tương tự như trên.
trình bày tại trang 594 trong cuốn sách Introductory Econometrics ấn bản lần thứ 5. Chúng ta sử
dụng bộ dữ liệu này để đánh giá (dự báo) tình trạng tham gia lực lượng lao động của nữ giới (biến
inlf) phụ thuộc như thế nào vào trình độ giáo dục (biến educ), tuổi (biến age), kinh nghiệm (exper),
bình phương của kinh nghiệm (exper2), có con nhỏ hơn 6 tuổi (kidslt6), có con từ trên 6 đến 18 tuổi
(kidsge6), và thu nhập của chồng (nwifeinc). Ở đây biến phụ thuộc là inlf = 1 nếu tham gia lực lượng
lao động, = 0 nếu khác.
Dưới đây là các câu lệnh chạy cả ba mô hình LPM, Logit, và Probit cũng như so sánh chúng:
setwd("D:/KTLR")
library(foreign)
trang <- read.dta("MROZ.DTA")
str(trang) # Xem qua bộ dữ liệu.
table(trang$inlf) # Xem có bao nhiêu người tham gia lực lượng lao động.
##
## 0 1
## 325 428
trang <- trang[, c(1, 20, 6, 19, 5, 3, 4)] # Chỉ lấy các biến cần thiết.
trang$exper2 <- (trang$exper)^2 # Tạo biến mới age2 bằng bình phương của age.
lpm <- lm(inlf ~., data = trang) # Chạy LPM.
trang$inlf <- factor(trang$inlf, levels = c("0", "1"),
labels = c("Une", "Emp"))
logit <- glm(inlf ~., family = binomial, data = trang)
probit <- glm(inlf ~., family = binomial(link="probit"), data = trang)
library(stargazer)
stargazer(lpm, logit, probit, title = "So sánh ba mô hình", type = "text")
## So sanh ba mô hình
## ===============================================================
## Dependent variable:
## -------------------------------------------
## inlf
## OLS logistic probit
## (1) (2) (3)
## ---------------------------------------------------------------
## nwifeinc -0.003** -0.021** -0.012**
Các bạn có thể đối chiếu với kết quả này với kết quả được Wooldridge trình bày tại trang 594 trong
cuốn sách Introductory Econometrics ấn bản lần thứ 5. Để khai thác thêm thông tin nhằm so sánh
các mô hình, chẳng hạn, giữa Probit là Logit căn cứ vào mức độ chính xác trong việc phân loại các bạn
có thể tạo ra ma trận nhầm lẫn (Confusion Matrix) như ở mục 13.2 của chương này.
13.7 Ứng dụng trong nghiên cứu của mô hình Logit và Probit và một số mô hình phân loại khác
cho xếp hạng tín dụng
Việc tái tạo (replicate) hay chí ít là mô phỏng các nghiên cứu của các tác giả đi trước là một việc cần
thiết. Tại chương 10, trang 440 sách giáo trình của NEU có đề cập đến một nghiên cứu của tác giả
Phan Lê Hà về xếp hạng tín dụng cho khách với mô hình Logit và Probit có tên “Assesing The
Effectiveness of Consumer Credit Scoring: The Case of a Leading Vietnam Commercial Bank” với
bộ số liệu mà giáo trình có đề cập là LEHA.wf1. Tuy nhiên, bộ số liệu thực hành đi kèm cuốn giáo trình
này không tồn tại bộ dữ liệu như miêu tả ở trên.
Để thay thế, tôi sử dụng bộ dữ liệu ở một nghiên cứu tương tự có tên “The comparisons of data
mining techniques for the predictive accuracy of probability of default of credit card clients” của
Yeh & Lien (2009). Nghiên cứu này có ở cơ sở dữ liệu của Sciencedirect:
http://www.sciencedirect.com/science/article/pii/S0957417407006719
Bộ dữ liệu của nghiên cứu này được lưu trữ ở cơ sở dữ liệu của University of California, Irvine. Bộ dữ
liệu này gồm các thông tin về hồ sơ tín dụng của 30000 khách hàng. Biến phụ thuộc ở đây là Y (với Y
= 1 nghĩa là khách hàng mất khả năng thanh toán, bằng 0 nếu khác). Các biến độc lập (cả định tính lẫn
định lượng từ X1 đến X23) với số lượng là 23. Các bạn có thể xem miêu tả chi tiết và download bộ dữ
liệu này tại:
https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients
Tuy nhiên, để thuận lợi cho các bạn, tôi đã download bộ data này và gửi cùng bộ data của tài liệu này
với tên gọi credit.csv.
Chúng ta sẽ sử dụng bộ dữ liệu này để mô phỏng nghiên cứu của tác giả Phan Le Hà. Tuy nhiên, các
nghiên cứu thường thấy (bao gồm cả nghiên cứu này) khi sử dụng các mô hình phân loại (như Logit,
Probit) chưa đề cập đến hai khía cạnh sau.
Một là, chưa chỉ rõ tỉ lệ, hay mức độ chính xác của mô hình phân loại. Chẳng hạn, mức độ chính xác
phân loại đối với nhóm hồ sơ xấu là bao nhiêu ?.
Hai là, sử dụng chính tỉ lệ sai sót huấn luyện (hoặc một số tiêu chí khác như R2 của MacFadden) làm
tiêu chuẩn đánh giá mức độ chính xác của mô hình phân loại là một cách tiếp cận chưa chính xác vì
hai lý do dưới đây.
Thứ nhất, về khía cạnh lý thuyết, tỉ lệ sai sót huấn luyện thường có xu hướng bé hơn tỉ lệ sai sót kiểm
định và do đó với mục đích dự báo, sử dụng tỉ lệ sai sót huấn luyện làm tiêu chí đánh giá sức mạnh
phân loại của mô hình là chưa phù hợp (James et al., 2014; Kuhn, 2013).
Thứ hai, về khía cạnh thực tế, các ngân hàng ngoài quan tâm đến tỉ lệ chính xác trong phân loại và dự
báo hồ sơ xấu còn quan tâm đến hậu quả kinh tế (lãi hay lỗ) nếu sử dụng mô hình phân loại. Thực
vậy, một mô hình có tỉ lệ phân loại chính xác toàn cục cao chưa hẳn đã là mô hình tối ưu đối với
ngân hàng. Chúng ta sẽ nghiên cứu vấn đề này chi tiết trong mục này.
Trước hết, chúng ta mô phỏng nghiên cứu của tác giả Phan Lê Hà với bộ dữ liệu của Yeh & Lien (2009)
bằng mô hình Logit và Probit. Tuy nghiên cứu gốc của Yeh & Lien sử dụng toàn bộ 23 biến nhưng với
mục đính minh họa chúng ta chỉ sử dụng 8 biến độc lập là X1,X6, X18, X19, X20, X21, X22, và X23.
Ngoài ra, kích thước cho bộ dữ liệu kiểm định cũng như huấn luyện chỉ là 1000. Việc cắt giảm số biến
số, kích thước dữ liệu chỉ đơn thuần là lý do kĩ thuật: máy tính cần quá nhiều thời gian để thực hiện
một số mô hình phân loại. Nếu máy tính của bạn đủ mạnh và bạn đủ thời gian tôi khuyến khích các
bạn sử dụng cả 23 biến số như nghiên cứu gốc. Dưới đây là Rcode cho mô hình Probit và Logit cũng
như đánh giá mô hình:
setwd("E:/KTLR")
dung <- read.csv("credit.csv")
library(tidyverse)
# Dán lại nhãn cho biến mục tiêu được phân loại:
dung$Y <- recode_factor(dung$Y,
"1" = "Default",
"0" = "NonDefault")
head(dung, 2)
## [1] 30000 9
head(dung, 2)
# Chia bộ dữ liệu thành hai phần bằng nhau (1000 cho mỗi phần):
library(caret)
set.seed(123)
indxTrain <- createDataPartition(y = dung$Y, p = 1 / 2, list = FALSE)
training <- dung[indxTrain, ]
testing <- dung[-indxTrain, ]
# Thiêt lập các lựa chọn thực hiện Cross-Validation:
set.seed(234)
ctrl <- trainControl(method = "repeatedcv",
number = 10,
repeats = 10,
classProbs = TRUE,
summaryFunction = multiClassSummary)
# Mô hình Logistic:
logistic <- train(Y ~.,
data = training,
method = "glm",
family = "binomial",
trControl = ctrl)
# Các tiêu chí đánh giá mô hình Logistic:
pred <- predict(logistic, newdata = testing)
confusionMatrix(data = pred, testing$Y)
# Mô hình Probit:
probit <- train(Y ~.,
data = training,
method = "glm",
family = "binomial"(link = "probit"),
trControl = ctrl)
## Default 52 32
## NonDefault 198 718
##
## Accuracy : 0.77
## 95% CI : (0.7426, 0.7958)
## No Information Rate : 0.75
## P-Value [Acc > NIR] : 0.07626
##
## Kappa : 0.2123
## Mcnemar's Test P-Value : < 2e-16
##
## Sensitivity : 0.2080
## Specificity : 0.9573
## Pos Pred Value : 0.6190
## Neg Pred Value : 0.7838
## Prevalence : 0.2500
## Detection Rate : 0.0520
## Detection Prevalence : 0.0840
## Balanced Accuracy : 0.5827
##
## 'Positive' Class : Default
##
Chúng ta đọc kết quả phân tích như sau. Chẳng hạn với mô hình phân loại Probit, mô hình phân loại
đúng 52 hồ sơ xấu trong tổng số 52 + 32 = 84 hồ sơ xấu và do vậy mức độ chính xác trong phân loại
hồ sơ xấu chỉ là 52 / 84 = 61.9 % (giá trị Pos Pred Value). Tương tự mức độ chính xác trong phân loại
hồ sơ tốt của mô hình này là 78.38 % (giá trị Neg Pred Value). Tỉ lệ chính xác toàn cục (Accuracy) cho
phân loại là (52 + 718) / 1000 = 77%.
Nếu căn cứ vào tỉ lệ dự báo toàn cục thì mô hình phân loại Logit tốt hơn (78% so với 77%). Phải chăng
bạn sẽ kiến nghị ngân hàng sử dụng mô hình Logit cho phân loại thay vì Logit?. Câu trả lời là chưa hẳn
như vậy. Trong tình huống của chúng ta, là ngược lại. Thực vậy, nếu chúng ta giả thiết rằng cứ một hồ
sơ xấu mà ta phân loại thành hô sơ tốt, thì cho vay 1$ ngân hàng sẽ mất trắng 1$. Còn hồ sơ tốt mà
phân loại đúng là hồ sơ tốt thì cho vay 1$ ngân hàng chỉ thu về lãi là 0.1 $ (với giả thiết lãi 10 % và
ngân hàng không gánh chi phí nào khác). Chúng ta giả thiết rằng mỗi một hồ sơ được duyệt vay thi sẽ
được vay 1$. Nếu thế, chúng ta có thể tóm tắt kết quả như sau:
Kết quả này chỉ ra rằng nếu sử dụng mô hình phân loại Probit – một mô hình phân loại kém chính xác
hơn mô hình Logit thì ngân hàng sẽ có nhiều lợi ích kinh tế hơn. Điều này xác nhận một lần nữa rằng:
tiêu chí lựa chọn mô hình phân loại trong thực tế của ngân hàng chưa hẳn đã là căn cứ vào mô
hình phân loại chính xác nhất. Vì lãi ròng của ngân hàng nếu chấp nhận mô hình Probit là 39.8 $ lớn
hơn 35.4 $ so với lựa chọn mô hình Logit.
Nguyên nhân là cái giá phải trả khi xếp nhầm hồ sơ xấu thành hồ sơ tốt là cao hơn rất nhiều lần so
với xếp nhầm hồ sơ tốt. Nên một mô hình mặc dù có mức độ chính xác khi phân loại nói chung cao
hơn lại có thể chưa phải là mô hình mang lại lợi nhuận tối ưu vì có thể đó là mô hình mà xếp nhầm
hồ sơ xấu thành hồ sơ tốt với tỉ lệ cao hơn.
Tuy nhiên cần phải lưu lý rằng, mức lợi nhuận cao hơn khi sử dụng mô hình Probit cho phần loại mà
chúng ta thấy ở đây liệu có tính phổ quát hay không vẫn là một câu hỏi. Vì chúng ta mới chỉ đánh giá
hai mô hình chỉ với một mẫu được chọn mà thôi (là testing data). Nghĩa là, với bộ số liệu mới, không
có gì chắc chắn rằng sử dụng Probit sẽ mang lại nhiều lợi nhuận hơn cho ngân hàng. Chúng ta sẽ
nghiên cứu cách tiếp cận theo ngôn ngữ của khoa học thống kê nhằm đưa ra câu trả lời cho câu hỏi
trên ở mục 13.8.2 . Điểm khác biệt ở đây là thay vì so sánh Logistic với Probit, chúng ta so sánh Logistic
với một mô hình có tên cây phân loại. Việc áp dụng trở lại cho so sánh Logistic với Probit là hoàn toàn
tương tự.
Có thể đánh giá các thước đo đánh giá phẩm chất của hai mô hình Logit và Probit qua phân tích
hình ảnh. Những thông tin về các thước đo đánh giá phẩm chất của hai mô hình này thu được từ 100
mẫu con do chúng ta đã thực hiện 10-fold cross-validation và lặp lại quá trình này 10 lần:
# Lưu lại các tiêu chí đánh giá phẩm chất của 2 mô hình:
r1 <- logistic$resample
r2 <- probit$resample
# Các tiêu chí đánh giá hai mô hình và xem qua:
total <- rbind(r1, r2) %>%
mutate(Model = c(rep("Logistic", 100), rep("Probit", 100)))
head(total[, 1:6])
theme_bw() +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())
Có thể đánh gía hình ảnh về Accuracy cho hai mô hình dựa trên 100 mẫu con đồng thời sử dụng kiểm
định t để đưa ra bằng chứng thống kê:
Căn cứ vào hình ảnh này có thể thấy mức độ chính xác toàn cục của Logistic có thể là cao hơn. Để đưa
ra bằng chứng thống kê cho nhận định trên có thể sử dụng kiểm định t:
t.test(total$Accuracy ~ total$Model)
##
## Welch Two Sample t-test
##
## data: total$Accuracy by total$Model
## t = 4.0803, df = 197.77, p-value = 6.522e-05
Kết quả chỉ ra rằng sự khác biệt về mức độ chính xác khi phân loại của hai mô hình là có ý nghĩa
thống kê.
13.8 Lựa chọn mô hình phù hợp cho bài toán phân loại – xếp hạng hồ sơ tín dụng
Dựa trên những phân tích ở mục 13.7 chúng ta rút ra một số kết luận dưới đây:
Để tối đa hóa lợi nhuận, hay chí ít là mang lại lợi ích kinh tế tốt nhất có thể (cho ngân hàng)
thì mô hình có mức độ phân loại chính xác toàn cục cao nhất chưa chắc đã là mô hình được
lựa chọn.
Việc so sánh phẩm chất của mô hình dựa trên một tiêu chí được lựa chọn (ví dụ như lợi nhuận,
mức độ chính xác chung) không thể dựa vào CHỈ MỘT mẫu.
Để có cách tiếp cận hơn trong việc lựa chọn mô hình phân loại chúng ta viết một hàm thực hiện việc
đánh giá phẩm chất của hai mô hình Logit và Probit dựa trên thử nghiệm (hay chạy) với, ví dụ, 100
mẫu khác nhau rồi ghi lại các tiêu chí đánh giá phẩm chất của hai mô hình này. Mẫu này phải là
những quan sát không thuộc dữ liệu huấn luyện (training) để tránh overfitting - tức là hiện tượng mà
mô hình thì rất khớp với dữ liệu đã có nhưng lại dự báo (khớp) rất tồi với dữ liệu mới. Các quy ước ở
đây là:
2. GB là hồ sơ là tốt nhưng xác phân loại sai thành xấu (Good - Bad).
# Viết hàm:
my_validation <- function(mohinh, ti_le, solanlap, dulieu, ...) {
luu_kq <- data.frame()
for (i in 1:solanlap) {
set.seed(i)
id <- createDataPartition(y = dulieu$Y, p = ti_le, list = FALSE)
test <- dulieu[id, ]
pred <- predict(mohinh, newdata = test)
u <- confusionMatrix(pred, test$Y, positive = "Default")
k <- as.vector(u$table)
luu_kq <- rbind(luu_kq, k)
tenmoi <- c("BB", "GB", "BG", "GG")
names(luu_kq) <- tenmoi
}
return(luu_kq)
}
Sử dụng hàm vừa viết trong đó chạy 100 lần với 50% bộ dữ liệu testing. Chú ý rằng số cách lấy ra
50% mẫu từ testing là tổ hợp 150 của 300 (một con số rất lớn):
all_df %>%
group_by(Model) %>%
summarise_each(funs(mean, min, max, sd), Profit)
## # A tibble: 2 x 5
## Model Profit_mean Profit_min Profit_max Profit_sd
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Logistic 18.569 11.1 25.4 3.310336
## 2 Probit 20.747 13.3 26.5 3.106769
all_df %>%
group_by(Model) %>%
summarise_each(funs(mean, min, max, sd), Accuracy)
## # A tibble: 2 x 5
## Model Accuracy_mean Accuracy_min Accuracy_max Accuracy_sd
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Logistic 0.78144 0.762 0.804 0.009398388
## 2 Probit 0.77122 0.748 0.792 0.009073861
Kết quả trên chỉ ra rằng: khi chạy thử nghiệm trên 100 mẫu con lấy ra từ dữ liệu kiểm định (testing)
thì Accuracy của Logistic cao hơn nhưng mô hình mang lại nhiều lợi nhuận hơn cho ngân hàng chính
là Probit – một mô hình có mức độ chính xác toàn cục trong phân loại thấp hơn.
Chúng ta có thể thực hiện các phân tích hình ảnh minh họa cho kết quả thu được ở trên:
# Thực hiện phân tích hình ảnh cho Profit với box plot:
all_df %>% ggplot(aes(Model, Profit, fill = Model, color = Model)) +
geom_boxplot(alpha = 0.4, show.legend = FALSE) + theme_bw()
# Thực hiện phân tích hình ảnh cho Accuracy với box plot (không hiển thị):
all_df %>% ggplot(aes(Model, Accuracy, fill = Model, color = Model)) +
geom_boxplot(alpha = 0.4, show.legend = FALSE) + theme_bw()
Để minh họa về mô hình này, chúng ta xét bộ số liệu có tên iris của Fisher (1936). Đây là bộ số liệu
gồm 150 quan sát về 3 loài hoa diên vĩ (setosa, versicolor, virginica - biến định tính Species) với số
lượng như nhau. Mục tiêu của chúng ta là tìm cách phân loại ba giống hoa diên vĩ này căn cứu vào các
thông tin như chiều dài cuống hoa, chiều rộng cuống hoa… Đây là bộ dữ liệu nổi tiếng và xuất hiện
nhiều trong các sách về thống kê, Machine Learning cũng như các sách về Statistical Learning và Data
Mining. Bộ dữ liệu này luôn tồn tại khi cài đặt R:
data("iris")
dim(iris)
## [1] 150 5
str(iris)
Trước hết chúng ta sẽ sử dụng gói rpart để thực hiện mô hình cây cho phân loại kết hợp với hàm
train() của gói caret:
set.seed(2611)
indxTrain <- createDataPartition(y = iris$Species, p = 8 / 10, list = FALSE)
training <- iris[indxTrain, ]
testing <- iris[-indxTrain, ]
library(rpart)
trang <- rpart(Species ~., data = training, method = "class") # Chạy mô hình
cây bằng gói rpart.
trang # Để xem kết quả của mô hình.
## n= 120
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 120 80 setosa (0.33333333 0.33333333 0.33333333)
## 2) Petal.Length< 2.45 40 0 setosa (1.00000000 0.00000000 0.00000000) *
## 3) Petal.Length>=2.45 80 40 versicolor (0.00000000 0.50000000 0.50000000
)
## 6) Petal.Width< 1.75 43 4 versicolor (0.00000000 0.90697674 0.0930232
6) *
## 7) Petal.Width>=1.75 37 1 virginica (0.00000000 0.02702703 0.97297297
) *
Kết quả thu được từ mô hình trình bày theo cách này là khó đọc. Chúng ta làm cho việc này sáng tỏ
hơn một cách hình ảnh với sự hỗ trợ của gói rpart.plot:
library(rpart.plot)
rpart.plot(trang, legend.x = 0.7)
Ý nghĩa của sơ đồ này như sau. Nếu chiều dài cuống hoa mà bé hơn 2.4 thì đó là loài sesota. Các con
số 1.00 0.00 0.00 ở ô màu đỏ ngụ ý rằng loài này được phân loại chính xác 100%, sai số là 0%, và
chiếm 33% toàn bộ mẫu huấn luyện. Nếu chiều dài cuốn hoa lớn hơn hoặc bằng 2.4 thì “tạm” xếp
chúng thành loài versicolor. Với nhóm được xếp tạm này, lại căn cứ vào chiều rộng cuống hoa. Cụ thể:
nếu bé hơn 1.8 thì chúng thuộc versicolor và được xếp loại chính xác đến 91% và do vậy tỉ lệ phân
loại sai là 9%. Còn nếu lớn hơn hoặc bằng 1.8 thì chúng thuộc loại virginica và được xếp loại chính
xác đến 97% ứng với tỉ lệ sai sót 3%. Sơ đồ trên cũng có thể được vẽ bằng một kiểu khác nhưng ý
nghĩa vẫn không đổi:
library(rattle)
fancyRpartPlot(trang) # Cách vẽ thứ khác với sự trợ giúp của gói rattle.
Chú ý rằng các tỉ lệ chính xác – sai sót mà chúng ta vừa thấy là cho bộ dữ liệu huấn luyện. Cái chúng
ta quan tâm là mức độ chính xác của mô hình phân loại này cho bộ dữ liệu kiểm định:
13.9.2 So sánh mô hình cây phân loại và Logistic dựa trên hậu quả kinh tế của việc sử dụng
Chúng ta sẽ nghiên cứu khả năng áp dụng của mô hình này trong thực tế với bộ số liệu có tên
GermanCredit. được tích hợp cùng gói caret. Đây là bộ số liệu về 1000 đơn xin vay tín dụng của một
ngân hàng Đức và được sử dụng ở nhiều nghiên cứu về các mô hình phân loại, xếp hạng tín dụng.
Thông tin đầu vào để lấy căn cứ phân loại là 61 biến số khác nhau, bao gồm cả định tính lẫn định
lượng. Các hồ sơ sẽ được xếp loại Good hoặc Bad (biến Class). Với mục đích minh họa, chúng ta sẽ chỉ
sử dụng các biến độc lập có vị trí ở cột thứ 1,2,5, và 9. Biến ở vị trí thứ 10 là Class. Tất nhiên các bạn
có thể sử dụng toàn bộ các biến số để xay dựng mô hình nhưng việc này sẽ đòi hỏi máy tính nhiều
thời gian để chạy:
data("GermanCredit")
trang <- GermanCredit[, c(1, 2, 5, 9, 10)]
str(trang)
Để so sánh khả năng dự báo của mô hình cây là logistic cũng như một số tiêu chí khác, trước hết chúng
ta đánh giá sơ bộ cho hai mô hình này cho một tình huống cụ thể. Dưới đây chúng ta chia bộ số liệu
thành hai phần. Dữ liệu huấn luyện và dữ liệu kiểm định được lấy theo tỉ lệ 70/30:
## Kappa : 0.0599
## Mcnemar's Test P-Value : 4.432e-14
##
## Sensitivity : 0.08889
## Specificity : 0.95714
## Pos Pred Value : 0.47059
## Neg Pred Value : 0.71025
## Prevalence : 0.30000
## Detection Rate : 0.02667
## Detection Prevalence : 0.05667
## Balanced Accuracy : 0.52302
##
## 'Positive' Class : Bad
##
So sánh sơ bộ chúng ta có thể thấy mô hình Logistic có vẻ chiếm ưu thế về mức độ chính xác. Mặt
khác, chúng ta hãy xem hiệu quả về mặt kinh tế nếu ngân hàng sử dụng những mô hình xếp hạng tín
dụng này. Với giả thiết là lãi 10%, lợi nhuận của ngân hàng sẽ là -11.55 và -2.1. Nghĩa là Logistic chiếm
ưu thế hơn khi căn cứ cả hai khía cạnh là chính xác trong phân loại và tiêu chí lợi nhuận.
Câu hỏi còn lại là: phải chăng kết luận trên có tính phổ quát và ngân hàng nên sử dụng Logistic?.
Để đảm bảo rằng ưu thế này của mô hình Logistic không phải là một trường hợp cá biệt của mẫu kiểm
định, dưới đây là một vòng lặp chạy 100 lần cả hai mô hình này với dữ liệu kiểm định và huấn luyện
được chia theo tỉ lệ 70:30. Cũng như mục 13.8, các tiêu chí đánh giá mô hình được lựa chọn là:
Accuraccy, số lượng hồ sơ xấu xếp nhầm thành tốt (kí hiệu BG) và số lượng hồ sơ tốt xếp chính xác
thành tốt (kí hiệu là GG) và đương nhiên là lợi nhuận của ngân hàng khi sử dụng các mô hình phân
loại tín dụng khác nhau. Như vậy cứ mỗi một mô hình chúng ta có 100 giá trị cho cả bốn tiêu chí này
và sẽ được đánh giá bằng kiểm định t về sự khác biệt về giá trị trung bình giữa chúng.
Dưới đây là R code để thực hiện đánh giá chất lượng của hai mô hình. Chắc chắn nó là một thử thách
với trí não của bạn, nhất là với những ai chưa bao giờ lập trình (viết code, programming). Nhưng tôi
tin bạn đủ kiên trì và cố gắng để hiểu chúng. Chú ý rằng có thể mất rất nhiều thời gian để chạy chương
trình dưới đây:
Muốn biết những phẩm chất nào của mô hình được lưu trong data frame có tên total:
names(total)
Đến đây chúng ta có thể thực hiện phân tích hình ảnh cũng như kiểm định t cho ba tiêu chí lựa chọn
là Accuracy, BG, và GG như đã làm ở mục 13.8:
library(ggplot2); library(gridExtra)
a <- ggplot(total, aes(Mohinh, Accuracy, colour = Mohinh)) + geom_boxplot()
b <- ggplot(total, aes(Accuracy, fill = Mohinh)) + geom_density(alpha = 0.3)
grid.arrange(a, b, ncol = 2, nrow = 1)
Từ hình ảnh thu được có thể nhận định rằng Logistic là mô hình có mức độ phân loại chính xác toàn
cục cao hơn. Thực hiện kiểm định t để đánh giá sự khác biệt này:
t.test(total$Accuracy ~ total$Mohinh)
##
## Welch Two Sample t-test
##
## data: total$Accuracy by total$Mohinh
## t = 3.8757, df = 192.9, p-value = 0.0001457
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 0.002979321 0.009154012
## sample estimates:
## mean in group Logistic mean in group Tree
## 0.7057333 0.6996667
Kết quả này chỉ ra rằng Accuracy (mức độ chính xác toàn cục) của mô hình cây là kém hơn và kết luận
này có ý nghĩa thống kê do p-value là rất bé. Đáng chú ý là sự sai khác này rất bé.
Tương tự chúng ta thực hiện phân tích hình ảnh và kiểm định t cho BG và GG:
t.test(total$BG ~ total$Mohinh)
##
## Welch Two Sample t-test
##
## data: total$BG by total$Mohinh
## t = 3.0517, df = 151.29, p-value = 0.002688
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 0.8884666 4.1515334
## sample estimates:
## mean in group Logistic mean in group Tree
## 8.98 6.46
t.test(total$GG ~ total$Mohinh)
##
## Welch Two Sample t-test
##
## data: total$GG by total$Mohinh
## t = -3.0517, df = 151.29, p-value = 0.002688
## alternative hypothesis: true difference in means is not equal to 0
Từ những kết quả này các bạn rút ra những kết luận cực kì quan trọng sau.
Thứ nhất, có sự khác biệt về khả năng dự báo hai loại hồ sơ và kết luận này có ý nghĩa thống kê. Cụ
thể là mô hình Logistic có mức độ chính xác toàn cục khi phân loại tín dụng cao hơn.
Nhưng có đúng là ngân hàng sẽ chấp nhận mô hình này? Câu trả lời hơi bất ngờ: ngược lại. Các bạn có
thể thấy ngay sau đây.
Với giả thiết rằng mỗi hồ sơ phân loại đúng mang lại lợi nhuận 10%, một hồ sơ xếp nhầm thì ngân
hàng mất trắng vốn và cứ giả định rằng mỗi một hồ sơ vay 1 USD , ta tính lợi nhuận của ngân hàng
ứng với các mô hình rồi thực hiện phân tích hình ảnh cho lợi nhuận:
Rõ ràng, hình ảnh mà cho thấy câu chuyện ngược lại: nếu ngân hàng sử dụng mô hình cây thì lợi nhuận
thu được sẽ cao hơn. Chúng ta cần đánh giá xem liệu kết luận này có ý nghĩa thống kê – tức có tính
phổ quát bằng kiểm định t:
t.test(total$loinhuan ~ total$Mohinh)
##
## Welch Two Sample t-test
##
## data: total$loinhuan by total$Mohinh
## t = -3.0517, df = 151.29, p-value = 0.002688
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -4.5666867 -0.9773133
## sample estimates:
Đến đây chúng ta có kết luận thứ hai rằng ngân hàng luôn luôn có lợi ích kinh tế lớn hơn khi sử
dụng mô hình cây cho phân loại bất kể là mô hình Logistic có mức độ dự báo toàn cục tốt hơn.
Nghiên cứu nhỏ này một lần nữa khẳng định rằng: một mô hình phân loại có mức độ chính xác toàn
cục cao hơn chưa phải là một mô hình tối ưu đối với ngân hàng về mặt kinh tế. Đây là sự khác biệt
giữa thực tiễn và lý thuyết.
Tất nhiên, việc chúng ta giả định rằng mỗi một hồ sơ chỉ vay 1 USD là một giả thuyết yếu. Ngoài ra,
một hồ sơ tốt được duyệt vay vẫn có thể không trả lại vốn được cho ngân hàng với một xác suất nào
đó. Còn cho vay hồ sơ xấu thì ngân hàng vẫn thu lại vốn với mức xác suất (tuy thấp) nào đó.
Chương 14: Mô hình có biến bị kiểm duyệt: Tobit và hồi quy Poisson
Chương 12 chúng ta đã nghiên cứu các mô hình mà biến phụ thuộc là biến nhị phân (biến định tính hai
cấp độ), hoặc là biến định tính nhiều cấp độ. Chương này chúng ta sẽ nghiên cứu hai nhóm mô hình mà
ở đó biến phụ thuộc bị một “ràng buộc” hay “giới hạn” nào đó về giá trị. Chúng ta xét hai mô hình cụ thể
là mô hình hồi quy Tobit và Poisson.
Lý thuyết và các khía cạnh khác của hai mô hình này các bạn có thể tìm thấy ở bất kì cuốn kinh tế lượng
nhập môn nào, chẳng hạn, cuốn sách giáo trình kinh tế lượng của NEU, tại chương 10.
## (12.955) (21.583)
##
## exper 65.673*** 131.564***
## (9.963) (17.279)
##
## age -30.512*** -54.405***
## (4.364) (7.419)
##
## kidslt6 -442.090*** -894.022***
## (58.847) (111.878)
##
## kidsge6 -32.779 -16.218
## (23.176) (38.641)
##
## exper2 -0.700** -1.864***
## (0.325) (0.538)
##
## logSigma 7.023***
## (0.037)
##
## Constant 1,330.482*** 965.305**
## (270.785) (446.436)
## -------------------------------------------------------
## Observations 753 753
## R2 0.266
## Adjusted R2 0.259
## Log Likelihood -3,819.095
## Akaike Inf. Crit. 7,656.189
## Bayesian Inf. Crit. 7,697.806
## Residual Std. Error 750.179 (df = 745)
## F Statistic 38.495*** (df = 7; 745)
## =======================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Việc diễn giải ý nghĩa của các hệ số hồi quy ở mô hình Tobit là tương tự như đối với các hệ số hồi quy
OLS tuy nhiên đó là tác động tuyến tính (linear effect) lên các biến không bị kiểm duyệt tiềm ẩn
(uncensored latent variable). Các bạn có thể tham khảo thêm McDonald & Moffitt (1980) để biết chi
tiết.
Kết quả thu được ở trên chính là kết quả được trình bày ở trang 601 cuốn sách của Wooldridge (2013)
và cũng là ví dụ được sách giáo trình NEU sử dụng ở trang 425.
Kết quả này có hai điểm đáng chú ý. Thứ nhất, hệ số ước lượng thu được từ hai mô hình là có cùng
dấu. Thứ hai, chúng ta nên thận trọng khi so sánh trực tiếp các hệ số ước lượng thu được từ hai mô
hình với nhau .
Để minh họa, chúng ta xét bộ số liệu CRIME1.DTA với biến phụ thuộc là narr86 (số lần 1 người đàn
ông bị bắt giữ trong năm 1986). Đây là bộ số liệu được sử dụng trong cuốn sách của Wooldridge
(2013) tại trang 607 và được sử dụng lại tại trang 430 của NEU. Miêu tả chi tiết các biến này các bạn
có thể tham khảo trang 430 sách của NEU. Dưới đây là các câu lệnh chạy hồi quy Poisson trong R cũng
như so sánh các kết quả với các ước lượng OLS và hồi quy bán Poisson (Quasi Poisson Regression)
nhằm hiệu chỉnh các sai lệch tiềm năng của phân phối Poisson:
## So sanh ba mo hinh
## =========================================================================
## Dependent variable:
## -----------------------------------------------------
## narr86
## OLS Poisson glm: quasipoisson
## link = log
## (1) (2) (3)
## -------------------------------------------------------------------------
## pcnv -0.132*** -0.402*** -0.402***
## (0.040) (0.085) (0.105)
##
## avgsen -0.011 -0.024 -0.024
Các hệ số ước lượng từ hai mô hình này không thể so sánh trực tiếp với nhau vì chúng có ý nghĩa hoàn
toàn khác biệt. Ví dụ, hệ số thu được từ OLS ứng với biến pcnv (tỉ lệ bị kết án) là -0.132 ngụ ý rằng
nếu biến này tăng lên 0.1 thì số người bị bắt giữ giảm 0.0132. Còn hệ số ước lượng từ mô hình Poisson
hàm ý rằng nếu tăng tỉ lệ bị kết án tăng 0.1 thì số người bị bắt sẽ giảm 0.1*0.402 = 4%. Hệ số của
black ngụ ý rằng số người bị bắt vơi người da màu là cao hơn100[exp(0.661) – 1]=93.7% so với người
da trắng.
Phân tích EFA (Exploratory Factor Analysis) là một trong những kĩ thuật phân tích thống kê nhiều
chiều (Multivariate Analysis) được sử dụng ở một số lĩnh vực, nhất là cho đo lường các thang đo liên
quan đến tâm lý, nhận thức. Nó cũng có thể được sử dụng như là bước phân tích nền cho các phân sâu
hơn như phân tích hồi quy hay sử dụng cho các mô hình SEM (Structural Equation Model).
Trong chương này, tôi sẽ giới thiệu một số phân tích cho EFA cũng như các kiểm định hay sử dụng là
kiểm định KMO, kiểm định Bartlett cũng như kiểm định thang đo Cronbach Alpha.
http://www.mediafire.com/download/wbxxpidlryf62u1/AndyFieldSPSS.rar
Tuy nhiên, để cho gọn và hỗ trợ thuận tiện cho các bạn nghiên cứu, tôi đã mã hóa 23 câu hỏi này bằng
các kí hiệu từ Q01 đến Q23 đồng thời đổi định dạng cho dữ liệu với tên gọi raq.dat.
Để thực hiện phân tích EFA và một số phân kĩ thuật phân tích đa biến khác chúng ta cần cài đặt một
số gói sau:
install.packages("GPArotation")
install.packages("corpcor")
install.packages("corrplot")
install.packages("grid")
Riêng gói jbryer và likert cài đặt có chút phức tạp hơn vì phải cài đặt từ Github:
library(devtools)
install_github("likert", "jbryer")
Theo Field (2013), phân tích khám phá EFA được sử dụng khi chúng ta muốn đo lường và khám phá
cấu trúc của những biến số hoặc khái niệm mà không thể đo lường trực tiếp được (các biến, khái niệm
như thế gọi là latent variables – các biến ẩn và còn có tên gọi khác là nhân tố - factor) mà chỉ có thể
đo lường gián tiếp qua các biến trung gian, chẳng hạn, một loạt các câu hỏi theo thang đo Likert 5. Để
khám phá cấu trúc và đo lường nhân tố chúng ta sử dụng một kĩ thuật phân tích đa biến gọi là phân
tích thành phần chính PCA (Principal Component Analysis) – một kĩ thuật phân tích nhằm xác định
những nhóm biến trung gian tập trung theo các cụm như thế nào dựa vào một tiêu chí thống kê gọi là
hệ số tải (factor loading). Bạn đọc quan tâm có thể xem chi tiết chương 17 cuốn sách của A. Field đã
nêu tên ở trên.
setwd("D:/KTLR")
love <- read.delim("raq.dat", header = TRUE)
library(psych); library(GPArotation); library(corpcor); library(corrplot)
library(factoextra); library(likert); library(tidyverse); library(grid)
you <- cor(love)
round(you, 3)
## Q01 Q02 Q03 Q04 Q05 Q06 Q07 Q08 Q09 Q10
## Q01 1.000 -0.099 -0.337 0.436 0.402 0.217 0.305 0.331 -0.092 0.214
## Q02 -0.099 1.000 0.318 -0.112 -0.119 -0.074 -0.159 -0.050 0.315 -0.084
## Q03 -0.337 0.318 1.000 -0.380 -0.310 -0.227 -0.382 -0.259 0.300 -0.193
Ma trận hệ số tương quan trong tình huống của phân tích EFA – CFA được gọi là R-matrix. Những hệ
số tương quan không thuộc đường chéo của ma trận (off-diagonal elements) chính là hệ số tương
quan của các biến trung gian. Ví dụ, giữa biến Q01 và Q04 (theo thang đo Likert 5) là 0.402. Một bộ
dữ liệu được cho là có thể thực hiện phân tích EFA – CFA khi mà các hệ số tương quan này đủ lớn về
giá trị tuyệt đối và được đánh giá thông qua một trong hai thống kê là kiểm định KMO và Bartlett mà
chúng ta sẽ nghiên cứu ở mục sau.
Chúng ta cũng có thể trình bày tương quan giữa các biến số theo một ngôn ngữ khác - ngôn ngữ của
hình ảnh và màu sắc:
Các ô vuông ở đường chéo luôn là màu xanh đậm (tương quan dương 1). Màu xanh càng nhạt thì
tương quan dương càng yếu. Tương tự, màu đỏ sậm là tương quan âm 1. Màu đỏ này càng nhạt thì
tương quan âm này càng yếu. Tất nhiên thông tin về tương quan giữa các câu hỏi chúng ta có thể có
được theo một cách thức khác như đã làm ở mục 8.3 của chương 8.
Do ma trận hệ số tương quan là đối xứng nên chúng ta có thể hiệu chỉnh bằng lệnh sau:
Hoặc có thể “tập trung” những biến có tương qua dương hoặc âm lại với nhau:
Ở đây chúng ta có thể thấy rằng, chẳng hạn, câu Q23 thì tỉ lệ chọn 1 (tức là rất không đồng ý là 12.45%)
và tỉ lệ chọn 2 là cao nhất với 42.43 %.Q23 có trung bình (với thang đo từ 1 đến 5) là 2.57 và độ lệch
chuẩn là 1.04.
Chúng ta cũng có thể biểu diễn các thông tin ở trên dưới dạng khác:
plot(love, centered = FALSE) + ggtitle(title)
Theo Kaiser (1974), để phân tích EFA chúng ta cần giá trị KMO này tối thiểu là 0.5. Với dữ liệu của
chúng ta, KMO Test là 0.93 cho thấy có thể sử dụng phân tích EFA cho bộ dữ liệu. Hutcheson &
Sofroniou (1999) thậm chí còn đưa ra các ngưỡng cụ thể hơn như sau: nếu thống kê KMO nằm từ 0.5
đến 0.7 thì là chấp nhận được (mediocre), từ 0.7 đến 0.8 là tốt, từ 0.8 đến 0.9 là rất tốt, còn trên 0.9
là siêu tốt (superb).
cortest.bartlett(love)
## $chisq
## [1] 19334.49
##
## $p.value
## [1] 0
##
## $df
## [1] 253
Kiểm định này có gía trị 19334.49 với 253 bậc tự do và tương ứng với p-value = 0 < 5% nên chúng ta
có kết luận rằng tương quan giữa các items là đủ lớn để sử dụng phân tích nhân tố.
Chúng ta thấy rằng sẽ có 4 nhân tố được rút ra theo tiêu chuẩn Kaiser. Nhân tố thứ 4(Dim.4) có
Eigenvalues là 1.23 tương ứng với nhân tố này giải thích cho 1.23/23 = 5.3 % tổng phương sai (total
variance). Cả 4 nhân tố này giải thích được 50.32 % tổng phương sai (chính là bằng (7.29 + 1.74 +
1.32 + 1.23)/23 ). Chúng ta có thể biểu diễn các kết quả này bằng hình ảnh như sau:
# Phương sai giải thích tương ứng cho 10 nhân tố đầu tiên:
fviz_screeplot(pca1, addlabels = TRUE, n = 10)
Chúng ta cũng có thể biểu diễn Eigenvalues cho các nhân tố bằng với độ chính xác 1 chữ số sau dấu
phẩy (không hiển thị hình ảnh):
15.5 Các biến cấu thành nhân tố, đặt tên cho nhân tố và kiểm định Cronbach Alpha
Các phân tích trên chỉ ra rằng có 4 nhân tố chính được rút ra. Để biết các nhân tố này được cấu thành
từ các biến nào (tức là khám phá cấu trúc của nhân tố) chúng ta có thể sử dụng phép xoay Varimax.
Câu lệnh dưới đây sẽ loại bỏ (không hiển thị) bất kì biến nào có hệ sổ tải (Factor Loadings) bé hơn
0.3:
Chúng ta thấy với nhân tố thứ nhất (PC1), các biến cấu thành nhân tố này là từ Q06 đến Q15. Đối chiếu
với nội dung các câu hỏi tương ứng với Q06 đến Q15 chúng ta có thể thấy rằng tất cả chúng thuộc về
một nhóm nhân tố mà chúng ta có thể gọi là “kiến thức về toán học”, hay “nỗi sợ toán học”. Chúng ta
đặt tên cho các nhân tố còn lại cũng căn cứ vào nội dung của các câu hỏi (xem bảng 17.1 Sách của
Field). Chú ý rằng cách đặt tên này không giống nhau giữa các cá nhân tuy nhiên việc đặt tên cho từng
nhân tố nên cố gắng phản ánh bản chất của nhân tố đó căn cứ vào các câu hỏi (các biến) cấu thành.
Việc chọn hệ số tải (trong tình huống của chúng ta là 0.3) có liên quan đến kích cỡ mẫu của phân tích
(Janssens et al., 2008) và được cho ở bảng dưới đây:
Nếu chúng ta lựa chọn một tiêu chuẩn chặt hơn, chúng ta có thể chọn ngưỡng hệ số tải là 0.4. Lúc này
kết quả là:
Chúng ta lưu tâm đến biến số Q12. Nó vừa thuộc nhân tố 3 lẫn nhân tố 1. Tuy nhiên hệ số tải của nó
với nhân tố 1 là lớn hơn (0.52 so với 0.47) nên ta có thể nói nó tương quan lớn hơn với nhân tố 1 .
Nói cách khác, căn cứ vào tiêu chí hệ số tải lớn hơn thì Q12 thuộc nhân tố 1 (PC1).
Dù chọn hệ số tải là 0.3 hay 0.4 thì các biến số cấu thành các nhân tố chính (từ PC1 đến PC4) vẫn
không thay đổi. Cụ thể, nhân tố “kiến thức về toán” được cấu thành từ các biến Q06, Q18, Q13, Q07,
Q14, Q10, và Q15. Chúng ta có thể thực hiện kiểm định Cronbach Alpha cho thang đo (hay nhân tố)
này bằng câu lệnh sau:
psych::alpha(love[, c(06, 18, 13, 07, 14, 10, 15)])
## Reliability analysis
## Call: psych::alpha(x = love[, c(6, 18, 13, 7, 14, 10, 15)])
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.82 0.82 0.81 0.4 4.6 0.0094 3.4 0.71
##
## lower alpha upper 95% confidence boundaries
## 0.8 0.82 0.84
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## Q06 0.79 0.79 0.77 0.38 3.7 0.011
## Q18 0.79 0.78 0.76 0.38 3.6 0.011
## Q13 0.79 0.79 0.77 0.39 3.8 0.011
Câu lệnh trên chúng ta phải gõ cả psych:: là bởi vì gói ggplot 2 cũng có “lệnh” alpha. Dao vậy chúng ta
cần gõ psych:: để chỉ thị cho R hiểu là dùng lệnh alpha của gói psych chứ không phải của gói ggplot2.
Chúng ta đã thực hiện sử dụng theo cách thức tương tự tại mục 2.6. Nếu bạn không làm thế, R sẽ báo
lỗi.
Một thang đo là hợp lí (Reability) nếu gí trị Cronbach Alpha này lớn hơn 0.7. Kêt quả của chúng ta là
0.82 > 0.7 nên thang đo “kiến thức về toán” cấu thành từ 7 biến số (thường gọi là items) trên là hợp
lí.
Thực hiện kiểm định thanh đo một cách tương tự cho 3 nhân tố (thang đo) còn lại một cách tương tự.
Cũng có thể kết hợp phân tích EFA với phân tích hồi quy hoặc mô hình SEM (Structural equation
modeling).
15.6 Mini Project: Hình ảnh hóa dữ liệu sử dụng thang đo Likert
Một khía cạnh quan trọng ngoài thực hiện các phân tích thống kê như chúng ta vừa thực hiện thì
chúng ta còn có thể phải thực hiện hình ảnh hóa dữ liệu với thang đo Likert – một việc làm khá phổ
biến ở nhiều báo cáo của các tổ chức lớn, các công ti nghiên cứu thị trường hay báo chí. Trong mục
này chúng ta sẽ thực hành một dự án nhỏ với bộ số liệu pisaitems tích hợp cùng gói likert. Bộ số
liệu này được thu thập bởi Tổ Chức Hợp Tác Kinh Tế và Phát Triển OECD (Organization for Economic
Co-operation and Development) . Xem thêm về số liệu tại http://www.pisa.oecd.org/. Các quốc gia
có trong lần khảo sát này là Canada, Hoa Kì và Mexico với 80 biến số (thường gọi là 80 items):
# Xóa tất cả các object:
rm(list = ls())
# Load gói likert:
library(likert)
# Kiểm tra dữ liệu thiếu
data(pisaitems)
sapply(pisaitems, function(x) sum(is.na(x)))
str(pisaitems)
Để minh họa chúng ta chỉ trích ra 11 câu hỏi liên quan đến thái độ của người được phỏng vấn đối
với việc đọc. Chúng là các câu hỏi có cụm kí tự ST24Q:
library(tidyverse)
# Trích ra bộ dữ liệu gồm các biến có kí tự ST24Q - thái độ với việc đọc:
reading <- select(pisaitems, contains("ST24Q"))
head(reading)
names(reading)
Hình ảnh hóa cho số lượng những người được phỏng vấn đến từ ba nước trên:
Để dễ hiểu cho bạn đọc chúng ta nên đổi tên cho các items:
# Đổi tên cho các biến số:
reading <- dplyr::rename(reading,
"I read only if I have to." = ST24Q01,
"Reading is one of my favorite hobbies." = ST24Q02,
"I like talking about books with other people." = ST
24Q03,
"I find it hard to finish books." = ST24Q04,
"I feel happy if I receive a book as a present." = S
T24Q05,
"For me, reading is a waste of time." = ST24Q06,
"I enjoy going to a bookstore or a library." = ST24Q
07,
"I read only to get information that I need." = ST24
Q08,
"I cannot sit still and read for more than a few min
utes." = ST24Q09,
"I like to express my opinions about books I have re
ad." = ST24Q10,
"I like to exchange books with my friends." = ST24Q1
1)
Với mục đích minh họa (và cũng để tiết kiệm giấy in) chúng ta chỉ xét 4 câu hỏi (items) đầu tiên của
bộ dữ liệu con này trước khi hình ảnh hóa dữ liệu:
# Chỉ lấy các câu hỏi (items) từ 1 đến 4:
f1_4 <- reading[, c(1:4)]
# Likert hóa các items này:
f1_4likert <- likert(f1_4)
# Tóm tắt:
summary(f1_4likert)
Hoặc chúng ta có thể hình ảnh hóa theo một số cách khác:
# Bar plot theo một cách khác:
plot(f1_4likert, centered = FALSE, wrap = 30)
##----------------------------------------------
## Đánh giá thái độ đối với reading của các
## quan sát đến từ ba quốc gia tham gia khảo sát
##----------------------------------------------
g <- likert(f1_4, grouping = pisaitems$CNT)
print(g)
## Group Item
## 1 Canada I read only if I have to.
## 2 Canada Reading is one of my favorite hobbies.
## 3 Canada I like talking about books with other people.
## 4 Canada I find it hard to finish books.
## 5 Mexico I read only if I have to.
## 6 Mexico Reading is one of my favorite hobbies.
## 7 Mexico I like talking about books with other people.
## 8 Mexico I find it hard to finish books.
## 9 United States I read only if I have to.
## 10 United States Reading is one of my favorite hobbies.
## 11 United States I like talking about books with other people.
## 12 United States I find it hard to finish books.
## Strongly disagree Disagree Agree Strongly agree
## 1 25.69810 35.12856 24.88383 14.289507
## 2 26.77758 35.18871 24.63608 13.397637
## 3 25.22917 31.68150 33.47062 9.618706
## 4 31.33106 40.44088 19.69811 8.529946
## 5 21.87500 36.76845 33.45526 7.901293
## 6 15.26451 36.42523 37.79077 10.519491
## 7 18.44410 34.78607 37.89150 8.878331
## 8 21.09309 39.92260 31.07241 7.911896
## 9 17.16996 33.00426 33.97213 15.853659
## 10 29.08282 40.51858 21.03328 9.365325
## 11 24.31646 35.13671 32.79038 7.756448
## 12 25.32455 43.61558 22.96067 8.099206
Khi bạn thực hiện hình ảnh hóa dữ liệu cho bộ số liệu của mình chú ý rằng bộ dữ liệu của bạn phải có
cấu trúc tương tự như pisaitems. Nếu không giống thì việc đầu tiên bạn cần thực hiện là cần chuyển
chúng về cấu trúc dữ liệu như pisaitems.
15.7 Về xu hướng sử dụng phân tích EFA trong nghiên cứu hiện nay
Có nhiều công cụ phân tích và cách tiếp cận có thể sử dụng cho nghiên cứu và sử dụng EFA chỉ là một
trong số đó. Nhưng có vẻ như sử dụng EFA với thang đo Likert 5 lại được ưu tiên một cách đặc biệt ở
Việt Nam. Điều này có thể thấy qua hầu hết các sách về hướng dẫn nghiên cứu khoa học đều dành một
khối lượng đáng kể để nói về phương pháp này, cá biệt có cuốn dành xấp xỉ 30% số trang sách cho
phương pháp phân tích EFA (mà trong đó 80% số trang giấy chỉ để in số liệu). Sự ưu ái vô lý dành cho
kĩ thuật phân tích đa biến này có thể dẫn đến ngộ nhận của nhiều người rằng EFA là công cụ vạn năng,
hoặc chí ít là công cụ đầy sức mạnh cho các nghiên cứu. Hầu hế các sách về hướng dẫn nghiên cứu
khoa học bằng tiếng Anh cho kinh tế và kinh doanh, không nhiều sách viết về EFA, nhất là sử kết hợp
việc sử dụng phân tích hồi quy OLS cho các nhân tố rút ra sau khi thực hiện EFA. Các sách về nghiên
cứu Marketing, nếu có, thì cũng chỉ dành một chương cho CFA mà thôi.
Nguyên nhân có lẽ là thang đo Likert vốn là biến thứ bậc (Ordinal Variable) và có nên coi nó là biến
Interval (hay thang đo khoảng) hay không và trong những trường hợp cụ thể nào vẫn là một vấn đề
chưa nhận được sự đồng thuận vì rằng với biến thứ bậc chúng ta chỉ có quyền so sánh, ví dụ, mức độ
nghiêm trọng của người được phỏng vấn đối với một vấn đề nào đó chứ không thể thực hiện các phép
toán cho loại biến này (Keller, 2013). Còn việc thực hiện phân tích hồi quy OLS cho các nhân tố rút
ra sau khi thực hiện EFA còn gây tranh cãi hơn nữa, ít nhất là với các nghiên cứu giải thích vì rằng
các nhân tố rút ra đó là biến không có đơn vị và cũng chẳng phải là loại biến thứ bậc hay Interval.
Điều này được giải thích chi tiết hơn dưới đây.
Để đánh giá tác động của giá lên lượng tiêu thụ nước ngọt có ga chúng ta có thể thực hiện hồi quy OLS
với giá là biến độc lập. Nếu hệ số hồi quy của giá là 0.002 thì ta có thể diễn giải (hay giải thích) rằng
nếu giá tăng 1 (đơn vị là ngàn VND) thì tiêu thụ về sản phẩm này giảm 0.002 (đơn vị là ngàn chai).
Cách giải thích này đã được thừa nhận rộng rãi và được chấp nhận.
Nhưng cách giải thích này áp dụng cho hồi quy OLS với các nhân tố rút ra là vô nghĩa. Thực vậy, trong
một nghiên cứu có tên “Các nhân tố ảnh hưởng đến mức độ trung thành của nhân viên tại ngân hàng
X” với 35 câu hỏi theo thang đo Likert 5. Sau khi thực hiện EFA, 35 câu hỏi này được rút về, chẳng
hạn, chỉ còn 2 nhân tố với tên gọi là “Thăng Tiến” và “Đồng Nghiệp”. Kế tiếp tác giả thực hiện hồi quy
OLS và cho ra kết quả là:
Kết quả này được diễn giải là khi Thăng Tiến tăng 1 thì Trung Thành tăng 1.02. Cách diễn giải như
vậy (do tác giả sử dụng OLS với các nhân tố rút ra) rõ ràng có một điểm yếu: các biến số độc lập Thăng
Tiến, Đồng Nghiệp và cả biến phụ thuộc Trung Thành là những biến không có đơn vị.
Thăng Tiến tăng 1 là 1 gì? Phải chăng là 1 Dollar hay 1 lời hứa cất nhắc lên vị trí cao hơn?
Để chốt lại xu hướng sử dụng EFA trong nghiên cứu khoa học ở Việt Nam, tôi nêu một số thực tế sau
(để đảm bảo khách quan, tôi không dịch chúng ra tiếng Việt nên bạn có thể copy cả cụm từ / câu để
tìm nguồn với sự trợ giúp của Google):
1. 36 was the number of articles ISI Web of Science shows with the topic “Factor Analsysis” for the
week ending October 11, 2003.
2. FA is not worth the time necessary to understand it and carry it out (Hills, 1977).
3. At the present time, factor analysis still maintains the flavor of an art, and no single strategy
should yet be "chiseled into stone" (Johnson & Wichern, 2002,).
4. Factor analysis should not be used in most practical situations (Chatfield & Collins, 1980).
Nghĩa là từ những năm của thập niên 70, giới nghiên cứu và phân tích số liệu đã không tán thành việc
lạm dụng và sử dụng phân tích nhân tố. Điều này có thể thấy rằng qua một số thực tế là cho đến tháng
10 năm 2003, trong số hàng chục ngàn nghiên cứu đăng trên ISI thì chỉ có 36 bài có cụm từ phân tích
nhân tố. Thậm chí Hills còn cực đoan hơn khi tuyên bố rằng “FA (kí hiệu của phân tích nhân tố) là
không đáng để nghiên cứu và thực hiện (các nghiên cứu sử dụng phân tích nhân tố)”. Một trong những
nguyên nhân là phân tích nhân tố là rất không ổn định và nó thiên về một nghệ thuật hơn là khoa học
như cách nói của Johnson & Wichern. Chi tiết hơn về việc chỉ trích sử dụng kĩ thuât phân tích này các
bạn có thể đọc chi tiết ở trang 159 cuốn An Introduction to Applied Multivariate Analysis with R
xuất bản bởi Springer của Brian Everitt và Torsten Hothorn.
Quan điểm của Chatfield & Collins có lẽ là đỡ khắt khe hơn (so với quan điểm có phần cực đoan của
Hills) khi hai ông cho rằng “Phân tích nhân tố không nên được sử dụng trong hầu hết các tình huống
(nghiên cứu)”.
Tại Việt Nam hiện cũng có một số tiếng nói chỉ trích phong trào lạm dụng sử dụng EFA trong nghiên
cứu. Các bạn có thể xem một loạt bài (có dẫn chứng và phân tích rõ ràng) tại:
http://vneconomist.net/newsdetail.php?f=36&t=988&sid=d3f701e15821ed7a6ee892bcca5b7b41