机器学习实战-改进约会网站的配对(knn算法)

 (0)knn算法

from numpy import *
import operator
def classify0(intx,dataset,labels,k):
    dataSetSize=dataset.shape[0] #ndarray.shape 数组的维度,对于矩阵,n行m列
    diffMat=tile(intx,(dataSetSize,1))-dataset #tile(A,(a,b))对于矩阵A在行方向上重复a次,列方向上重复b次
    sqDiffMat=diffMat**2        #对每一个维度进行平方
    sqDistances=sqDiffMat.sum(axis=1)   #np.sum(a, axis=0)的含义是a[0][j],a[1][j],a[2][j](j=0,1,2,3)对应行项相加的结果
    distances=sqDistances**0.5          #np.sum(a, axis=1)的含义是a[i][0],a[i][1],a[i][2],a[i][3](i=0,1,2)对应列项相加的结果
    sortedDistIndicies=distances.argsort() #numpy.argsort() 函数返回的是数组值从小到大的索引值,索引值从0开始
    classCount = {}
    #print(type(classCount))
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    # 排序
    #如果items()替换为iteritems()则会报错
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

(1)收集数据:收集文本信息

(2)准备数据:解析文本文件内容,将其信息矩阵化、向量化

from numpy import *
import operator
def file2matrix(filename):
    labels = {'didntLike': 1, 'smallDoses': 2, 'largeDoses': 3}
    fr=open(filename)               #打开文件
    arrayOLines=fr.readlines()      #读取文件所有行
    numberOfLines=len(arrayOLines)  #计算文件行数
    returnMat=zeros((numberOfLines,3))   #为numberoflines行,3列的矩阵填充0元素
    classLabelVector=[]                  #创建标记向量
    index=0
    for line in arrayOLines:     #获取每一行的文本信息
        line=line.strip()         #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
        listFromLine=line.split('\t')#以\t对字符串进行切片
        returnMat[index,:]=listFromLine[0:3]  #取每一行的前三个元素放到列表(矩阵)内
        classLabelVector.append(labels[listFromLine[-1]])#向classlabel内添加标记,并用自字典返回键值对的值,标记在每一行最后一个
        index+=1                                           #取下一行
    return  returnMat,classLabelVector

(3)分析数据:使用matplotlib画二维扩散图

import knn
from numpy import *
import matplotlib
import matplotlib.pyplot as plt
datingDataMat,datingLabels=knn.file2matrix('datingTestSet.txt')
fig=plt.figure()       #创建自定义图像
ax=fig.add_subplot(111) #add_subplot可以为figure新增111个划分子图
#print(datingLabels)
#print(type(datingLabels))
#print(type(datingDataMat))
ax.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels))
#标记数据点的属性类别
plt.show()

(4)数据处理:使用归一化,处理不同取值范围的特征值,将取值范围处理到0到1或-1到1

import knn
from numpy import *
def autoNorm(dataset):
    # print(a.min())  # 无参,所有中的最小值
    # print(a.min(0))  # axis=0; 每列的最小值
    # print(a.min(1))  # axis=1;每行的最小值
    minvals=dataset.min(0) #每一属性下的最小值元素,共3列,3*1
    maxvals=dataset.max(0) #每一属性下的最大值元素
    tmprange=maxvals-minvals
    normDataSet=zeros(shape(dataset))#shape()计算数组的维度n行m列,以0元素填充n行m列的矩阵
    m=dataset.shape[0]    #计算行数;nuarray.shape[0]代表行数,nuarray.shape[1]代表列数
    normDataSet=dataset-tile(minvals,(m,1))  #复制minvals向量m行1列
    normDataSet=normDataSet/tile(tmprange,(m,1))#复制tmprange向量m行1列,归一化
    return normDataSet,tmprange,minvals

(5)测试算法:根据测试样本计算算法性能

import knn
import dataProcessing
import knnAlgorithm
from numpy import *
datingDataMat,datingLabels=knn.file2matrix('datingTestSet.txt')
normalMat,tmprange,minvals=dataProcessing.autoNorm(datingDataMat)
def datingClassTest():
    ratio=0.10      #测试样本占整体样本的比例
    m=normalMat.shape[0]#计算整体样本的行数
    numTestVecs=int(m*ratio)#计算测试样本
    print(numTestVecs)
    errorcount=0
    for i in range(numTestVecs):
        classifierResult=knnAlgorithm.classify0(normalMat[i,:],normalMat[numTestVecs:m,:],datingLabels[numTestVecs:m],4)

        #print("xx")
        str='the classifier came back with: '+repr(classifierResult)+",the real answer is :"+repr(datingLabels[i])
        print(str)
        if(classifierResult!=datingLabels[i]):   #获取算法性能
            errorcount+=1.0
    errorRate=errorcount/numTestVecs
    print(errorRate)

datingClassTest()

(6)预测样本


import knn
import dataProcessing
import knnAlgorithm
from numpy import *
import operator
datingDataMat,datingLabels=knn.file2matrix('datingTestSet.txt')
normalMat,tmprange,minvals=dataProcessing.autoNorm(datingDataMat)
def classifyPerson():
    resultList=["不感兴趣","有一点兴趣","有极大兴趣"]
    percentFilms=float(input("玩游戏的时间占比"))
    ffmiles=float(input("你每年飞多少里程"))
    icecream=float(input("吃冰淇淋的数量"))
    inarray=array([ffmiles,percentFilms,icecream])

    inarray=(inarray-minvals)/tmprange
    classifierResult=knnAlgorithm.classify0(inarray,datingDataMat,datingLabels,4)
    print(classifierResult)
    print("对你"+resultList[classifierResult-1])
classifyPerson()

 

 

 

posted @ 2019-10-31 21:15  Whiterwater  阅读(430)  评论(0)    收藏  举报