k-近邻算法
---恢复内容开始---
k-近邻算法
2.1 算法优缺点
优点:精度高,对异常值不敏感,无数据输入假定。
缺点:计算复杂度高,空间复杂度高。
适用数据范围:数值型,标称型。
2.11-2.12 k-近邻算法的一般流程
算法:
def classify0(inX,dataSet,labels,k): dataSetSize = dataSet.shape[0] #样本维度 diffMat = tile(inX,(dataSetSize,1))-dataSet #创建一个(dataSetSize维度) sqDiffMat = diffMat**2 sqDistances = sqDiffMat .sum(axis=1) distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() #返回distances 从小到大的index classCount = {} #分类 for i in range(k): voteIlabel =labels[sortedDistIndicies[i]] #取出排K的分类 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #error dict[obj] 'int' object has no attribute 'get' sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse =True) #根据第二项进行降序排序 # classCount.iteritems() #返回迭代器方法同items() #items()方法是将字典中的每个项分别做为元组,添加到一个列表中,形成了一个新的列表容器。如果有需要也可以将返回的结果赋值给新变量,这个新的变量就会是一个列表数据类型。 print sortedClassCount #[('B', 2), ('A', 1)] return sortedClassCount[0][0] ''' a = [1,2,3] >>> b=operator.itemgetter(1) //定义函数b,获取对象的第1个域的值 >>> b(a) 2 >>> b=operator.itemgetter(1,0) //定义函数b,获取对象的第1个域和第0个的值 >>> b(a) (2, 1) 要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。 sorted函数 Python内置的排序函数sorted可以对list或者iterator进行排序,官网文档见:http://docs.python.org/2/library/functions.html?highlight=sorted#sorted,该函数原型为: sorted(iterable[, cmp[, key[, reverse]]]) 参数解释: (1)iterable指定要排序的list或者iterable,不用多说; (2)cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数,如: students为类对象的list,没个成员有三个域,用sorted进行比较时可以自己定cmp函数,例如这里要通过比较第三个数据成员来排序,代码可以这样写: students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] sorted(students, key=lambda student : student[2]) (3)key为函数,指定取待排序元素的哪一项进行排序,函数用上面的例子来说明,代码如下: sorted(students, key=lambda student : student[2]) key指定的lambda函数功能是去元素student的第三个域(即:student[2]),因此sorted排序时,会以students所有元素的第三个域来进行排序。 有了上面的operator.itemgetter函数,也可以用该函数来实现,例如要通过student的第三个域排序,可以这么写: sorted(students, key=operator.itemgetter(2)) sorted函数也可以进行多级排序,例如要根据第二个域和第三个域进行排序,可以这么写: sorted(students, key=operator.itemgetter(1,2)) 即先跟句第二个域排序,再根据第三个域排序。 (4)reverse参数就不用多说了,是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列。 '''
1,收集数据:可以使用任何方法。
2,准备数据:距离计算所需的数值,最好是结构化的数据格式。
def creatDataSet(): group = array([1.0,1.1],[1.0,1.0],[0,0],[0,0.1]) labels = ['A','A','B','B'] return group,labels
3,分析数据:可以使用任何方法。
4,训练算法:此步骤不适用k-近邻算法。
5,测试算法:测试错误率。
6,使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。
2.2.1 准备数据:从文本中解析数据
def file2matrix(filename): fr = open(filename) arrayOLines = fr.readlines() #读取文件 numberOfLines = len(arrayOLines) #得到文件行数 returnMat = zeros((numberOfLines,3)) #返回一个为0的矩阵 ''' zeros(shape[, dtype, order]) 依据给定形状和类型(shape[, dtype, order])返回一个新的元素全部为0的数组。 参数: shape:int或者ints元组; 定义返回数组的形状,形如:(2, 3)或2。 dtype:数据类型,可选。 返回数组的数据类型,例如:numpy.int8、默认为numpy.float64。 order:{‘C’, ‘F’},可选,返回数组为多维时,元素在内存的排列方式是按C语言还是Fortran语言顺序(row- or columnwise)。 输出:ndarray 给定形状,数据类型的数组。 ''' classLabelVector = [] index = 0 for line in arrayOLines: line = line.strip() listFromLine = line.split('\t') returnMat[index,:]=listFromLine[0:3] #每行前3个放入矩阵 classLabelVector.append(int(listFromLine[-1])) index+=1 return returnMat,classLabelVector
2.2.2 分析数据:使用Matplotlib创建散点图
import matplotlib import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) #绘制子图1行,1列,第一个 ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels)) #行,列,数据颜色 plt.show()
2.2.3 准备数据:归一化数值
公式:(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(maxVals, (m,1))-tile(minVals, (m,1))) return normDataSet,ranges,minVals
a.min()取a中最小值
a.min(0)区列中最小值
a.min(1)取行中最小值
2.2.4 测试算法
def datingClassTest(): hoRatio = 0.1 datingDataMat,datingLabels = file2matrix(r'C:\Users\home\Desktop\Django\rar\Ch02\datingTestSet2.txt') normMat,ranges,minVals = autoNorm(datingDataMat) m = normMat.shape[0] numTestVecs = int(m*hoRatio) errorCount = 0.0 #print numTestVecs for i in range(numTestVecs): #计算前numTestVecs个是否符合 classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m],3) if classifierResult!=datingLabels[i]: errorCount+=1.0 print 'toal error rate is %f'%(errorCount/float(numTestVecs)) #错误率
2.2.5 使用算法:构建完整可用系统
---恢复内容结束---
k-近邻算法
1,算法优缺点
优点:精度高,对异常值不敏感,无数据输入假定。
缺点:计算复杂度高,空间复杂度高。
适用数据范围:数值型,标称型。
2,k-近邻算法的一般流程
算法:
def classify0(inX,dataSet,labels,k): dataSetSize = dataSet.shape[0] #样本维度 diffMat = tile(inX,(dataSetSize,1))-dataSet #创建一个(dataSetSize维度) sqDiffMat = diffMat**2 sqDistances = sqDiffMat .sum(axis=1) distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() #返回distances 从小到大的index classCount = {} #分类 for i in range(k): voteIlabel =labels[sortedDistIndicies[i]] #取出排K的分类 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #error dict[obj] 'int' object has no attribute 'get' sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse =True) #从大到小概率高的排序 # classCount.iteritems() #返回迭代器方法同items() #items()方法是将字典中的每个项分别做为元组,添加到一个列表中,形成了一个新的列表容器。如果有需要也可以将返回的结果赋值给新变量,这个新的变量就会是一个列表数据类型。 print sortedClassCount #[('B', 2), ('A', 1)] return sortedClassCount[0][0] ''' a = [1,2,3] >>> b=operator.itemgetter(1) //定义函数b,获取对象的第1个域的值 >>> b(a) 2 >>> b=operator.itemgetter(1,0) //定义函数b,获取对象的第1个域和第0个的值 >>> b(a) (2, 1) 要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。 sorted函数 Python内置的排序函数sorted可以对list或者iterator进行排序,官网文档见:http://docs.python.org/2/library/functions.html?highlight=sorted#sorted,该函数原型为: sorted(iterable[, cmp[, key[, reverse]]]) 参数解释: (1)iterable指定要排序的list或者iterable,不用多说; (2)cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数,如: students为类对象的list,没个成员有三个域,用sorted进行比较时可以自己定cmp函数,例如这里要通过比较第三个数据成员来排序,代码可以这样写: students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] sorted(students, key=lambda student : student[2]) (3)key为函数,指定取待排序元素的哪一项进行排序,函数用上面的例子来说明,代码如下: sorted(students, key=lambda student : student[2]) key指定的lambda函数功能是去元素student的第三个域(即:student[2]),因此sorted排序时,会以students所有元素的第三个域来进行排序。 有了上面的operator.itemgetter函数,也可以用该函数来实现,例如要通过student的第三个域排序,可以这么写: sorted(students, key=operator.itemgetter(2)) sorted函数也可以进行多级排序,例如要根据第二个域和第三个域进行排序,可以这么写: sorted(students, key=operator.itemgetter(1,2)) 即先跟句第二个域排序,再根据第三个域排序。 (4)reverse参数就不用多说了,是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列。 '''
1,收集数据:可以使用任何方法。
2,准备数据:距离计算所需的数值,最好是结构化的数据格式。
def creatDataSet(): group = array([1.0,1.1],[1.0,1.0],[0,0],[0,0.1]) labels = ['A','A','B','B'] return group,labels
3,分析数据:可以使用任何方法。
4,训练算法:此步骤不适用k-近邻算法。
5,测试算法:测试错误率。
6,使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。