Python机器学习:基于西瓜数据集的KNN算法实现

因为本人在学习这块内容之后,发现网络上大部分现有代码的不简洁以及运行报错,再者想要的表达方法的不同,所以自己动手结合网络上已有的代码改写了一个,运行正常。
代码及数据集以上传到GitHubhttps://github.com/king/aaa

# -*- coding:utf-8 -*-
# Author: 非鱼子焉
# Creation_time: 2020.11.11
# Content: 基于西瓜数据集的KNN算法实现

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# KNN算法类
class KNN(object):
    def __init__(self, x, y, K):#x:密度;y:含糖率;k:近邻数
        self.x = x
        self.y = y
        self.K = K
        self.n = len(x)
        
	# 计算距离
    def distance(self, p1, p2):
        return np.linalg.norm(np.array(p1) - np.array(p2))
        
	#算法实现
    def knn(self, x):
        distance = []
        for i in range(self.n):
            dist = self.distance(x, self.x[i])
            distance.append([self.x[i], self.y[i], dist])
        distance.sort(key=lambda x: x[2])
        neighbors = []
        neighbors_labels = []
        for k in range(self.K):
            neighbors.append(distance[k][0])  # 近邻具体数据
            neighbors_labels.append(distance[k][1])  # 近邻标记
        return neighbors, neighbors_labels
        
	#选择多数投票数
    def vote(self, x):
        neighbors, neighbors_labels = self.knn(x)
        vote = {}  # 投票法
        for label in neighbors_labels:
            vote[label] = vote.get(label, 0) + 1
        sort_vote = sorted(vote.items(), key=lambda x:x[1], reverse=True)
        return sort_vote[0][0]  # 返回投票数最多的标记
        
	#对应标记
    def fit(self):
        labels = []
        for sample in self.x:
            label = self.vote(sample)
            labels.append(label)
        return labels  # 返回所有样本的标记
        
	# 计算正确率
    def accuracy(self):
        predict_labels = self.fit()
        real_labels = self.y
        correct = 0
        for predict, real in zip(predict_labels, real_labels):
            if int(predict) == int(real):
                correct += 1
        return correct / self.n
        
#读取数据
def getdata(path):
    dataSet = pd.read_csv(path, delimiter=",")
    X = dataSet[['density', 'sugar_rate']].values
    Y = dataSet['label']
    return X,Y
    
# 进行绘图
def drawpictures(x_positive, y_positive,x_negative, y_negative): 
    plt.scatter(x_positive, y_positive, marker='o', color='red', label='1')
    plt.scatter(x_negative, y_negative, marker='o', color='blue', label='0')
    plt.xlabel('密度')
    plt.ylabel('含糖率')
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.legend(loc='upper left')
    plt.show()
    
#训练数据
def train(X,Y):
    for k in range(1, 9):
        print("*****第%d次*****" %k)
        print('本次knn的k值选取为{}'.format(k))
        knn = KNN(X, Y, k)
        predict = knn.fit()
        print('本次knn的正确率为{}'.format(knn.accuracy()))
        x_positive = []
        y_positive = []
        x_negative = []
        y_negative = []
        for i in range(len(X)):
            if int(predict[i]) == 1:
                x_positive.append(X[i][0])
                y_positive.append(X[i][1])
            else:
                x_negative.append(X[i][0])
                y_negative.append(X[i][1])
        drawpictures(x_positive, y_positive,x_negative, y_negative)

if __name__ == '__main__':
    X,Y = getdata('watermelon3_0a.csv')
    train(X,Y)
    print("************程序运行结束************")

最终结果输出为所选择近邻K的对应的正确率,并且进行plot可视化,其中循环遍历每一次的K值(K从1开始到所设定的值-1为止)

参考博文:https://blog.csdn.net/weixin_42152526/article/details/93528560
参考书籍:MACHINE LEARNING 机器学习(周志华)清华大学出版社

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非鱼子焉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值