栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Python

k-近邻算法实现约会网站配对效果

Python 更新时间:发布时间: 百科书网 趣学号



前言

提示:机器学习第一次作业。


提示:以下是本篇文章正文内容,下面案例可供参考


一、KNN算法原理?

 1.1算法介绍

KNN的全称是K Nearest Neighbors,意思是K个最近的邻居。K个最近邻居,毫无疑问,K的取值肯定是至关重要的。KNN的原理就是当预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别。

 图中绿色的点就是我们要预测的那个点,假设K=3。那么KNN算法就会找到与它距离最近的三个点(这里用圆圈把它圈起来了),看看哪种类别多一些,比如这个例子中是蓝色三角形多一些,新来的绿色点就归类到蓝三角了。当k=5时,判定结果就不一样了,这次变成红圆多一些,所以新来的绿点被归类成红圆。从这个例子中,我们就能看得出K的取值是很重要的。


1.2K值的选取和点距离的计算

二维平面两点间的距离:A(x1,y1),B(x2,y2)

若扩展到多维:

如何确定K取多少值好呢?答案是通过交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如6:4拆分出部分训练数据和验证数据),从选取一个较小的K值开始,不断增加K的值,然后计算验证集合的方差,最终找到一个比较合适的K值。


二、代码实现


1.在约会网站上使用k-近邻算法的步骤
(1) 收集数据:提供文本文件。
(2) 准备数据:使用Python解析文本文件。
(3) 分析数据:使用Matplotlib画二维扩散图。
(4) 训练算法:此步骤不适用于k-近邻算法。
(5) 测试算法:使用海伦提供的部分数据作为测试样本。测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
(6) 使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。


2.准备数据:从文本文件中解析数据

在kNN.py中创建名为file2matrix的函数,以此类处理输入格式问题。该函数的输入为文件名字符串,输出为训练样本矩阵和类标签向量。代码如下:

#输入为文件名字符串,输出为训练样本矩阵和类标签向量
def file2matrix(filename):
    '''
    函数作用:从文件中读入训练数据,并且存储为矩阵
    :param filename:文件名字符串
    :return:训练样本矩阵和类标签向量
    '''
    fr = open(filename)                     #打开文件
    arrayOLines = fr.readlines()            #读取文件内容
    numberOflines = len(arrayOLines)        #得到文件行数
    returnMat = zeros((numberOflines,3))    #返回解析后的数据
    classLabelVector = []                   #定义类标签向量
    index = 0
    for line in arrayOLines:
        line = line.strip()                       #截取掉所有的回车字符
        listFromLine = line.split('t')           #用‘t’将行数据分割成元素列表
        returnMat[index,:] = listFromLine[0:3]    #选取前三个数据将他们存储到特征矩阵中
        classLabelVector.append(int(listFromLine[-1]))    #把该样本对应的标签放置标签向量,顺序与样本集对应
        index += 1
    return returnMat,classLabelVector
2.分析数据:使用Matplotlib创建散点图

(1)原始数据的散点图

import matplotlib
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
    '''
    散点图使用datingDataMat矩阵的第二,第三列数据,分别表示特征值“玩视频游戏所耗时间百分比”
    和“每周所消费的冰淇凌公升数”
    '''
    #无样本类别标签的约会数据散点图
    ax.scatter(datingDataMat[:,1],datingDataMat[:,2])
    #加入这两行可以避免plt画图报找不到字体的错误,这样就可以输出中文字体
    plt.rcParams['font.sans-serif']=['SimHei']  #显示中文标签
    plt.rcParams['axes.unicode_minus']=False
    plt.xlabel('玩视频游戏所耗时间百分比')
    plt.ylabel('每周消费的冰淇淋公升数')
    plt.show()

原始数据散点图难以辨识图中的点究竟属于哪个分类

 (2)带有分类标签的约会数据散点图

#带有分类标签的约会数据散点图
    ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))

 (3)改进带有分类标签散点图

import numpy as np
    dating_data_mat, dating_labels = kNN.file2matrix('datingTestSet2.txt')
    fig = plt.figure()
    ax = fig.add_subplot(111)
    dating_labels = np.array(dating_labels)
    idx_1 = np.where(dating_labels == 1)
    p1 = ax.scatter(dating_data_mat[idx_1, 0], dating_data_mat[idx_1, 1], marker='o', color='r', label='不喜欢', s=30)
    idx_2 = np.where(dating_labels == 2)
    p2 = ax.scatter(dating_data_mat[idx_2, 0], dating_data_mat[idx_2, 1], marker='o', color='g', label='魅力一般', s=45)
    idx_3 = np.where(dating_labels == 3)
    p3 = ax.scatter(dating_data_mat[idx_3, 0], dating_data_mat[idx_3, 1], marker='o', color='b', label='极具魅力', s=60)
    plt.legend(loc='upper left')
    plt.xlabel("每年获取的飞行常客历程数")
    plt.ylabel("玩游戏所耗时间百分比")
    plt.show()

 3.准备数据:归一化数值

在处理这种不同取值范围的特征值时,我们通常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。

#归一化特征值,将数字特征值转化为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))
    return normDataSet,ranges,minVals
 4.测试算法:作为完整程序验证分类器
#分类器针对约会网站的测试代码
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)))
5.使用算法:构建完整可用系统
def classifyPerson():
    #类标签列表
    resultlist = ['讨厌', '一般喜欢', '非常喜欢']
    #用户输入不同特征值
    precentTats = float(input("玩视频游戏所占时间百分比?"))
    ffMiles = float(input("每年获得的飞行常客里程数?"))
    iceCream = float(input("每周消费的冰淇淋公升数?"))
    #打开文件并处理数据
    datingDataMat,datingLabels = kNN.file2matrix('datingTestSet2.txt')
    normMat, ranges, minVals = autonorm(datingDataMat)            #归一化训练集
    inArr = np.array([precentTats, ffMiles, iceCream])            #创建测试集数组
    norm_in_arr = (inArr - minVals) / ranges                      #归一化测试集
    # 返回分类结果
    classifierResult = classify0(norm_in_arr, normMat, datingLabels, 3)  #返回分类结果
    #输出结果
    print("你对这个人的感觉可能是: ", resultList[classifierResult - 1])

实现结果:


 


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

注:以上代码均来自机器学习实战。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/293735.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号