关闭

python-手写knn(k Nearest Neighbor) k近邻算法

标签: pythonknn机器学习
176人阅读 评论(0) 收藏 举报
分类:

先上代码 附上测试集

!!!


# -*- coding:utf-8 -*-

import csv
import random
import math
import operator

# 文件名 分割比例  训练集 测试集
def loadDate(fileName, split, trainSet=[], testSet=[]):
    with open(fileName, 'rb') as csvfile:
        lines = csv.reader(csvfile)
        dataSet = list(lines)

        for i in range(len(dataSet)):  # 数值类型转化 以及分组
            for j in range(4):
                dataSet[i][j] = float(dataSet[i][j])
            if random.random() < split:
                testSet.append(dataSet[i])
            else:
                trainSet.append(dataSet[i])



# dimension-维度 计算两点的距离 拓展带各个维度
def calDistance(point, point2, dimension):
    distance = 0.0
    for i in range(dimension):  # 各个维度计算
        distance += pow((point[i] - point2[i]), 2)
    return math.sqrt(distance)


# 返回k近邻list
def getNeighbors(trainSet, testSingle, k):  # 训练集 测试实例  k临近
    distance = []
    length = len(testSingle) - 1
    for i in range(len(trainSet)):  # 与每个训练元素计算距离排序
        dist = calDistance(testSingle, trainSet[i], length)
        distance.append((trainSet[i], dist))  # distance 存放 对比的实例 与 两点距离
    distance.sort(key=operator.itemgetter(1))  # 对第二个元素(距离)排序
    
    neighbors = []
    for i in range(k):  # 前k个
        neighbors.append(distance[i][0])
    return neighbors


# 从前k个最近的点中找出预测答案 预测答案在训练集中
def getResponse(neighbors):
    dict = {}  # 字典中的答案 计数
    for i in range(len(neighbors)):
        ans = neighbors[i][-1]  # 训练数据中最后一个是预测答案
        if ans in dict:
            dict[ans] += 1
        else:
            dict[ans] = 1
    sortVec = sorted(dict.iteritems(), key=operator.itemgetter(1), reverse=True)  # 排序k个中出现次数最多的作为ans
    return sortVec[0][0]


 # 测试 与 预测比对正确率
def getOk(testSet, preSet):
    correct = 0
    for i in range(len(testSet)):
        if testSet[i][-1] == preSet[i]:
            correct += 1
    return (correct / float(len(testSet))) * 100.0


if __name__ == '__main__':

    trainSet = []  # 训练集
    testSet = []   # 测试集
    split = 0.67   # 分割比例  可以来自两个文件 可以不需要分割
    k = 1          # ~~k近~~
    preAnsSet = []    # 预测结果

    loadDate(r'F:\knnData.txt', split, trainSet, testSet)
    for i in range(len(testSet)):
        neighbors = getNeighbors(trainSet, testSet[i], k)  # 测试每个testSet与trainSet的最近的k个点
        res = getResponse(neighbors)  # 得到预测结果答案
        preAnsSet.append(res)

    acc = getOk(testSet, preAnsSet)  # 得到准确率
    print len(testSet)
    print len(trainSet)  # 各种数据集大小
    print ("ok rate %.2f%%") % acc  # ac率

