lolamontes69

kdTree_knn.py for Machine Learning in Action: Chapter 2.

Oct 12th, 2013
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.50 KB | None | 0 0
  1. """ Machine Learning in Action - Chapter 2.  kdTree_knn.
  2.    A very simple implementation of a kdtree_nn search based around the wikipedia
  3.    python example for kdtrees with an added search method.
  4.    If an exact match is found it returns the result, if not it performs knn
  5.    for the result.
  6. """
  7.  
  8. from operator import itemgetter
  9. from math import *
  10.  
  11. class Node:
  12.     def __init__(self,location,result,left_child,right_child):
  13.         self.location=location
  14.         self.result=result
  15.         self.lc=left_child
  16.         self.rc=right_child
  17.  
  18.  
  19. def kdtree(point_list, depth=0):
  20.     try:
  21.         k = len(point_list[0])
  22.     except IndexError as e:
  23.         return None
  24.     axis = depth % k
  25.     point_list.sort(key=itemgetter(axis))
  26.     median = len(point_list) // 2                  # choose median
  27.     return Node(location=point_list[median][0],
  28.                 result=point_list[median][1],
  29.                 left_child=kdtree(point_list[:median], depth + 1),
  30.                 right_child=kdtree(point_list[median + 1:], depth + 1))
  31.  
  32. def file2matrix(filename):
  33.     returnMat=[]
  34.     classLabelVector = []
  35.     fr = open(filename)
  36.     for line in fr.readlines():
  37.         line = line.strip()
  38.         listFromLine = line.split('\t')
  39.         returnMat.append(listFromLine[0:3])
  40.         classLabelVector.append(str(listFromLine[-1]))
  41.     return returnMat, classLabelVector
  42.  
  43. def pearson(v1a, v2a):
  44.     v1=[float(a) for a in v1a]
  45.     v2=[float(a) for a in v2a]
  46.     sum1 = sum(v1)
  47.     sum2 = sum(v2)
  48.     sum1Sq = sum([pow(v, 2) for v in v1])
  49.     sum2Sq = sum([pow(v, 2) for v in v2])
  50.     pSum = sum([v1[i]*v2[i] for i in range(len(v1))])
  51.     num = pSum-(sum1*sum2/len(v1))
  52.     den = sqrt((sum1Sq-pow(sum1, 2)/len(v1))*(sum2Sq-pow(sum2, 2)/len(v1)))
  53.     if den == 0: return 0
  54.     return 1.0-num/den
  55.  
  56. def search_nn(query,tree,lowd=500000,nearest=[(500000,"frogs")],distance=pearson,k=4):
  57.     res, childdist, childres = "frogs", 500000, "frogs"
  58.  
  59.     # if we already have a winrar
  60.     if (tree.location==None) or lowd==0: return 500000, "frogs", nearest
  61.  
  62.     # parent
  63.     dist=distance(query,tree.location)
  64.     if dist==0: return dist, tree.result, nearest
  65.     elif dist<0: dist = (dist-dist-dist)
  66.     if dist<lowd:
  67.         lowd=dist
  68.         res=tree.result
  69.     if len(nearest)<k:
  70.         nearest.append((dist,tree.result))
  71.     elif dist<max(nearest):
  72.         nearest[nearest.index(max(nearest))]=(dist,tree.result)
  73.        
  74.     # children
  75.     if tree.lc == None:
  76.         if tree.rc == None: pass
  77.         else: childdist, childres, nearest = search_nn(query,tree.rc,lowd,nearest)
  78.     elif tree.rc == None:
  79.         if tree.lc == None: pass
  80.         else: childdist, childres, nearest = search_nn(query,tree.lc,lowd,nearest)
  81.     else:
  82.         childdist, childres, nearest = search_nn(query,tree.lc,lowd,nearest)
  83.         if childdist<lowd: lowd, res =childdist, childres
  84.         childdist, childres, nearest = search_nn(query,tree.rc,lowd,nearest)
  85.     if childdist<lowd: lowd, res =childdist, childres
  86.     return lowd, res, nearest
  87.  
  88. def main():
  89.     datingDataMat, datingLabels = file2matrix('datingTestSet.txt')
  90.     point_list=[]
  91.     for a in range(len(datingDataMat)):
  92.         point_list.append([list(datingDataMat[a]),datingLabels[a]])
  93.     tree = kdtree(point_list)
  94.     while 1:
  95.         percentTats = float(raw_input("Percentage of time spent playing Video Games? >"))
  96.         ffMiles = float(raw_input("Frequent flier miles earned per year? >"))
  97.         iceCream = float(raw_input("Liters of ice cream consumed per year? >"))
  98.         lowd, res, nearest=search_nn([ffMiles,percentTats, iceCream],tree)
  99.         if lowd!=0:
  100.             dict1, hi, res = {}, 0, ""
  101.             for a in nearest:
  102.                 if a[1] not in dict1: dict1[a[1]]=1
  103.                 else: dict1[a[1]]+=1
  104.             for a in dict1:
  105.                 if dict1[a]>hi: hi,res = dict1[a], a
  106.             print "Using knn..."
  107.         print "You will probably like this person: ",res
  108.         print "-"*44
  109.         another=raw_input('Classify another?(y/n) >')
  110.         if another=='n': break
  111.         print "-"*44
  112.  
  113. def test():
  114.     datingDataMat, datingLabels = file2matrix('datingTestSet.txt')
  115.     point_list=[]
  116.     for a in range(len(datingDataMat)):
  117.         point_list.append([list(datingDataMat[a]),datingLabels[a]])
  118.     tree = kdtree(point_list)
  119.     # test each item in the dataset to see if it returns zero distance
  120.     test_list=[]
  121.     for a in point_list:
  122.         print search_nn(a[0],tree),' ',
  123.  
  124. if __name__ == "__main__":
  125.     main()
Add Comment
Please, Sign In to add comment