สวัสดีครับ สำหรับบทความนี้บทความที่ต่อจาก 2 บทความที่แล้วที่ผมเขียนไว้ในรอบที่แล้ว ซึ่งเป็นการทำ Regression ของข้อมูลทั้งแบบเชิงเส้นและแบบดีกรีมากกว่า 1

เทคนิคทั้ง 2 ที่ผมเขียนไปสามารถนำไปประมาณค่าได้แค่ในความสัมพันธ์ที่มีตัวแปร 2 ตัวเท่านั้น (ค่า x และ y) แต่ในบางวามสัมพันธ์ ค่าค่านึงอาจจะมีผลมาจากหลายอย่างได้ อย่างเช่น ราคาของรถ ก็อาจจะมีผลมาจากยี่ห้อ จำนวนลูกสูบ กำลังของเครื่องยนต์ ความจุตัวถัง ฯลฯ

ซึ่ง model ที่ผมเขียนบทความไปทั้ง 2 ตัวที่แล้วไม่สามารถประมาณค่าได้เพราะประมาณได้ก็แค่ค่า x และ y เท่านั้น

ในบทความนี้ผมจะเขียนเกี่ยวกับ Multi Variable Regression ซึ่งสามารถที่จะนำมาแก้ปัญหาข้างต้นที่ว่ามาได้ครับ


ในบทความนี้ผมขอยกตัวอย่างปรากฎการณ์ทางฟิสิกส์ปรากฎการณ์นึงซึ่งเราสามารถนำ Multi Variable Regression ไปช่วยทำนายค่าได้ และเป็นปรากฎการณ์นึงที่น่าสนใจมากในทางฟิสิกส์ครับ

ปรากฎการณ์ที่ว่านี้มีชื่อว่า Photoelectric ซึ่งเป็นปรากฎการณ์ที่ไอน์สไตน์สามารถอธิบายได้ จนได้รับรางวัลโนเบลสาขาฟิสิกส์ในปี 1921(เกือบ 100 ปีมาแล้วเชียว)

ปรากฎการณ์นี้มีคนให้ความสนใจเพราะเมื่อเราฉายรังสี(พลังงาน)ไปที่วัตถุโลหะซักวัตถุนึง จนทำให้อิเล็กตรอนที่อยู่ในวัตถุนั้นหลุดออกมา แต่ว่าพอไปวัดพลังงานจลน์ของอิเล็กตรอนที่หลุดออกมาจากวัตถุนั้น กลับมีค่าไม่เท่ากับพลังงานที่เราป้อนเข้าไป?

ถ้าใครสนใจสามารถไปหาอ่านได้นะครับ แต่เพื่อไม่ให้บทความยาวเกินไปผมจะขอเอาสมการที่อธิบายปรากฎการณ์นี้มาให้ดูเลย

จากสมการค่า Ek คือพลังงานจลน์ที่จะวัดได้เมื่ออิเล็กตรอนหลุดออกมาจากวัตถุโลหะ h คือค่าคงที่ของพลังค์ (~6.26 x 10^-34) f คือความถี่ของรังสีที่เราปล่อยส่วน ϕ คือค่าฟังค์ชันงานของวัตถุโลหะ ซึ่งแต่ละชนิดมีไม่เท่ากัน (คิดซะว่าเป็นพลังงานที่อิเล็กตรอนสูญเสียไปในโลหะ)

โดยสิ่งที่เราต้องการจะทำนายคือค่า พลังงานจลน์โดยจะทำนายจากค่า 2 ค่าคือพลังงานที่เราปล่อยไปใส่วัตถุโลหะ และฟังค์ชันงานของวัตถุโลหะ

ถ้าไม่อยากคิดมากลองนึกว่า Ek = hf - ϕ เป็น y = x + z ดูครับ จะเห็นว่าถ้าเกิดค่า x หรือ z เปลี่ยนไป จะทำให้ค่า y เปลี่ยนไปด้วย ซึ่งเป็นสิ่งที่เราต้องการหาความสัมพันธ์ของมันนั่นเอง

มาเขียนโค้ดกันเลยดีกว่า

ก่อนอื่นถ้าใครยังไม่ติดตั้ง package ตัวไหนต่อไปนี้ต้องติดตั้งก่อนครับ pandas, scipy, matplotlib, scikit-learn, statsmodels

สามารถติดตั้งโดยใช้คำสั่งนี้บน command line ได้เลย

pip install <ชื่อแพคเกจ>

ผมเริ่มต้นจากการ generate ข้อมูลขึ้นมาก่อน โดย generate ข้อมูลตามสมการข้างบนแล้วเอามาใส่ใน DataFrameimport random
import matplotlib.pyplot as plt
from scipy.constants import Planck, speed_of_light, e
import pandas as pd# Ba 2.5
# Cs 1.9
# Cu 4.7
# K 2.2
# Ag 4.6
# Na 2.3
# W 4.5# Ek = hf — W
# lambda 400nm -> 700nm# Ek = h lambda / c — Wlength_of_lights = []
Work_functions = []
Eks = []for _ in range(100):
 length_of_light = random.uniform(400, 700)
 W = random.choice([2.5, 1.9, 4.7, 2.2, 4.6, 2.3, 4.5])
 Ek = (Planck / e * speed_of_light / (length_of_light * 0.000000001)) — WEks.append(Ek)length_of_lights.append(length_of_light)Work_functions.append(W)df = pd.DataFrame({‘W’: Work_functions, ‘lambda’: length_of_lights, ‘Ek’: Eks})

สำหรับใครที่งงทฤษฎีฟิสิกส์ไม่ต้องซีเรียสครับเพราะตรงนี้ยังไม่ถึงตอนทำโมเดลจริงๆX = df[[‘W’, ‘lambda’]]
y = df[‘Ek’]

เมื่อสร้างชุดข้อมูลเสร็จแล้วผมเอาข้อมูลมาแบ่งตามคอลัมน์เป็น X กับ y

จะสังเกตว่าที่ X จะมีคอลัมน์มากกว่า 1 คอลัมน์ เพราะว่าตามสมการแล้วค่าที่เราต้องการทำนายจะมีผลมาจากค่า 2 ค่าไม่ใช่แค่ค่าเดียวครับimport statsmodels.api as smmodel = sm.OLS(y, X).fit()

ในการ train model เราแค่เรียกใช้คำสั่ง sm.OLS().fit() ก็จะได้ตัวโมเดลมาเรียบร้อยครับpredicted = est.predict([4.5, 525.])
print(predicted)

ไหนๆก็ train เสร็จแล้วลองเอา model มาคำนวณค่าดูครับผมให้ค่าฟังค์ชันงานเป็น 4.5 และ ความยาวคลื่นเป็น 525 นาโนเมตร ได้ผลออกมาเป็น

-2.03656012 ซึ่งผมลองกดเครื่องคิดเลขคิดดูตามสมการเองแล้วจะได้ค่าประมาณ -2.13 กว่าๆ ซึ่งตัวโมเดลที่เราทำก็มีค่า error ไม่น่าเกลียดมากเท่าไร (คิดว่าที่ค่า error น่าจะมาจากแปลงหน่วยไปมาด้วยส่วนนึงครับ)


โค้ดทั้งหมด


ตอนนี้น่าจะเป็นตอนสุดท้ายที่เขียนเกี่ยวกับการทำ regression แล้วครับ สำหรับการทำ machine learning ก็ยังมีเทคนิคอื่นๆที่น่าสนใจอีกเยอะ เดี๋ยวผมจะพยายามเขียนมาเรื่อยๆนะครับ 😊😊😊