机器学习实战笔记第二章

mac2022-06-30  24

机器学习实战第二章

1、KNN算法概述

原理

在要分类的点周边寻找K个距离最近的点,其中出现最多的类别就作为新数据的分类。

优点
精度高对异常值不敏感无输入输假定
缺点
计算复杂度高空间复杂度高
简单举例
from numpy import * import operator #创建二维数组 group = array([[1.,1.1],[1.,1.],[0.,0.],[0.,0.1]]) labels = ['A','A','B','B']#目标向量 #定义KNN分类函数 #inx为要预测的向量 #dataSet为已知数据集 #labels为数据集的类别向量 #k为KNN选择的k值 def classify0(inx,dataSet,labels,k): dataSetSize = dataSet.shape[0]#得到 dataSet 的行数 diffMax = tile(inx,(dataSetSize,1))-dataSet#得到向量差值 #tile函数为重复函数 #tile(a,(1,2)) 复制a,1行2个a #tile(a,(2,1)) 复制a,2行1个a diffMaxSq = diffMax**2 diff = diffMaxSq.sum(axis=1) #sum() axis默认是None 全部相加 #axis=1时,列向量相加,最后得到一个列向量 #axis=0时,行向量相加,最后得到一个行向量 dif = diff**0.5 Num = dif.argsort()#距离从小到大的序号值 #argsort(dif)对数组排序得到从小到大的值对应的序号 #argsort(-dif)对数组排序得到从大到小的值对应的序号 res = {} for i in range(k): note = labels[Num[i]]#距离最小点的类别 res[note] = res.get(note,0) + 1#dic.get(note,0) 返回note的value值,如没有则返回默认值0 sortedClass = sorted(res.items(),key=operator.itemgetter(1),reverse=True) #dic.items()返回一个元组数组 #key=operator.itemgetter(1) 表示按照元组第二个元素排序 #reverse=True 表示逆序,即从大到小排列 return sortedClass[0][0]#最后返回出现次数最多的类别

简单举例2——约会网站

text.txt有1000行数据每行数据包括

每年获得的飞行常客里程数玩视频游戏所耗时间百分比每周消费的冰淇淋公升数海伦的感觉: (1)不喜欢的人(2)魅力一般的人 (3)极具魅力的人 通过这些数据利用KNN算法,向海伦推荐约会对象。 ''' 取名myknn.py ''' from numpy import * import operator ''' 定义KNN分类函数 inx为要预测的向量 dataSet为已知数据集 labels为数据集的类别向量 k为KNN选择的k值 ''' def classify0(inx,dataSet,labels,k): dataSetSize = dataSet.shape[0] diffMax = tile(inx,(dataSetSize,1))-dataSet diffMaxSq = diffMax**2 diff = diffMaxSq.sum(axis=1) dif = diff**0.5 Num = argsort(dif)#距离从小到大的序号值 res = {} for i in range(k): note = labels[Num[i]]#距离最小行的label res[note] = res.get(note,0) + 1#加入字典 sortedClass = sorted(res.items(),key=operator.itemgetter(1),reverse=True) return sortedClass[0][0] ''' 从txt文件中处理数据 ''' def file2matrix(filename): with open(filename) as fr: arrayOLines = fr.readlines() numberOfLines = len(arrayOLines) returnMat = zeros((numberOfLines,3))#存储特征 classLabelVector = []#存储目标 index = 0 for line in arrayOLines: line = line.strip() #strip('0')去除字符串首尾的‘0’,无参数时去除空格 listFromLine = line.split('\t')#以空格分割 returnMat[index,:] = listFromLine[0:3] if listFromLine[-1] == 'didntLike': classLabelVector.append(1) elif listFromLine[-1] == 'smallDoses': classLabelVector.append(2) elif listFromLine[-1] == 'largeDoses': classLabelVector.append(3) index += 1 return returnMat,classLabelVector#返回特征和目标 ''' 归一化函数 减最小值除以极差 ''' def autoNorm(dataSet): minVals = dataSet.min(axis=0) maxVals = dataSet.max(axis=0) ranges = maxVals - minVals#极差 normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals,(m,1))#减最小值 normDataSet = normDataSet/tile(ranges,(m,1)) return normDataSet,ranges,minVals#返回特征,极差,最小向量 #分类测试代码,测试数据占比百分之10 def datingClassTest(): hoRatio = 0.10 datingDataMat,datingLabels = file2matrix('text.txt') 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) ''' normMat[i,:]:要预测的向量 normMat[numTestVecs:m,:]:剩下的十分之九数据集 datingLabels[numTestVecs:m]:剩下十分之九目标 3:k值 ''' print('the classifier came back with: {},the real answer is: {}'\ .format(classifierResult,datingLabels[i]))#输出预测结果和实际 if(classifierResult != datingLabels[i]): errorCount += 1.0 print("the total error rate is:{}".format(errorCount/float(numTestVecs))) #交互 def classifyPerson(): resultList = ['not at all','in small doses','in large doses'] percentTats = float(input('percentage of time spent playing video games?')) ffMiles = float(input('frequent flier miles earned per year?')) icecream = float(input('liters of ice cream consumed per year?')) datingDataMat,datingLabels = file2matrix('text.txt') normMat,ranges,minVals = autoNorm(datingDataMat) inArr = array([ffMiles,percentTats,icecream])#还未归一化 classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3) print('You will probably like this person: {}'.format(resultList[classifierResult-1])) ''' test.py ''' import matplotlib import matplotlib.pyplot as plt fig = plt.figure()#生成新图片 ax = fig.add_subplot(111)#增加1行1列子图。画在1号上 ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*np.array(datingLabels),15.0*np.array(datingLabels)) plt.show() ''' python3中reload在importlib包中,需要导入才可使用 ''' import myknn import importlib importlib.reload(myknn)

简单举例3——数字识别

训练集由2000个TXT文本文件组成。单个文本由32*32的矩阵组成。因此需要创建一个由文本文件中读取出数组的函数。

def img2vector(filename): returnVect = zeros((1,1024))#将矩阵转换为一维数组 with open(filename) as fr: for i in range(32):#行数 lineStr = fr.readline() for j in range(32):#列数 returnVect[0,32*i+j] = int(lineStr[j]) return returnVect

接下来创建数字识别函数:

from os import listdir #为了得到文件夹下的所有文件的列表 def handingwritingClassTest(): hwLabels = []#存取训练集的目标 trainingFileList = listdir('MachineLearningInAction/Ch02/digits/trainingDigits') #得到文件夹下所有的txt文件列表 m = len(trainingFileList) trainingMat = zeros((m,1024))#创建m*1024数组存取所有的txt文件 for i in range(m): fileNameStr = trainingFileList[i] fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) hwLabels.append(classNumStr)#得到文件对应的目标 trainingMat[i,:] = img2vector('MachineLearningInAction/Ch02/digits/trainingDigits/{}'.format(fileNameStr)) #调用函数存入一个txt ''' 接下来处理测试集+调用分类函数(原约会网站的) ''' testFileList = listdir('MachineLearningInAction/Ch02/digits/testDigits') errorCount = 0.0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) vectorUnderTest = img2vector('MachineLearningInAction/Ch02/digits/testDigits/{}'.format(fileNameStr)) classifyResult = classify0(vectorUnderTest,trainingMat,hwLabels,3) print('the classifier came back with: {},the real answer is: {}'\ .format(classifyResult,classNumStr)) if(classifyResult != classNumStr): errorCount += 1.0 print("the total error rate is:{}".format(errorCount/float(mTest)))
最新回复(0)