lolamontes69

Ch6 Ex1-Programming Collective Intelligence.

Jul 17th, 2013
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.00 KB | None | 0 0
  1. """ Chapter 6 Exercise 1: Varying assumed probabilities.
  2.  
  3.    1 Change the classifier class so it supports different assumed probabilities for different features.
  4.      New usage:  cl.weightedprob('quick','good',cl.fprob) # ap is called from db instead
  5.                  cl.get_ap('quick','good')                # returns ap from fc table in db (default is 0.5)
  6.                  cl.set_ap('quick','good',0.89)           # sets the ap
  7.                  cl.set_ap('quick','bad',0.26)          
  8.  
  9.    2 Change the init method so that it will take another classifier and start with a better guess than 0.5 for the assumed probabilities.
  10.  
  11.    I was unable to figure out what this meant (:In my defence I have lived in French-speaking countries for 18 years:)
  12.    Does take another classifier mean import another instance of a classifier?
  13. """
  14.  
  15. import re as re
  16. import math as math
  17. from pysqlite2 import dbapi2 as sqlite
  18.  
  19. def sampletrain(cl):
  20.     cl.train('Nobody owns the water','good')
  21.     cl.train('the quick rabbit jumps fences','good')
  22.     cl.train('buy pharmeceuticals now','bad')
  23.     cl.train('make quick money at the online casino','bad')
  24.     cl.train('the quick brown fox jumps over the lazy dog','good')
  25.  
  26. def getwords(doc):
  27.     splitter=re.compile('\\W*')
  28.     # Split the words by non-alpha characters
  29.     words=[s.lower() for s in splitter.split(doc) if len(s)>2 and len(s)<20]
  30.     # Return the unique set of words only
  31.     return dict([(w,1) for w in words])
  32.  
  33. class classifier:
  34.     def __init__(self,getfeatures):
  35.         self.getfeatures=getfeatures
  36.  
  37.     def setdb(self,dbfile):
  38.         self.con=sqlite.connect(dbfile)
  39.         self.con.execute('create table if not exists fc(feature,category,count,ap)')
  40.         self.con.execute('create table if not exists cc(category,count)')
  41.  
  42.     # Increase the count of a feature/category pair
  43.     def incf(self,f,cat):
  44.         count=self.fcount(f,cat)
  45.         try:
  46.             if count==0:
  47.                 self.con.execute("insert into fc values ('%s','%s',1,0.5)" % (f,cat)) # default ap value is 0.5
  48.             else:
  49.                 self.con.execute("update fc set count=%d where feature='%s' and category='%s'" % (count+1,f,cat))
  50.         except: print "error adding",f,"in category",cat
  51.  
  52.     def set_ap(self,f,cat,ap):
  53.         changeit = "update fc set ap="+str(ap)+" where feature='"+f+"' and category='"+cat+"'"
  54.         self.con.execute(changeit)
  55.  
  56.     def get_ap(self,f,cat):
  57.         res=self.con.execute('select ap from fc where feature="%s" and category="%s"' % (f,cat)).fetchone()
  58.         if res==None: return 0   # default ap value
  59.         else: return float(res[0])
  60.  
  61.     # Increase the count of a category
  62.     def incc(self,cat):
  63.         count=self.catcount(cat)
  64.         try:
  65.             if count==0:
  66.                 self.con.execute("insert into cc values ('%s',1)" % (cat))
  67.             else:
  68.                 self.con.execute("update cc set count=%d where category='%s'" % (count+1,cat))
  69.         except: print "error adding",f,"in category",cat
  70.  
  71.     # The number of times a feature has appeared in a category
  72.     def fcount(self,f,cat):
  73.         res=self.con.execute('select count from fc where feature="%s" and category="%s"' % (f,cat)).fetchone()
  74.         if res==None: return 0
  75.         else: return float(res[0])
  76.  
  77.     # The number of items in a category
  78.     def catcount(self,cat):
  79.         res=self.con.execute('select count from cc where category="%s"' % (cat)).fetchone()
  80.         if res==None: return 0
  81.         else: return float(res[0])
  82.  
  83.     # The total number of items
  84.     def totalcount(self):
  85.         res=self.con.execute('select sum(count) from cc').fetchone()
  86.         if res==None: return 0
  87.         return res[0]
  88.  
  89.     # The list of all the categories
  90.     def categories(self):
  91.         cur=self.con.execute('select category from cc')
  92.         return [d[0] for d in cur]
  93.  
  94.     def train(self,item,cat):
  95.         features=self.getfeatures(item)
  96.         # Increment the count for every feature with this category
  97.         for f in features:
  98.             self.incf(f,cat)
  99.  
  100.         # Increment the count for this category
  101.         self.incc(cat)
  102.         self.con.commit()
  103.  
  104.     def fprob(self,f,cat):
  105.         if self.catcount(cat)==0: return 0
  106.  
  107.         # The total number of times this feature appeared in this category
  108.         # divided by the total number of items in this category
  109.         return self.fcount(f,cat)/self.catcount(cat)
  110.  
  111.     def weightedprob(self,f,cat,prf,weight=1.0):
  112.         # Calculate current probability
  113.         basicprob=prf(f,cat)
  114.         # Count the number of times this feature has appeared in all categories
  115.         totals=sum([self.fcount(f,c) for c in self.categories()])
  116.  
  117.         # Get the assumed probability for the feature
  118.         ap = self.get_ap(f,cat)
  119.         if ap == 0: ap = 0.5       # If not in database set to default value
  120.  
  121.         # Calculate the weighted average
  122.         bp=((weight*ap)+(totals*basicprob))/(weight+totals)
  123.         return bp
  124.  
  125. class naivebayes(classifier):
  126.  
  127.     def __init__(self,getfeatures):
  128.         classifier.__init__(self,getfeatures)
  129.         self.thresholds={}
  130.  
  131.     def docprob(self,item,cat):
  132.         features=self.getfeatures(item)
  133.  
  134.         # Multiply the probabilities of all the features together
  135.         p=1
  136.         for f in features: p *= self.weightedprob(f,cat,self.fprob)
  137.         return p
  138.  
  139.     def prob(self,item,cat):
  140.         catprob=self.catcount(cat)/self.totalcount()
  141.         docprob=self.docprob(item,cat)
  142.         return docprob*catprob
  143.  
  144.     def setthreshold(self,cat,t):
  145.         self.thresholds[cat]=t
  146.  
  147.     def getthreshold(self,cat):
  148.         if cat not in self.thresholds: return 1.0
  149.         return self.thresholds[cat]
  150.  
  151.     def classify(self,item,default=None):
  152.         probs={}
  153.         # Find the category with the highest probability
  154.         max=0.0
  155.         for cat in self.categories():
  156.             probs[cat]=self.prob(item,cat)
  157.             if probs[cat]>max:
  158.                 max=probs[cat]
  159.                 best=cat
  160.  
  161.         # Make sure the probability exceeds threshold*next best
  162.         for cat in probs:
  163.             if cat==best: continue
  164.             if probs[cat]*self.getthreshold(best)>probs[best]: return default
  165.         return best
  166.  
  167. class fisherclassifier(classifier):
  168.     def __init__(self,getfeatures):
  169.         classifier.__init__(self,getfeatures)
  170.         self.minimums={}
  171.  
  172.     def setminimum(self,cat,min):
  173.         self.minimums[cat]=min
  174.  
  175.     def getminimum(self,cat):
  176.         if cat not in self.minimums: return 0
  177.         return self.minimums[cat]
  178.  
  179.     def cprob(self,f,cat):
  180.         # The frequency of this feature in this category
  181.         clf=self.fprob(f,cat)
  182.         if clf==0: return 0
  183.  
  184.         # The frequency of this feature in all the categories
  185.         freqsum=sum([self.fprob(f,c) for c in self.categories()])
  186.  
  187.         # The probability is the frequency in this category divided by the overall frequency
  188.         p=clf/(freqsum)
  189.  
  190.         return p
  191.  
  192.     def fisherprob(self,item,cat):
  193.         # Multiply all the probabilities together
  194.         p=1
  195.         features=self.getfeatures(item)
  196.         for f in features:
  197.             p *= (self.weightedprob(f,cat,self.cprob))
  198.  
  199.         # Take the natural log and multiply by -2
  200.         try: fscore=-2*math.log(p)   # if db returns none for ap because feature not in fc
  201.         except: return 0
  202.         # Use the inverse chi2 function to get a probability
  203.         return self.invchi2(fscore,len(features)*2)
  204.  
  205.     def invchi2(self,chi,df):
  206.         m=chi/2.0
  207.         sum = term = math.exp(-m)
  208.         for i in range(1, df//2):
  209.             term *= m/i
  210.             sum += term
  211.         return min(sum, 1.0)
  212.  
  213.     def classify(self,item,default=None):
  214.         # Loop through looking for the best result
  215.         best=default
  216.         max=0.0
  217.         for c in self.categories():
  218.             p=self.fisherprob(item,c)
  219.             # Make sure it exceeds the minimum
  220.             if p>self.getminimum(c) and p>max:
  221.                 best=c
  222.                 max=p
  223.         return best
Advertisement
Add Comment
Please, Sign In to add comment