จากข้อมูลสู่เมทริกซ์
ในบทก่อนหน้า เราได้เรียนรู้การใช้ list และ loop ในการจัดการข้อมูล
อย่างไรก็ตาม ในงานเศรษฐศาสตร์จริง โดยเฉพาะ econometrics เรามักต้องทำงานกับข้อมูลจำนวนมาก และแบบจำลองที่ซับซ้อน
การใช้ loop อาจช้าและไม่สะดวก
ดังนั้น เราจึงใช้ “เมทริกซ์” และ “การคำนวณเชิงเวกเตอร์” เพื่อให้การคำนวณมีประสิทธิภาพมากขึ้น ในวิชาเศรษฐมิติ (Econometrics) และการสร้างแบบจำลองทางเศรษฐศาสตร์ ข้อมูลมักถูกจัดเก็บและประมวลผลในรูปของ เมทริกซ์ และ เวกเตอร์ เช่น สมการพื้นฐานอย่าง \(\mathbf{y} = \mathbf{X}\boldsymbol{\beta} + \boldsymbol{\epsilon}\) การพยายามคำนวณหาค่า \(\hat{\beta}\) หรือจัดการกับข้อมูลขนาดใหญ่ด้วยการเขียน for loop แบบดั้งเดิม ไม่เพียงแต่จะใช้เวลาประมวลผลมหาศาล แต่ยังยากต่อการเขียนโปรแกรมและการตรวจสอบความถูกต้อง
NumPy (Numerical Python) คือรากฐานสำคัญที่เปลี่ยนให้ Python กลายเป็นเครื่องมืออันทรงพลังสำหรับนักเศรษฐศาสตร์สมัยใหม่ ด้วยแนวคิด Vectorization ที่ช่วยให้เราสามารถส่งคำสั่งทางคณิตศาสตร์ไปประมวลผลกับข้อมูล “ทั้งชุด” ได้พร้อมกันในระดับหน่วยความจำ
ในบทนี้ เราจะวางรากฐานตั้งแต่การสร้างเมทริกซ์พิเศษที่จำเป็นในงานเศรษฐศาสตร์ ไปจนถึงเทคนิค Broadcasting ที่ช่วยลดความซับซ้อนของโค้ด และปิดท้ายด้วยการนำความรู้ทั้งหมดมาสร้างแบบจำลองการประมาณค่าด้วยวิธี Ordinary Least Squares (OLS) จากศูนย์ เพื่อให้เห็นว่าพลังของการคำนวณเชิงเวกเตอร์สามารถเปลี่ยนสมการที่ซับซ้อนให้กลายเป็นโค้ดที่สั้น กระชับ และเปี่ยมประสิทธิภาพได้อย่างไร
ก่อนจะเริ่มต้นใช้งาน เราจำเป็นต้องติดตั้งไลบรารี NumPy ในระบบก่อน ถ้าผู้อ่านหรือนักศึกษาใช้งานผ่าน Anaconda หรือ Miniconda สามารถเปิด Terminal (หรือ Anaconda Prompt) แล้วใช้คำสั่งดังนี้:
สำหรับผู้ใช้ Conda (แนะนำ):
สำหรับผู้ใช้ Python ทั่วไป (pip):
ทำไมต้อง NumPy? และ Vectorization คืออะไร?
ในบทก่อนหน้า เราได้เรียนรู้การใช้ for loop เพื่อทำงานกับข้อมูลหลายค่า อย่างไรก็ตาม ในงานเศรษฐศาสตร์จริง เรามักต้องจัดการกับข้อมูลขนาดใหญ่ เช่น:
คำถามสำคัญคือ:
❗ เราจะยังใช้ for loop แบบเดิมได้หรือไม่?
แนวคิดของ Vectorization
Vectorization คือความสามารถของ NumPy ในการประมวลผลข้อมูล “ทั้งชุด” พร้อมกัน โดยไม่ต้องวนซ้ำทีละค่าใน Python
ตัวอย่าง: การคำนวณภาษีสินค้า สมมติว่าเรามีราคาสินค้า 1 ล้านรายการ และต้องการบวกภาษี 7%
คลิกเพื่อดูโค้ดไพธอน
import numpy as np
import time
n_items = 1000000
prices_list = list (range (1 , n_items + 1 ))
start_time = time.time()
taxed_list = []
for p in prices_list:
taxed_list.append(p * 1.07 )
end_time = time.time()
list_duration = end_time - start_time
print (f"แบบ Python List (For Loop) ใช้เวลา: { list_duration:.5f} วินาที" )
แบบ Python List (For Loop) ใช้เวลา: 0.03454 วินาที
คลิกเพื่อดูโค้ดไพธอน
prices_np = np.array(prices_list)
start_time = time.time()
taxed_np = prices_np * 1.07
end_time = time.time()
numpy_duration = end_time - start_time
print (f"แบบ NumPy (Vectorization) ใช้เวลา: { numpy_duration:.5f} วินาที" )
แบบ NumPy (Vectorization) ใช้เวลา: 0.00105 วินาที
เปรียบเทียบผลลัพธ์
คลิกเพื่อดูโค้ดไพธอน
speed_gain = list_duration / numpy_duration
print (f"---" )
print (f"สรุป: NumPy เร็วกว่า Python List ประมาณ { speed_gain:.0f} เท่า!" )
---
สรุป: NumPy เร็วกว่า Python List ประมาณ 33 เท่า!
ความเร็วที่เพิ่มขึ้นไม่ได้เป็นเพียง “เรื่องเทคนิค” แต่สะท้อนความแตกต่างของวิธีคิด:
ในงานเศรษฐศาสตร์ เราแทบไม่เคยสนใจข้อมูลเพียงค่าเดียว แต่สนใจ “โครงสร้างของข้อมูลทั้งหมด” เช่น:
ดังนั้น Vectorization จึงเป็นวิธีคิดที่สอดคล้องกับธรรมชาติของข้อมูลทางเศรษฐศาสตร์
การสร้างและจัดการ NumPy Array
เมื่อเข้าใจแนวคิดของ Vectorization แล้ว ขั้นต่อไปคือการจัดเก็บข้อมูลในรูปแบบที่เหมาะสม
คลิกเพื่อดูโค้ดไพธอน
import numpy as np
# สร้างข้อมูลรายได้ของประชากร 5 คน (หน่วย: หมื่นบาท)
income = np.array([3.5 , 4.2 , 2.8 , 5.0 , 3.2 ])
ตัวอย่าง: การคำนวณแบบ Vectorized สมมติว่าเราต้องการเพิ่มโบนัส 0.5 ให้ทุกคน:
คลิกเพื่อดูโค้ดไพธอน
new_income = income + 0.5
print (f"รายได้ใหม่: { new_income} " )
รายได้ใหม่: [4. 4.7 3.3 5.5 3.7]
Python จะทำการคำนวณกับทุกค่าพร้อมกัน โดยไม่ต้องใช้ loop
การคูณเมทริกซ์: จากการคำนวณสู่แบบจำลอง
ในส่วนก่อนหน้า เราได้เห็นว่า NumPy สามารถประมวลผลข้อมูลทั้งชุดได้พร้อมกัน (vectorization) ซึ่งช่วยให้การคำนวณมีประสิทธิภาพมากขึ้น
อย่างไรก็ตาม ในงานเศรษฐศาสตร์จริง โดยเฉพาะ econometrics เราไม่ได้เพียงแค่คูณค่าทั้งหมดด้วยตัวเลขเดียว แต่ต้องทำงานกับ “ความสัมพันธ์ระหว่างตัวแปรหลายตัว” เช่น:
รายได้ขึ้นอยู่กับการศึกษาและประสบการณ์
การบริโภคขึ้นอยู่กับรายได้
ผลตอบแทนขึ้นอยู่กับปัจจัยหลายด้าน
คำถามคือ:
❗ เราจะเขียนความสัมพันธ์เหล่านี้ใน Python ได้อย่างไร?
สมมติว่าเรามีข้อมูลของ 3 คน:
คลิกเพื่อดูโค้ดไพธอน
import numpy as np
X = np.array([
[1 , 12 ],
[1 , 16 ],
[1 , 14 ]
])
และสมมติว่าเรามีพารามิเตอร์ของแบบจำลอง:
เราสามารถคำนวณค่าที่คาดการณ์ได้โดยใช้:
การคูณเมทริกซ์นี้หมายถึง:
\[y = X\beta\]
หรือในเชิงเศรษฐศาสตร์:
สำหรับแต่ละคน:
คนที่ 1: 5 + 2×12 = 29
คนที่ 2: 5 + 2×16 = 37
คนที่ 3: 5 + 2×14 = 33
Python คำนวณทั้งหมดนี้ในคำสั่งเดียว
ลองเปรียบเทียบ:
วิธีแบบ Loop
คลิกเพื่อดูโค้ดไพธอน
result = []
for row in X:
value = row[0 ]* beta[0 ] + row[1 ]* beta[1 ]
result.append(value)
วิธีแบบ Matrix
โค้ดสั้นกว่า ชัดเจนกว่า และตรงกับสมการทางเศรษฐศาสตร์
Matrix multiplication คือวิธีที่ทำให้ “สมการเศรษฐศาสตร์” กลายเป็น “สิ่งที่คำนวณได้โดยตรงใน Python”
ใน econometrics แบบจำลองพื้นฐานเขียนได้ว่า:
\[y = X\beta + \varepsilon\]
ซึ่งหมายความว่า:
ดังนั้น การคูณเมทริกซ์ที่เราเห็นในส่วนนี้คือ “หัวใจ” ของ regression analysis
เมทริกซ์ (Matrices) ในทางเศรษฐศาสตร์
ในการประมาณค่าด้วยวิธี OLS (Ordinary Least Squares) เราจำเป็นต้องจัดการกับเมทริกซ์ของตัวแปรอิสระ (\(\mathbf{X}\) )
คลิกเพื่อดูโค้ดไพธอน
# สมมติเรามีข้อมูล (Constant, ปีการศึกษา, ประสบการณ์) ของพนักงาน 3 คน
X = np.array([
[1 , 16 , 2 ],
[1 , 12 , 5 ],
[1 , 18 , 0 ]
])
# การตรวจสอบขนาดของเมทริกซ์ (Rows, Columns)
print (f"ขนาดของเมทริกซ์ X: { X. shape} " )
ขนาดของเมทริกซ์ X: (3, 3)
Matrix Algebra: การคูณเมทริกซ์ และการหา Inverse
หัวใจของ Econometrics คือการแก้สมการเพื่อหาพารามิเตอร์ \(\hat{\beta}\) ซึ่งมีสูตรมาตรฐานคือ: \[\hat{\beta} = (\mathbf{X}'\mathbf{X})^{-1} \mathbf{X}'\mathbf{y}\]
ลองมาดูการเขียนโค้ดในรูปแบบ NumPy ที่สั้นและทรงพลังกันครับ:
คลิกเพื่อดูโค้ดไพธอน
# 1. กำหนดข้อมูลจำลอง y (รายได้จริง) และ X (ตัวแปรต้น)
y = np.array([45000 , 38000 , 52000 ])
X = np.array([
[1 , 16 ], # คนที่ 1: ค่าคงที่, เรียน 16 ปี
[1 , 12 ], # คนที่ 2: ค่าคงที่, เรียน 12 ปี
[1 , 18 ] # คนที่ 3: ค่าคงที่, เรียน 18 ปี
])
# 2. คำนวณ X'X (X Transpose คูณ X)
XTX = X.T @ X
# 3. คำนวณ Inverse ของ XTX
XTX_inv = np.linalg.inv(XTX)
# 4. คำนวณ X'y
XTy = X.T @ y
# 5. หาค่า Beta (ผลตอบแทนจากการศึกษา)
beta_hat = XTX_inv @ XTy
print (f"ค่าสัมประสิทธิ์ (Intercept, Education): { beta_hat} " )
ค่าสัมประสิทธิ์ (Intercept, Education): [10500. 2250.]
หมายเหตุ: เครื่องหมาย @ ใน Python ใช้สำหรับการคูณเมทริกซ์ (Matrix Multiplication)
การสร้างเมทริกซ์พิเศษสำหรับงานเศรษฐศาสตร์
ในการทำ Econometrics หรือการคำนวณดุลยภาพ เรามักต้องใช้เมทริกซ์ที่มีรูปแบบเฉพาะ NumPy มีฟังก์ชันที่ช่วยสร้างสิ่งเหล่านี้ได้ทันที:
Identity Matrix (\(I\) ): ใช้มากใน Input-Output Analysis หรือการหา Inverse
คลิกเพื่อดูโค้ดไพธอน
I = np.eye(3 ) # สร้างเมทริกซ์เอกลักษณ์ขนาด 3x3
I
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Diagonal Matrix: สำหรับเมทริกซ์ความแปรปรวน (Variance-Covariance Matrix)
คลิกเพื่อดูโค้ดไพธอน
v = np.array([1 , 2 , 3 ])
V = np.diag(v) # นำค่าใน v ไปวางในแนวทแยงมุม
V
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
Matrices of Ones/Zeros: สำหรับสร้าง Constant term หรือพื้นที่ว่างเพื่อรอรับค่าคำนวณ
คลิกเพื่อดูโค้ดไพธอน
ones = np.ones((100 , 1 )) # สำหรับเพิ่ม Intercept ใน X matrix
# ไม่แสดงผลลัพธ์เพราะมันเปลืองหน้ากระดาษ
พลังของ Broadcasting: การคำนวณข้ามมิติ
นักเศรษฐศาสตร์มักต้องทำ Mean Centering (การลบค่าเฉลี่ยออกจากข้อมูล) เพื่อเตรียมข้อมูลก่อนวิเคราะห์ NumPy ช่วยให้เราลบเวกเตอร์ค่าเฉลี่ยออกจากเมทริกซ์ข้อมูลขนาดใหญ่ได้ในบรรทัดเดียวโดยไม่ต้องเขียน Loop
คลิกเพื่อดูโค้ดไพธอน
# ข้อมูลรายได้และรายจ่าย 5 ครัวเรือน (5x2)
data = np.array([[50 , 30 ], [60 , 45 ], [45 , 25 ], [70 , 50 ], [55 , 35 ]])
mean = data.mean(axis= 0 ) # หาค่าเฉลี่ยของแต่ละคอลัมน์
# Broadcasting: นำค่าเฉลี่ย (1x2) ไปลบออกจากข้อมูล (5x2) ทุกแถวอัตโนมัติ
centered_data = data - mean
print (centered_data)
[[ -6. -7.]
[ 4. 8.]
[-11. -12.]
[ 14. 13.]
[ -1. -2.]]
การจัดการข้อมูลสูญหาย (NaN)
ในข้อมูลเศรษฐกิจจริง มักมีค่าว่างหรือข้อมูลที่ไม่สมบูรณ์ ซึ่งใน NumPy จะแทนด้วย np.nan หากเราใช้ฟังก์ชันปกติคำนวณ ผลลัพธ์จะเป็น nan ทั้งหมด เราจึงต้องใช้ฟังก์ชัน “nan-safe”:
คลิกเพื่อดูโค้ดไพธอน
gdp_growth = np.array([2.5 , np.nan, 3.1 , 1.8 ])
# แบบปกติ (จะได้ nan)
print (np.mean(gdp_growth))
คลิกเพื่อดูโค้ดไพธอน
# แบบ nan-safe (ข้ามค่าว่างให้โดยอัตโนมัติ)
print (np.nanmean(gdp_growth))
การสร้างแบบจำลอง OLS (Ordinary Least Squares)
ในส่วนก่อนหน้า เราได้เรียนรู้การคูณเมทริกซ์ในรูปแบบ:
\[
y = X\beta
\]
ซึ่งเป็นรูปแบบพื้นฐานของแบบจำลองเชิงเส้น อย่างไรก็ตาม ในโลกจริง เราไม่รู้ค่า \(\beta\) ล่วงหน้า
ดังนั้นคำถามสำคัญคือ:
❗ เราจะ “ประมาณค่า” พารามิเตอร์เหล่านี้จากข้อมูลได้อย่างไร?
คำตอบคือ Ordinary Least Squares (OLS) ซึ่งเป็นวิธีมาตรฐานในตัวแบบจำลองทางเศรษฐมิติ
เราต้องการประมาณสมการ:
\[
\ln(\text{wage}) = \beta_0 + \beta_1 \text{educ} + \beta_2 \text{exper} + \epsilon
\]
โดย:
\(\text{educ}\) = ปีการศึกษา
\(\text{exper}\) = ประสบการณ์ทำงาน
\(\epsilon\) = ปัจจัยอื่นที่ไม่ได้อยู่ในแบบจำลอง
การเตรียมข้อมูลในรูปแบบเมทริกซ์ เพื่อใช้สูตร OLS เราต้องจัดข้อมูลให้อยู่ในรูป:
\[
\mathbf{y} = \mathbf{X}\boldsymbol{\beta} + \boldsymbol{\epsilon}
\]
สิ่งสำคัญคือ: > เมทริกซ์ \(X\) ต้องมีคอลัมน์ของ 1 เพื่อใช้แทนค่า intercept
คลิกเพื่อดูโค้ดไพธอน
import numpy as np
# ตัวแปรตาม (log wage)
y = np.array([10.5 , 11.2 , 9.8 , 12.0 , 10.1 ]).reshape(- 1 , 1 )
y
array([[10.5],
[11.2],
[ 9.8],
[12. ],
[10.1]])
คลิกเพื่อดูโค้ดไพธอน
# ตัวแปรต้น: education และ experience
X_orig = np.array([
[16 , 5 ],
[18 , 2 ],
[12 , 10 ],
[20 , 8 ],
[14 , 4 ]
])
X_orig
array([[16, 5],
[18, 2],
[12, 10],
[20, 8],
[14, 4]])
คลิกเพื่อดูโค้ดไพธอน
# เพิ่มคอลัมน์ 1 (intercept)
intercept = np.ones((X_orig.shape[0 ], 1 ))
X = np.hstack((intercept, X_orig))
print ("Matrix X: \n " , X)
Matrix X:
[[ 1. 16. 5.]
[ 1. 18. 2.]
[ 1. 12. 10.]
[ 1. 20. 8.]
[ 1. 14. 4.]]
การคำนวณตัวประมาณค่า OLS โดยมีเป้าหมายเพื่อหา \(\hat{\beta}\) ที่ทำให้ “ความคลาดเคลื่อนรวม” ต่ำที่สุด
สูตรเมทริกซ์คือ:
\[
\hat{\boldsymbol{\beta}} = (\mathbf{X}'\mathbf{X})^{-1}\mathbf{X}'\mathbf{y}
\]
ขั้นตอนการคำนวณ
คลิกเพื่อดูโค้ดไพธอน
# (X'X)
XTX = X.T @ X
XTX
array([[ 5., 80., 29.],
[ 80., 1320., 452.],
[ 29., 452., 209.]])
คลิกเพื่อดูโค้ดไพธอน
# (X'X)^-1
XTX_inv = np.linalg.inv(XTX)
XTX_inv
array([[ 9.62043011e+00, -4.85483871e-01, -2.84946237e-01],
[-4.85483871e-01, 2.74193548e-02, 8.06451613e-03],
[-2.84946237e-01, 8.06451613e-03, 2.68817204e-02]])
คลิกเพื่อดูโค้ดไพธอน
array([[ 53.6],
[868.6],
[309.3]])
คลิกเพื่อดูโค้ดไพธอน
# คำนวณ Beta hat
beta_hat = XTX_inv @ XTy
labels = ['Intercept' , 'Education' , 'Experience' ]
for label, coef in zip (labels, beta_hat.flatten()):
print (f" { label} : { coef:.4f} " )
Intercept: 5.8299
Education: 0.2889
Experience: 0.0462
Intercept: รายได้พื้นฐานเมื่อค่าอื่นเป็นศูนย์
Education: ผลตอบแทนจากการศึกษา (เพิ่ม 1 ปี → รายได้เพิ่มเท่าใด)
Experience: ผลของประสบการณ์
นี่คือการเปลี่ยน “ข้อมูล” → “ข้อสรุปทางเศรษฐศาสตร์”
การประเมินแบบจำลอง
เมื่อได้ \(\hat{\beta}\) แล้ว เราสามารถคำนวณค่าพยากรณ์และความคลาดเคลื่อนได้ทันที
คลิกเพื่อดูโค้ดไพธอน
# ค่าพยากรณ์
y_hat = X @ beta_hat
# Residuals
residuals = y - y_hat
# Sum of Squared Residuals (SSR)
ssr = residuals.T @ residuals
print (f"Sum of Squared Residuals (SSR): { ssr[0 ,0 ]:.4f} " )
Sum of Squared Residuals (SSR): 0.0435
เมื่อเข้าใจ OLS ในรูปแบบเมทริกซ์ นักศึกษาจะเข้าใจพื้นฐานของ econometrics เกือบทั้งหมด
ประโยชน์ในเชิงลึกสำหรับนักเศรษฐศาสตร์
การใช้ NumPy ไม่เพียงแต่ทำให้เราคำนวณ OLS ได้เอง แต่ยังเป็นพื้นฐานสำคัญสำหรับ:
Linear Algebra: การหาจุดดุลยภาพในแบบจำลองหลายตลาด
Simulation: การสุ่มตัวอย่างแบบ Monte Carlo เพื่อทดสอบนโยบายเศรษฐกิจ
Data Transformation: การทำ Log-transform หรือ Scaling ข้อมูลขนาดใหญ่ก่อนส่งเข้าโมเดล Machine Learning
Géron, Aurélien. 2019. Hands-on Machine Learning with Scikit-Learn, Keras, and TensorFlow . 2nd ed. O’Reilly Media.
Greene, William H. 2018. Econometric Analysis . 8th ed. Pearson.
Hamilton, James D. 1994. Time Series Analysis . Princeton University Press.
Hastie, Trevor, Robert Tibshirani, and Jerome Friedman. 2009a. The Elements of Statistical Learning . Springer.
Hastie, Trevor, Robert Tibshirani, and Jerome Friedman. 2009b. The Elements of Statistical Learning: Data Mining, Inference, and Prediction . 2nd ed. Springer.
Hyndman, Rob J., and George Athanasopoulos. 2021. Forecasting: Principles and Practice . 3rd ed.
McKinney, Wes. 2022. Python for Data Analysis . 3rd ed. O’Reilly Media.
Quarto Team. 2024.
Quarto Documentation .
https://quarto.org .
Stock, James H., and Mark W. Watson. 2020. Introduction to Econometrics . 4th ed. Pearson.
VanderPlas, Jake. 2016. Python Data Science Handbook . O’Reilly Media.
Wickham, Hadley, Mine Cetinkaya-Rundel, and Garrett Grolemund. 2023. R for Data Science . 2nd ed.
Wooldridge, Jeffrey M. 2020. Introductory Econometrics: A Modern Approach . 7th ed. Cengage Learning.
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2018. R Markdown: The Definitive Guide . Chapman; Hall/CRC.