Skip to content

Instantly share code, notes, and snippets.

@PirosB3
Last active August 29, 2015 14:05
Show Gist options
  • Save PirosB3/04932c561b7386d953a5 to your computer and use it in GitHub Desktop.
Save PirosB3/04932c561b7386d953a5 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"sync"
"math"
)
type FreqDist struct {
sync.Mutex
events map[interface{}]int
count int
}
func (fd *FreqDist) add(event interface{}) {
fd.Lock()
if fd.events[event] == 0 {
fd.events[event]++
}
fd.events[event]++
fd.count++
fd.Unlock()
}
func (fd *FreqDist) prob(event interface{}) float64 {
freq := float64(fd.events[event])
if freq == 0 {
freq = 1
}
return float64(freq) / float64(fd.count)
}
func (fd *FreqDist) logprob(event interface{}) float64 {
return math.Log(fd.prob(event))
}
func NewFreqDist() *FreqDist {
events := make(map[interface{}]int)
return &FreqDist{events: events, count: 2}
}
type ConditionalFreqDist struct {
sync.Mutex
eventsInClasses map[string]*FreqDist
}
func NewConditionalFreqDist() *ConditionalFreqDist {
return &ConditionalFreqDist{
eventsInClasses: make(map[string]*FreqDist),
}
}
func (cfd *ConditionalFreqDist) getClass(class string) *FreqDist {
if cfd.eventsInClasses[class] == nil {
cfd.eventsInClasses[class] = NewFreqDist()
}
return cfd.eventsInClasses[class]
}
func (cfd *ConditionalFreqDist) add(class string, event string) {
cfd.Lock()
cfd.getClass(class).add(event)
cfd.Unlock()
}
func (cfd *ConditionalFreqDist) prob(class string, event string) float64 {
return cfd.getClass(class).prob(event)
}
type NaiveBayesClassifier struct {
classNames map[string]bool
classFrequencies *FreqDist
eventFrequencies *FreqDist
eventClassFrequencies *ConditionalFreqDist
}
func NewNaiveBayesClassifier() *NaiveBayesClassifier {
return &NaiveBayesClassifier {
classNames: make(map[string]bool),
classFrequencies: NewFreqDist(),
eventFrequencies: NewFreqDist(),
eventClassFrequencies: NewConditionalFreqDist(),
}
}
func (nb *NaiveBayesClassifier) add(class string, events []string) {
// Increase P(class)
nb.classFrequencies.add(class)
nb.classNames[class] = true
for _, event := range events {
// Increase P(event)
nb.eventFrequencies.add(event)
// Increase P(event|class)
nb.eventClassFrequencies.add(class, event)
}
}
func (nb *NaiveBayesClassifier) prob(class string, events []string) float64 {
// P(class)
classProb := nb.classFrequencies.logprob(class)
for _, event := range events {
// P(event|class)
classProb *= nb.eventClassFrequencies.prob(class, event)
}
return classProb
}
func (nb *NaiveBayesClassifier) classify(events []string) (string, float64) {
var topClassName string = ""
var topClassScore float64 = -1
for class := range nb.classNames {
score := nb.prob(class, events)
if score > topClassScore {
topClassScore = score
topClassName = class
}
}
return topClassName, topClassScore
}
func main() {
nb := NewNaiveBayesClassifier()
nb.add("positive", []string{"I", "am", "so" ,"happy" ,"at" ,"the", "moment"})
nb.add("negative", []string{"Fuck", "off"})
nb.add("negative", []string{"I", "Hate", "You"})
fmt.Println(nb.classify([]string{"Fuck", "I", "am", "so", "happy"}))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment