对机器学习实战的课本和代码进行精读,帮助自己进步。
#coding:utf-8 from numpy import * import operator #运算符模块 from os import listdir #os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。这个列表以字母顺序。 它不包括 ‘.‘ 和‘..‘ 即使它在文件夹中。 #创建数据集和标签 def createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) #数据集 #python中的list是python的内置数据类型,list中的数据类不必相同的,而array的中的类型必须全部相同。在list中的数据类型保存的是数据的存放的地址,简单的说就是指针,并非数据,这样保存一个list就太麻烦了,例如list1=[1,2,3,‘a‘]需要4个指针和四个数据,增加了存储和消耗cpu。 labels = [‘A‘,‘B‘,‘C‘,‘D‘] #标签 return group,labels #实施KNN算法 #欧氏距离公式:欧几里得度量(euclidean metric)(也称欧氏距离)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离 def classify0(inX, dataSet, labels, k): #inX:用于分类的输入向量; dataSet:输入的训练样本集; labels:标签向量; k:选择最近邻居的数目 dataSetSize = dataSet.shape[0] #shape函数它的功能是读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度。它的输入参数可以使一个整数表示维度,也可以是一个矩阵。 diffMat = tile(inX, (dataSetSize,1)) - dataSet #他的功能是重复某个数组。比如tile(A,n),功能是将数组A重复n次,构成一个新的数组 sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) #平时用的sum应该是默认的axis=0 就是普通的相加 ,而当加入axis=1以后就是将一个矩阵的每一行向量相加 distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() #sort函数只定义在list中,sorted函数对于所有的可迭代序列都可以定义. #argsort()函数,是numpy库中的函数,返回的是数组值从小到大的索引值. classCount={} for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #key:用列表元素的某个属性和函数进行作为关键字,有默认值,迭代集合中的一项 #reverse:排序规则. reverse = True 或者 reverse = False,有默认值。返回值:是一个经过排序的可迭代类型 #operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号) return sortedClassCount[0][0] #step01 :因为直接用的人家的文件,所以我们这一步没有收集数据,我们可以用python爬虫进行海里数据收集 #step02 : 准备数据:从文本文件中解析数据,得到距离计算所需要的数值 def file2matrix(filename): fr = open(filename) #打开文件,赋值给fr numberOfLines = len(fr.readlines()) #get the number of lines in the file returnMat = zeros((numberOfLines,3)) #创建给定类型的矩阵,并初始化为0,另一维度设置为固定数值3 classLabelVector = [] fr.close() #有打开就要有关闭 fr = open(filename) index = 0 for line in fr.readlines(): #.readline() 和 .readlines() 之间的差异是后者一次读取整个文件,象 .read() 一样。.readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for ... in ... 结构进行处理。另一方面,.readline() 每次只读取一行,通常比 .readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 .readline() line = line.strip() #截取掉所有的回车字符。 listFromLine = line.split(‘\t‘) #使用tab字符\t将上一步得到的整行数据分割成一个列表 returnMat[index,:] = listFromLine[0:3] #选取前三个元素,将它们存储到特征矩阵中 classLabelVector.append(int(listFromLine[-1])) #将列表中最后一列存储到向量classLabelVector中 index += 1 fr.close() return returnMat,classLabelVector #step02: 准备数据:归一化数值 #在处理这种不同取值范围的特征值时,我们通常采用的方法是将数值归一化 #newvalue = (oldValue-min)/(max-min) 将任意取值范围的特征值转化为0到1区间的值 def autoNorm(dataSet): minVals = dataSet.min(0) #从列中选取最小值,而不是当前行的最小值 maxVals = dataSet.max(0) ranges = maxVals - minVals #算出来数值范围 normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals, (m,1)) normDataSet = normDataSet/tile(ranges, (m,1)) #element wise divide return normDataSet, ranges, minVals #step03 :分析数据:使用Matplotlib创建散点图 #step04: 测试算法:作为完整程序验证分类器 def datingClassTest(): hoRatio = 0.50 #hold out 10% datingDataMat,datingLabels = file2matrix(‘./datingTestSet2.txt‘) #load data setfrom file normMat, ranges, minVals = autoNorm(datingDataMat) m = normMat.shape[0] numTestVecs = int(m*hoRatio) errorCount = 0.0 for i in range(numTestVecs): classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3) print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]) if (classifierResult != datingLabels[i]): errorCount += 1.0 print "the total error rate is: %f" % (errorCount/float(numTestVecs)) print errorCount #step05 使用算法:构建完整可用系统 def classifyPerson(): resultList = [‘not at all‘,‘in small doses‘,‘in large doses‘] percentTats = float(raw_input("percentage of time spent palying video games?")) ffMiles = float(raw_input("freguent filer miles earned per year?")) iceCream = float(raw_input("liters of ice cream consumed per year?")) datingDataMat,datingLabels = file2matrix(‘./datingTestSet2.txt‘) normMat,ranges,minVales = autoNorm(datingDataMat) inArr = array([ffMiles,percentTats,iceCream]) classifierResult = classify0((inArr - minVales)/ranges,normMat,datingLabels,3) print "you will probably like this person:",resultList[classifierResult -1]
重点:
01:K-近邻算法底层算法是欧式距离公式,计算m维空间中两点之间的真实距离,或者向量的自然长度。
02:归一化数值:
newvalue = (oldValue-min)/(max-min) 将任意取值范围的特征值转化为0到1区间的值
这个思想很重要。
体会:在我看来,整个机器学习从数据采集到最终的程序,整个流程特别重要,算法是核心,处理干扰项的时候,我们用到了归一化。
时间: 2024-10-10 22:45:28