lolamontes69

kdTree_nn.py for Machine Learning in Action - Chapter 2

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