01204435/haskell2
เราจะอิมพลีเมนท์ Perceptron algorithm แบบง่าย (ข้อมูลมี 2 มิติ) บน Haskell
- อ่านรายละเอียดของ Perceptron algorithm
- อ่านรายละเอียดของแฟ้มข้อมูลทดสอบ: การทดลองเกี่ยวกับ perceptron
- ดาวน์โหลดข้อมูลทดสอบ: [1] เป็นไฟล์ p1.txt และ p2.txt
เราจะนิยามชนิดข้อมูล Vector เพื่อความสะดวกต่อไป
type Vector = (Double, Double)
เนื้อหา
ฟังก์ชันเกี่ยวกับเวกเตอร์
จริง ๆ แล้ว Haskell มีไลบรารีเกี่ยวกับเวกเตอร์ (ดู [2]) แต่เราจะเขียนเองเพื่อความง่ายและสะดวก
ด้านล่างเป็น type ของฟังก์ชัน dot (คำนวณ dot product), addVector และ negVector และตัวอย่าง
dot :: Vector -> Vector -> Double
ตัวอย่างฟังก์ชัน dot
*Main> dot (1,0) (1,0) 1.0 *Main> dot (1,0) (0,1) 0.0 *Main> dot (1,0.5) (0,1) 0.5 *Main> dot (1,0.5) (-1,2) 0.0
addVector :: Vector -> Vector -> Vector
ตัวอย่างฟังก์ชัน addVector
*Main> addVector (1,2) (3,-4) (4,-2)
negVector :: Vector -> Vector
ตัวอย่างฟังก์ชัน negVector
*Main> negVector (10,-5) (-10,5)
ทำนาย
1. เขียนฟังก์ชัน
predict :: Vector -> Vector -> Int
ที่รับเวกเตอร์ w และ x จากนั้นคืนผลการทำนาย (เป็น 1 หรือ -1)
ตัวอย่าง
*Main> predict (1,-1) (1,0) 1 *Main> predict (1,-1) (1,-1) 1 *Main> predict (1,-1) (0,1) -1 *Main> predict (1,-1) (-1,1) -1
2. เขียนฟังก์ชัน
predictAll :: Vector -> [Vector] -> [Int]
ที่รับ w และ list xs จากนั้นทำนายข้อมูลทุกตัวใน xs ให้ลองเขียนด้วยฟังก์ชัน map (ดูตัวอย่างที่ [3])
ตัวอย่าง
*Main> predictAll (1,-1) [(1,0), (1,-1), (0,1), (-1,1)] [1,1,-1,-1]
ฝึกสอนด้วย perceptron algorithm
1. เขียนฟังก์ชัน trainOnce w x z
trainOnce :: Vector -> Vector -> Int -> Vector
ที่รับ weight w, input x และคลาสเฉลย z และคืนค่า weight vector w ใหม่ ตามที่ระบุใน perceptron algorithm
สังเกตว่าถ้า w สามารถจำแนก x ได้ถูกต้อง w จะไม่มีการปรับค่า
2. เขียนฟังก์ชัน train w xs
train :: Vector -> [(Vector,Int)] -> Vector
ตัวอย่าง
*Main> train (0,0) [((1,0),1), ((-1,1),-1), ((0,1),-1), ((1,-1),1)] (1.0,0.0)
ที่รับ weight vector เริ่มต้น และ train ข้อมูลฝึกหัดที่อยู่ใน xs ทั้งหมด
การอ่าน input/output
เราจะเขียนฟังก์ชันที่ประมวลผล input / output โดยที่รับ input เป็นสตริง และคืนผลลัพธ์เป็น weight vector ก่อน จากนั้นเราถึงจะเขียนฟังก์ชันที่อ่านข้อมูลจากไฟล์จริงชื่อ trainFromFile ซึ่งฟังก์ชันดังกล่าวนี้จะมี type พิเศษ
แปลงจาก String เป็น Int และ Double
เราสามารถใช้ฟังก์ชัน read ได้ เช่น
*Main> read "100" :: Int 100 *Main> read "100.343" :: Double 100.343
หรืออาจจะเขียนฟังก์ชันได้ เช่น
strToInt s = (read s :: Int)
processInput
เขียนฟังก์ชัน processInput ที่รับสตริงในรูปแบบ
จำนวนข้อมูล ข้อมูล1 ข้อมูล2 ข้อมูล3 ...
โดยที่บรรทัดที่เป็นข้อมูล ประกอบไปด้วย Double สองตัวและ Int หนึ่งตัว เช่น
-7.25968563254 -8.90106971694 -1
โดยที่จำนวนจริงสองตัวแรกเป็นพิกัดของข้อมูล และ จำนวนเต็มตัวที่สามเป็นประเภทข้อมูล (มีค่าเป็น -1 หรือ 1)
และคืนค่าเป็นรายการของข้อมูลสำหรับส่งให้ฟังก์ชัน train
ตัวอย่างเช่น
*Main> processInput "3\n-7.259 -8.901 -1\n10.077 10.904 1\n11.478 8.530 1\n" [((-7.259,-8.901),-1),((10.077,10.904),1),((11.478,8.530),1)]
ในการแปลงดังกล่าว ฟังก์ชันสตริงที่อาจจะต้องใช้ เช่น ฟังก์ชัน lines [4] และ ฟังก์ชัน words [5]
ซึ่งใช้งานได้ดังตัวอย่างด้านล่าง
*Main> lines "1234\n6789\n101213\n" ["1234","6789","101213"] *Main> words "-7.25968563254 -8.90106971694 -1" ["-7.25968563254","-8.90106971694","-1"]
trainFromFile
ในส่วนที่อ่านข้อมูลจากไฟล์ เราจะใช้ฟังก์ชันดังด้านล่าง สำหรับการใช้งาน do <- และ return เราจะกล่าวถึงต่อไป
trainFromFile fname = do l <- readFile fname return (train (0,0) (processInput l))
ทดสอบ weight (extra) =
ถ้าเป็นไปได้ ควรทดลองเขียนฟังก์ชันที่นำ weight vector ที่ได้ไปทดสอบความถูกต้องกับข้อมูลที่ใช้ฝึกสอนและคืนค่าเปอร์เซ็นต์ความถูกต้องออกมา