ผลต่างระหว่างรุ่นของ "01204435/haskell2"
Jittat (คุย | มีส่วนร่วม) (หน้าที่ถูกสร้างด้วย 'เราจะอิมพลีเมนท์ Perceptron algorithm แบบง่าย (ข้อมูลมี 2 มิติ) ...') |
Jittat (คุย | มีส่วนร่วม) |
||
(ไม่แสดง 18 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน) | |||
แถว 2: | แถว 2: | ||
* อ่านรายละเอียดของ [[01204472/perceptron algorithm|Perceptron algorithm]] | * อ่านรายละเอียดของ [[01204472/perceptron algorithm|Perceptron algorithm]] | ||
− | * อ่านรายละเอียดของแฟ้มข้อมูลทดสอบ [[01204472/การทดลองเกี่ยวกับเวกเตอร์#ทดลองอัลกอริทึม perceptron|การทดลองเกี่ยวกับ perceptron]] | + | * อ่านรายละเอียดของแฟ้มข้อมูลทดสอบ: [[01204472/การทดลองเกี่ยวกับเวกเตอร์#ทดลองอัลกอริทึม perceptron|การทดลองเกี่ยวกับ perceptron]] |
+ | * ดาวน์โหลดข้อมูลทดสอบ: [http://theory.cpe.ku.ac.th/~jittat/01204472-55/vectors/] เป็นไฟล์ p1.txt และ p2.txt | ||
+ | |||
+ | เราจะนิยามชนิดข้อมูล Vector เพื่อความสะดวกต่อไป | ||
+ | |||
+ | type Vector = (Double, Double) | ||
+ | |||
+ | == ฟังก์ชันเกี่ยวกับเวกเตอร์ == | ||
+ | |||
+ | จริง ๆ แล้ว Haskell มีไลบรารีเกี่ยวกับเวกเตอร์ (ดู [http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Vector_Tutorial]) แต่เราจะเขียนเองเพื่อความง่ายและสะดวก | ||
+ | |||
+ | ด้านล่างเป็น 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 (ดูตัวอย่างที่ [http://www.haskell.org/haskellwiki/Function]) | ||
+ | |||
+ | ตัวอย่าง | ||
+ | |||
+ | *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 [http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:lines] และ ฟังก์ชัน words [http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:words] | ||
+ | |||
+ | ซึ่งใช้งานได้ดังตัวอย่างด้านล่าง | ||
+ | |||
+ | *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 ที่ได้ไปทดสอบความถูกต้องกับข้อมูลที่ใช้ฝึกสอนและคืนค่าเปอร์เซ็นต์ความถูกต้องออกมา |
รุ่นแก้ไขปัจจุบันเมื่อ 10:56, 4 กรกฎาคม 2556
เราจะอิมพลีเมนท์ 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 ที่ได้ไปทดสอบความถูกต้องกับข้อมูลที่ใช้ฝึกสอนและคืนค่าเปอร์เซ็นต์ความถูกต้องออกมา