ผลต่างระหว่างรุ่นของ "01204435/haskell2"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
 
(ไม่แสดง 17 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน)
แถว 3: แถว 3:
 
* อ่านรายละเอียดของ [[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 เพื่อความสะดวกต่อไป
 
เราจะนิยามชนิดข้อมูล Vector เพื่อความสะดวกต่อไป
แถว 11: แถว 12:
  
 
จริง ๆ แล้ว Haskell มีไลบรารีเกี่ยวกับเวกเตอร์ (ดู [http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Vector_Tutorial]) แต่เราจะเขียนเองเพื่อความง่ายและสะดวก
 
จริง ๆ แล้ว 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

เราจะนิยามชนิดข้อมูล 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 ที่ได้ไปทดสอบความถูกต้องกับข้อมูลที่ใช้ฝึกสอนและคืนค่าเปอร์เซ็นต์ความถูกต้องออกมา