lolamontes69

numpredict.py for Ch8 Programming Collective Intelligence

Aug 10th, 2013
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.72 KB | None | 0 0
  1. from random import random,randint
  2. import math as math
  3.  
  4. def wineprice(rating,age):
  5.     peak_age=rating-50
  6.  
  7.     # Calculate price based on rating
  8.     price=rating/2    
  9.     if age>peak_age:
  10.         # Past its peak, goes bad in 5 years
  11.         price=price*(5-(age-peak_age))
  12.     else:
  13.         # Increases to 5x its original value as it approaches its peak
  14.         price=price*(5*((age+1)/peak_age))
  15.     if price<0: price=0
  16.     return price
  17.  
  18.  
  19. def wineset1():
  20.     rows=[]
  21.     for i in range(300):
  22.         # Create a random age and rating
  23.         rating=random()*50+50
  24.         age=random()*50
  25.  
  26.         # Get reference price
  27.         price=wineprice(rating,age)
  28.  
  29.         # Add some noise
  30.         price*=(random()*0.4+0.8)
  31.  
  32.         # Add to the dataset
  33.         rows.append({'input':(rating,age), 'result':price})
  34.     return rows
  35.  
  36. def euclidean(v1,v2):
  37.     d=0.0
  38.     for i in range(len(v1)):
  39.         d+=(v1[i]-v2[i])**2
  40.     return math.sqrt(d)
  41.  
  42.  
  43. def getdistances(data,vec1):
  44.     distancelist=[]
  45.     for i in range(len(data)):
  46.         vec2=data[i]['input']
  47.         distancelist.append((euclidean(vec1,vec2),i))
  48.     distancelist.sort()
  49.     return distancelist
  50.  
  51. def knnestimate(data,vec1,k=3):
  52.     # Get sorted distances
  53.     dlist=getdistances(data,vec1)
  54.     avg=0.0
  55.  
  56.     # Take the average of the top k results
  57.     for i in range(k):
  58.         idx=dlist[i][1]
  59.         avg+=data[idx]['result']
  60.     avg=avg/k
  61.     return avg
  62.  
  63. def inverseweight(dist,num=1.0,const=0.1):
  64.     return num/(dist+const)
  65.  
  66. def subtractweight(dist,const=1.0):
  67.     if dist>const: return 0
  68.     else: return const-dist
  69.  
  70. def gaussian1(dist,sigma=10.0):
  71.     return math.e**(-(dist*10)**2/(2*sigma**2)) # I found two versions of gaussian
  72.  
  73. def gaussian(dist,sigma=10.0):
  74.     return math.e**(-dist**2/(2*sigma**2))
  75.  
  76.  
  77. def weightedknn(data,vec1,k=5,weightf=gaussian):
  78.     # Get distances
  79.     dlist=getdistances(data,vec1)
  80.     avg=0.0
  81.     totalweight=0.0
  82.  
  83.     # Get weighted average
  84.     for i in range(k):
  85.         dist=dlist[i][0]
  86.         idx=dlist[i][1]
  87.         weight=weightf(dist)
  88.         avg+=weight*data[idx]['result']
  89.         totalweight+=weight
  90.     if totalweight==0: return 0
  91.     avg=avg/totalweight
  92.     return avg
  93.  
  94. def dividedata(data,test=0.05):
  95.     def dd(data,test):
  96.         trainset=[]
  97.         testset=[]
  98.         for row in data:
  99.             if random()<test:
  100.                 testset.append(row)
  101.             else:
  102.                 trainset.append(row)
  103.         return trainset,testset
  104.     a = 1
  105.     while a==1:
  106.         trainset,testset = dd(data,test)
  107.         if len(trainset)!=0 and len(testset)!=0: a=2   # So we always return two valid sets
  108.     return trainset,testset
  109.  
  110.  
  111. def testalgorithm(algf,trainset,testset):
  112.     error=0.0
  113.     for row in testset:
  114.         guess=algf(trainset,row['input'])
  115.         error+=(row['result']-guess)**2
  116.     return error/len(testset)
  117.  
  118. def crossvalidate(algf,data,trials=100,test=0.05):
  119.     error=0.0
  120.     for i in range(trials):
  121.         trainset,testset=dividedata(data,test)
  122.         error+=testalgorithm(algf,trainset,testset)
  123.     return error/trials
  124.  
  125. def wineset2():
  126.     rows=[]
  127.     for i in range(300):
  128.         rating=random()*50+50
  129.         age=random()*50
  130.         aisle=float(randint(1,20))
  131.         bottlesize=[375.0,750.0,1500.0][randint(0,2)]
  132.         price=wineprice(rating,age)
  133.         price*=(bottlesize/750)
  134.         price*=(random()*0.9+0.2)
  135.         rows.append({'input':(rating,age,aisle,bottlesize),'result':price})
  136.     return rows
  137.  
  138. def rescale(data,scale):
  139.     scaledata=[]
  140.     for row in data:
  141.         scaled=[scale[i]*row['input'][i] for i in range(len(scale))]
  142.         scaledata.append({'input':scaled,'result':row['result']})
  143.     return scaledata
  144.  
  145. def createcostfunction(algf,data):
  146.     def costf(scale):
  147.         print "scale =",scale
  148.         sdata=rescale(data,scale)
  149.         return crossvalidate(algf,data,trials=10)
  150.     return costf       # Returns the function itself
  151.  
  152. weightdomain = [(0,10)]*4   # This can of course be optimized  [(0,10)] for example.
  153.  
  154. def wineset3():
  155.     rows=wineset1()
  156.     for row in rows:
  157.         if random()<0.5:
  158.             # Wine was bought at discount store
  159.             row['result']*=0.6
  160.     return rows
  161.  
  162. def probguess(data,vec1,low,high,k=5,weightf=gaussian):
  163.     dlist=getdistances(data,vec1)
  164.     nweight=0.0
  165.     tweight=0.0
  166.  
  167.     for i in range(k):
  168.         dist=dlist[i][0]
  169.         idx=dlist[i][1]
  170.         weight=weightf(dist)
  171.         v=data[idx]['result']
  172.  
  173.         # Is this point in the range?
  174.         if v>=low and v<=high:
  175.             nweight+=weight
  176.         tweight+=weight
  177.     if tweight==0: return 0
  178.  
  179.     # The probability is the weights in the range divided by all the weights
  180.     return nweight/tweight
Advertisement
Add Comment
Please, Sign In to add comment