"""
前四列是坐标,最后一列是答案:分类
F:\knnData.txt

5.1,3.5,1.4,0.2,0
4.9,3. ,1.4,0.2,0
4.7,3.2,1.3,0.2,0
4.6,3.1,1.5,0.2,0
5. ,3.6,1.4,0.2,0
5.4,3.9,1.7,0.4,0
4.6,3.4,1.4,0.3,0
5. ,3.4,1.5,0.2,0
4.4,2.9,1.4,0.2,0
4.9,3.1,1.5,0.1,0
5.4,3.7,1.5,0.2,0
4.8,3.4,1.6,0.2,0
4.8,3. ,1.4,0.1,0
4.3,3. ,1.1,0.1,0
5.8,4. ,1.2,0.2,0
5.7,4.4,1.5,0.4,0
5.4,3.9,1.3,0.4,0
5.1,3.5,1.4,0.3,0
5.7,3.8,1.7,0.3,0
5.1,3.8,1.5,0.3,0
5.4,3.4,1.7,0.2,0
5.1,3.7,1.5,0.4,0
4.6,3.6,1. ,0.2,0
5.1,3.3,1.7,0.5,0
4.8,3.4,1.9,0.2,0
5. ,3. ,1.6,0.2,0
5. ,3.4,1.6,0.4,0
5.2,3.5,1.5,0.2,0
5.2,3.4,1.4,0.2,0
4.7,3.2,1.6,0.2,0
4.8,3.1,1.6,0.2,0
5.4,3.4,1.5,0.4,0
5.2,4.1,1.5,0.1,0
5.5,4.2,1.4,0.2,0
4.9,3.1,1.5,0.1,0
5. ,3.2,1.2,0.2,0
5.5,3.5,1.3,0.2,0
4.9,3.1,1.5,0.1,0
4.4,3. ,1.3,0.2,0
5.1,3.4,1.5,0.2,0
5. ,3.5,1.3,0.3,0
4.5,2.3,1.3,0.3,0
4.4,3.2,1.3,0.2,0
5. ,3.5,1.6,0.6,0
5.1,3.8,1.9,0.4,0
4.8,3. ,1.4,0.3,0
5.1,3.8,1.6,0.2,0
4.6,3.2,1.4,0.2,0
5.3,3.7,1.5,0.2,0
5. ,3.3,1.4,0.2,0
7. ,3.2,4.7,1.4,1
6.4,3.2,4.5,1.5,1
6.9,3.1,4.9,1.5,1
5.5,2.3,4. ,1.3,1
6.5,2.8,4.6,1.5,1
5.7,2.8,4.5,1.3,1
6.3,3.3,4.7,1.6,1
4.9,2.4,3.3,1.,1
6.6,2.9,4.6,1.3,1
5.2,2.7,3.9,1.4,1
5. ,2. ,3.5,1.,1
5.9,3. ,4.2,1.5,1
6. ,2.2,4. ,1.,1
6.1,2.9,4.7,1.4,1
5.6,2.9,3.6,1.3,1
6.7,3.1,4.4,1.4,1
5.6,3. ,4.5,1.5,1
5.8,2.7,4.1,1.,1
6.2,2.2,4.5,1.5,1
5.6,2.5,3.9,1.1,1
5.9,3.2,4.8,1.8,1
6.1,2.8,4. ,1.3,1
6.3,2.5,4.9,1.5,1
6.1,2.8,4.7,1.2,1
6.4,2.9,4.3,1.3,1
6.6,3. ,4.4,1.4,1
6.8,2.8,4.8,1.4,1
6.7,3. ,5. ,1.7,1
6. ,2.9,4.5,1.5,1
5.7,2.6,3.5,1.,1
5.5,2.4,3.8,1.1,1
5.5,2.4,3.7,1.,1
5.8,2.7,3.9,1.2,1
6. ,2.7,5.1,1.6,1
5.4,3. ,4.5,1.5,1
6. ,3.4,4.5,1.6,1
6.7,3.1,4.7,1.5,1
6.3,2.3,4.4,1.3,1
5.6,3. ,4.1,1.3,1
5.5,2.5,4. ,1.3,1
5.5,2.6,4.4,1.2,1
6.1,3. ,4.6,1.4,1
5.8,2.6,4. ,1.2,1
5. ,2.3,3.3,1.,1
5.6,2.7,4.2,1.3,1
5.7,3. ,4.2,1.2,1
5.7,2.9,4.2,1.3,1
6.2,2.9,4.3,1.3,1
5.1,2.5,3. ,1.1,1
5.7,2.8,4.1,1.3,1
6.3,3.3,6. ,2.5,2
5.8,2.7,5.1,1.9,2
7.1,3. ,5.9,2.1,2
6.3,2.9,5.6,1.8,2
6.5,3. ,5.8,2.2,2
7.6,3. ,6.6,2.1,2
4.9,2.5,4.5,1.7,2
7.3,2.9,6.3,1.8,2
6.7,2.5,5.8,1.8,2
7.2,3.6,6.1,2.5,2
6.5,3.2,5.1,2.,2
6.4,2.7,5.3,1.9,2
6.8,3. ,5.5,2.1,2
5.7,2.5,5. ,2.,22
5.8,2.8,5.1,2.4,2
6.4,3.2,5.3,2.3,2
6.5,3. ,5.5,1.8,2
7.7,3.8,6.7,2.2,2
7.7,2.6,6.9,2.3,2
6. ,2.2,5. ,1.5,2
6.9,3.2,5.7,2.3,2
5.6,2.8,4.9,2.,2
7.7,2.8,6.7,2.,2
6.3,2.7,4.9,1.8,2
6.7,3.3,5.7,2.1,2
7.2,3.2,6. ,1.8,2
6.2,2.8,4.8,1.8,2
6.1,3. ,4.9,1.8,2
6.4,2.8,5.6,2.1,2
7.2,3. ,5.8,1.6,2
7.4,2.8,6.1,1.9,2
7.9,3.8,6.4,2.,2
6.4,2.8,5.6,2.2,2
6.3,2.8,5.1,1.5,2
6.1,2.6,5.6,1.4,2
7.7,3. ,6.1,2.3,2
6.3,3.4,5.6,2.4,2
6.4,3.1,5.5,1.8,2
6. ,3. ,4.8,1.8,2
6.9,3.1,5.4,2.1,2
6.7,3.1,5.6,2.4,2
6.9,3.1,5.1,2.3,2
5.8,2.7,5.1,1.9,2
6.8,3.2,5.9,2.3,2
6.7,3.3,5.7,2.5,2
6.7,3. ,5.2,2.3,2
6.3,2.5,5. ,1.9,2
6.5,3. ,5.2,2.,2
6.2,3.4,5.4,2.3,2
5.9,3. ,5.1,1.8,2

"""


knn其实很好理解 

因为在机器学习实战中....是第一讲???

然后python实现详见代码垃圾注释


主要思路

枚举待预测的点 与 训练集各个点的距离

然后取距离前k的点(这k个点是训练集的点 有确切答案)

根据少数服从多数原则进行判断结果

over

各个函数功能简单粗暴 见注释

然后恭喜手敲AC rate 0.87

恭喜照抄理解AC rate 0.96

嗯 明天上提交传代码

(代办清单:爬虫,图像识别,更新后删除括号内内容)

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:26022次
    • 积分:1424
    • 等级:
    • 排名:千里之外
    • 原创:111篇
    • 转载:2篇
    • 译文:0篇
    • 评论:4条
    博客专栏