KNN近邻算法预测爱的程度

基本上把一些点都注释了,使用的原始数据是在网上找的
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import operator
from os import listdir
# 设置在图像中可以使用中文
from matplotlib.font_manager import FontProperties

font_set = FontProperties(fname=r'simsun.ttc', size=15)


def file_matrix(filename):
    """处理文件内容,输出处理成矩阵和类标签向量"""
    fr = open(filename)
    fr1 = np.genfromtxt(filename, delimiter='\t', dtype=str, skip_header=0)
    # 每一行对象
    # print(fr1)
    array_lines = fr.readlines()
    # 总行数
    number_oflines = len(array_lines)
    # print(arrayOlines)
    # print(number_oflines)
    # 返回一个给定形状和类型的用0填充的数组
    # 参数:shape:形状,dtype:可选参数,默认numpy.float64
    # order:可选,c代表行优先,f代表列优先
    return_mat = np.zeros((number_oflines, 3))
    class_label_vector = []
    index = 0
    for line in array_lines:
        # 移除每行开头结尾的空格
        line = line.strip()
        # 切割字符串
        list_fromline = line.split('\t')
        # print(list_fromline)
        # 替换掉为0的数据
        return_mat[index, :] = list_fromline[0:3]
        # print(return_mat[index,:])
        # 将航班号存储到列表中
        class_label_vector.append(int(list_fromline[-1]))
        index += 1
    return return_mat, class_label_vector


def matplotlib_(data):
    # 利用原始数据制作散点图
    # 创建一个名为figure的画图窗口
    fig = plt.figure()
    # 添加子图,111是默认参数,用来设定大小
    ax = fig.add_subplot(111)
    # 在子图中画scatter散点图
    ax.scatter(data[:, 0], data[:, 1])
    # 设置可以显示中文字体
    ax.set_ylabel(u'看电影的次数', fontproperties=font_set)
    ax.set_xlabel(u'玩视频游戏所耗的时间百分比', fontproperties=font_set)
    plt.show()


def auto_norm(dataset):
    """在原始数据的继承上归一化数据"""
    # 取出矩阵中最小的数,参数0使得取得的从列中取出最小值
    min_vals = dataset.min(0)
    # print(min_vals)
    # 取出矩阵中最大的数
    max_vals = dataset.max(0)
    ranges = max_vals - min_vals
    # 用0来填充矩阵
    norm_dataset = np.zeros(np.shape(dataset))
    # print(norm_dataset)
    # 取出行数
    m = dataset.shape[0]
    # print(m)
    # 归一化公式:n e w V a l u e = {o l d V a l u e - m i n ) / (max-min)
    # np.tile将min_vals 这个矩阵的列复制m次
    norm_dataset = dataset - np.tile(min_vals, (m, 1))
    norm_dataset = norm_dataset / np.tile(ranges, (m, 1))
    return norm_dataset, ranges, min_vals


def classify0(inX, dataSet, labels, k):
    # 用来测试的行数,inx 当前一行矩阵,dataset用来测试的数据(后500行),labels分类结果,k是取前几个值来预判
    dataSetSize = dataSet.shape[0]
    # 复制当前行数,在减去以前求得的最小值
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    # 平方
    sqDiffMat = diffMat ** 2
    # 求和
    sqDistances = sqDiffMat.sum(axis=1)
    # 根号处理
    distances = sqDistances ** 0.5
    # y|{0 - 67)2 + (20 000 - 32 000)2 + (1 • 1 — 0.1)2
    # argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出到sortedDistIndicies
    sortedDistIndicies = distances.argsort()
    classCount = {}
    for i in range(k):
        # 取出与当前值误差最小的3个值,来作为预测的结果
        voteIlabel = labels[sortedDistIndicies[i]]
        # 生成字典键,默认值为0
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    # py2和py3中字典的处理方式不同,3中是items(),reverse,默认是flase,由小到大,True由大大小,
    # key是选取value来判断,写成lambda item:item[0]结果一样,可以接受的是一个函数
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    # 返回结果中出现次数多的那个当结果
    return sortedClassCount[0][0]


def dating_classtest():
    # 分类器测试
    # 用来预测的原始数据
    horario = 0.5
    # 初始化数据
    data, data_list = file_matrix('datingTestSet2.txt')
    norm_dataset, ranges, min_vals = auto_norm(data)

    # 取行
    m = norm_dataset.shape[0]
    num_test_vecs = int(m * horario)
    # 初始化错误次数
    error_count = 0.0
    for i in range(num_test_vecs):
        # 调用classify0判断预测结果
        class_ifier_result = classify0(norm_dataset[i, :], norm_dataset[num_test_vecs:m, :], data_list[num_test_vecs:m],
                                       3)
        print('正确结果是%d,预测的是%d' % (class_ifier_result, data_list[i]))
        if (class_ifier_result != data_list[i]):
            error_count += 1
    print("这次预测的正确率是%.2f%%" % ((1-(error_count) / float(num_test_vecs))*100))


data,list1 = file_matrix('datingTestSet2.txt')

matplotlib_(data)
# norm_dataset,ranges,c = auto_norm(data)
# print(a)
# dating_classtest()
def classify_person():
    result_list = ['一点点','很喜欢','爱']
    ff_miles = float(input("请输入一年的出差里数:"))
    peroent_tabs = float(input("玩视频游戏所耗的时间百分比:"))
    ice_creame = float(input("请输入两个人一起看电影的次数:"))
    data, data_list = file_matrix('datingTestSet2.txt')
    norm_dataset, ranges, min_vals = auto_norm(data)
    in_arr = np.array([ff_miles,peroent_tabs,ice_creame])
    # print(in_arr)
    # print(type(peroent_tabs))
    # print(type(min_vals))
    # print(type(ranges))
    data1 = (in_arr-min_vals)/ranges
    classifier_result = classify0(data1,norm_dataset,data_list,3)
    print("喜欢的程度:",result_list[classifier_result-1])

# classify_person()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值