实验——KNN的实现

import numpy as np

def loadData(filename):

    # 读取文件
    fr = open(filename)
    # 读取文件内容
    getFile = fr.readlines()
    # 获取文件行数
    lines = len(getFile)
    # 定义存放标签的列表
    lableMat = []
    # 定义一个空矩阵,存放特征值的列表
    emptyMat = np.zeros((lines,2))
    # 初始化索引
    index = 0
    # 通过迭代读取数据
    for line in getFile:
        # 将每一行的数据的空格或者换行符去掉
        lineArr = line.strip().split()
        # 逐行读取前三列数据
        #dataMat.append(lineArr[:3])
        emptyMat[index,:] = lineArr[:2]
        # 读取每一行的标签值(lineArr[-1]代表的是每一行最后一个元素)
        lableMat.append(int(lineArr[-1]))   # 为什么要转会出问题为int,因为我们的linArr[-1]是str类型,这里不类型转换后续操作
        # 索引值自增
        index += 1

    return emptyMat,lableMat





def dataNorm(dataSet):

    maxValue = dataSet.max(0)
    # print(maxValue)
    # 获取数据集中每一列的最小值
    minValue = dataSet.min(0)
    # print(minValue)
    # 最大值与最小值之间的差值
    diffs = maxValue - minValue
    # 获取dataSet行数
    num = dataSet.shape[0]   # num = 1000
    # 定义一个和DataSet一样大小的矩阵
    normData = np.zeros(dataSet.shape)
    # 数据归一化(使数据属于(0,1)之间)
    for i in range(num):
        # 采用的是最值归一化:x = (x - min) / (max - min)
        normData[i,: ] = (dataSet[i,:] - minValue) / diffs
    return diffs,normData,minValue
def classify(input,data,label,k):

    size = data.shape[0]
    # 作差 (其中np.tile(input,(size,1))作用是将input重复一次形成size大小的矩阵)
    diff = np.tile(input,(size,1)) - data
    # 求平方
    sqdiff = diff ** 2
    # 求和
    squreDiff = np.sum(sqdiff,axis=1)
    # 开根号
    dist = squreDiff ** 0.5
    sortDist = np.argsort(dist)
    # 对前k个最小距离点进行统计
    classCount = {}
    for i in range(k):
        voteLabel = label[sortDist[i]]
        # 对选取的前k个最小点的类别进行统计
        classCount[voteLabel] = classCount.get(voteLabel,0) + 1
    # 统计所选类别出现最多的
    maxCount = 0
    for key,value in classCount.items():
        if value > maxCount:
            maxCount = value
            classes = key
    return classes



def classifyTest(filepath):

    # 设置分类结果
    classResult = ['Romance','Action']#分类
    # 用户输入三维特征
    miles = float(input("of kicks:"))
    precentTats = float(input("kissse:"))
  
    # 将输入的特征存入到数组中
    inputs = np.array([miles,precentTats])
    # 处理数据
    dataMat,labelMat = loadData(filepath)
    # 训练集归一化
    diffs,normData,minValue = dataNorm(dataMat)
    # 测试集归一化
    normInput = (inputs - minValue) / diffs
    # 返回分类结果
    classify_result = classify(normInput,normData,labelMat,3)
    # 输出预测结果
    print("this movie may be %s" % (classResult[classify_result - 1]))




def dataTest(filepath):

    datingDataMat, datingLabels = loadData(filepath)
    # 取所有数据的百分之十
    hoRatio = 0.10
    # 数据归一化,返回归一化后的矩阵,数据范围,数据最小值
    ranges,normMat, minVals = dataNorm(datingDataMat)
    # 获得normMat的行数
    rows = normMat.shape[0]
    # 百分之十的测试数据的个数
    nums = int(hoRatio * rows)
    # 分类错误概率
    errorRate = 0
    for i in range(nums):
        classifyResult = classify(normMat[i,:],normMat[nums:rows,:],datingLabels[nums:rows],3)
        print("分类结果:%d\t真实类别:%d" % (classifyResult, datingLabels[i]))
        if classifyResult != datingLabels[i]:
            errorRate += 1
    print("错误率:%f%%" % (errorRate / float(nums) * 100))




if __name__ == '__main__':
    filepath = "你的数据集的地址 相对地址和绝对地址都可以"
    data,label = loadData(filepath)
    classifyTest(filepath)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值