Last active
December 11, 2015 14:18
-
-
Save Lambdanaut/4613240 to your computer and use it in GitHub Desktop.
A binary labeling perceptron written in Haskell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module Percept where | |
| -- The example training/testing data has single digit numbers set to True, and double digit numbers set to False | |
| trainingData :: [([Double], Bool)] | |
| testingData :: [([Double], Bool)] | |
| trainingData = [ | |
| ([1], True), | |
| ([5], True), | |
| ([6], True), | |
| ([9], True), | |
| ([15], False), | |
| ([12], False), | |
| ([25], False), | |
| ([19], False)] | |
| testingData = [ | |
| ([4], True), | |
| ([2], True), | |
| ([3], True), | |
| ([8], True), | |
| ([13], False), | |
| ([11], False), | |
| ([29], False), | |
| ([18], False)] | |
| learningIterations = 100 | |
| startingWeights = take (length $ fst $ testingData !! 0 ) $ repeat 0.0 | |
| startingTheta = 0.0 | |
| dotProduct x y = sum $ zipWith (*) x y | |
| decision x w theta = dotProduct x w > theta | |
| -- Updates the weights and theta from a single training record. | |
| -- (Training Data, Binary Value of Training Data) -> (Previous Weights, Old Theta) -> (New Weights, New Theta) | |
| perceptron :: ([Double], Double) -> ([Double], Bool) -> ([Double], Double) | |
| perceptron (weights, theta) (trainingData, val) | |
| | d == False && val == True = (newWeights (+), theta - 1) | |
| | d == True && val == False = (newWeights (-), theta + 1) | |
| | otherwise = (weights, theta) | |
| where | |
| d = decision trainingData weights theta | |
| newWeights combiningFunction = zipWith combiningFunction weights trainingData | |
| -- Loops through a list of training records "learningIterations" times, and returns adjusted weights and theta. | |
| learn :: ([Double], Double) -> [([Double], Bool)] -> ([Double], Double) | |
| learn (weights, theta) trainingData = last $ take learningIterations $ iterate (\ currentWeightTheta -> foldl perceptron currentWeightTheta trainingData) (startingWeights, startingTheta) | |
| -- Loops through a list of training records and prints "Correct" if the given weights/theta correctly classified the value, and "Incorrect" otherwise. | |
| act :: ([Double], Double) -> [([Double], Bool)] -> IO () | |
| act (weights, theta) testingData = mapM_ (\ (dataSet, val) -> putStrLn $ boolToEnglish $ val == decision dataSet weights theta) testingData | |
| where | |
| boolToEnglish True = "Correct" | |
| boolToEnglish False = "Incorrect" | |
| main :: IO () | |
| main = (\ x -> act x testingData) $ learn (startingWeights, startingTheta) trainingData |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment