KNN算法的实现

本文介绍KNN算法在鸢尾花预测及手写数字识别中的应用,包括数据集加载、特征提取、模型训练与评估等关键步骤。
#!/usr/bin/env python
#-*-coding:utf-8-*-
#knn 的具体实现
import csv
import random
import math
import operator
#导入数据集 文件名,split区分那个集
def loadDataset(filename,split,trainintset=[],testSet=[]):
    with open(filename,'rb') as csvfile:
        lines=csv.reader(csvfile)
        dataset=list(lines)
        for x in range(len(dataset)-1):
            for y in range(4):
                dataset[x][y]=float(dataset[x][y])
            if random.random()<split:
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])
#计算距离
def euclideanDistance(instance1,instance2,length):
    distance=0
    for x in range(length):
        distance+=pow((instance1[x]-instance2[x]),2)
    return math.sqrt(distance)
#得到相邻的k个邻居
def getNeighbors(trainingSet,testInstance,k):
    distance=[]
    length=len(testInstance)-1
    #测试集的维度
    for x in range(len(trainingSet)):
        dist=euclideanDistance(testInstance,trainingSet[x],length)
        distance.append((trainingSet[x],dist))
    distance.sort(key=operatos.itemgetter(1))
    neighbors=[]
    for x in  range(k):
        neighbors.append(distances[x][0])
    return neighbors
#得到那个类占大多数

def getResponse(neighbors):
    classVotes={}
    for x in range(len(neighbors)):
        response=neighbors[x][-1]
        if response in classVotes:
            classVotes[response]+=1
        else:
            classVotes[response]=1
    sortedVotes=sorted(classVotes.iteritems(),key=operator.itemgetter(1),reverse=True)
    #按降序排列
    return sortedVotes[0][0]
#准确率
def getAccuracy(testSet,predictions):
    correct=0
    for x in range(len(testSet)):
        if testSet[x][-1]==predictions[x]:
            correct+=1
    return (correct/float(len(testSet)))*100.0

def main():
    trainingSet=[]
    testSet=[]
    split=0.67
    loadDataset(r'data.txt',split,trainingSet,testSet)
    print('Train set: '+repr(len(trainingSet)))
    print('Test set: '+repr(len(testSet)))

    predictions=[]
    k=3
    for x in range(len(testSet)):
        neighbors=getNeighbors(trainingSet,testSet[x],k)
        result=getResponse(neighbors)
        predictions.append(result)
        print('> predicted='+repr(result)+', actual='+repr(testSet[x][-1]))
    accuracy=getAccuracy(testSet,predictions)
    print('Accuracy: '+repr(accuracy)+'%')

main()







#!/usr/bin/env python#-*-coding:utf-8-*-#knn实现手写数字识别#1建立工程并导入sklearn包‘import numpy as npfrom os import listdir #使用listdir模块,用于访问本地文件from sklearn import neighbors#2加载训练数据#将加载的32*32的图片矩阵展开成一列向量def img2vector(fileName): retMat=np.zeros([1024],int)#定义返回的矩阵,大小为1*1024 fr=open(fileName)#打开包含32*32大小的数字文件 lines=fr.readlines()#读取文件的所有行 for i in range(32):#遍历文件所有行 for j in range(32):#并将01数字存放在retMat中 retMat[i*32+j]=lines[i][j] return retMat#定义加载训练数据的函数readDataSet;def readDataSet(path): fileList=listdir(path)#获取文件夹下的所有文件 numFiles=len(fileList)#统计需要读取的文件的数目 dataSet=np.zeros([numFiles,1024],int)#用于存放所有的数字文件 hwLabels=np.zeros([numFiles])#用于存放对应的标签(与神经网络的不同) for i in range(numFiles):#遍历所有的文件 filePath=fileList[i]#获取文件名称/路径 digit=int(filePath.split('_')[0])#通过文件名获取标签 hwLabels[i]=digit#直接存放数字,并非one-hot向量 dataSet[i]=img2vector(path+'/'+filePath)#读取文件内容 return dataSet,hwLabelstrain_dataSet,train_hwLabels=readDataSet('digits/trainingDigits/')#训练的图片,对应的标签#3构建KNN分类器knn=neighbors.KNeighborsClassifier(algorithm='kd_tree',n_neighbors=3)knn.fit(train_dataSet,train_hwLabels)#加载测试集dataSet,hwLabels=readDataSet('digits/testDigits/')#构建好的knn分类器对测试集进行预测,并计算预测的错误率res=knn.predict(dataSet)#对测试集进行预测error_num=np.sum(res!=hwLabels)#统计分类错误的数目num=len(dataSet)#测试集的数目print('Total num:',num,' wrong num:', error_num,' WrongRate:',error_num/float(num))




#!/usr/bin/env python
#-*-coding:utf-8-*-
#knn算法实例鸢尾花预测
from sklearn import neighbors
from sklearn import datasets

knn=neighbors.KNeighborsClassifier()
#加载数据
iris=datasets.load_iris()
#打印数据
print(iris)
#训练KNN分类器
knn.fit(iris.data,iris.target)
#KNN实验
predictedLabel=knn.predict([[0.1,0.2,0.3,0.4]])
print(predictedLabel)




结果解释:	
     鸢尾花的数据集
     数据代表花瓣的长宽,花萼的长宽
     预测目标target
     预测结果【0】
    
#!/usr/bin/env python
#-*-coding:utf-8-*-
#knn实现手写数字识别
#1建立工程并导入sklearn包‘
import numpy as np
from os import listdir #使用listdir模块,用于访问本地文件
from sklearn import neighbors
#2加载训练数据
#将加载的32*32的图片矩阵展开成一列向量
def img2vector(fileName):
    retMat=np.zeros([1024],int)#定义返回的矩阵,大小为1*1024
    fr=open(fileName)#打开包含32*32大小的数字文件
    lines=fr.readlines()#读取文件的所有行
    for i in range(32):#遍历文件所有行
        for j in range(32):#并将01数字存放在retMat中
            retMat[i*32+j]=lines[i][j]
    return retMat
#定义加载训练数据的函数readDataSet;
def readDataSet(path):
    fileList=listdir(path)#获取文件夹下的所有文件
    numFiles=len(fileList)#统计需要读取的文件的数目
    dataSet=np.zeros([numFiles,1024],int)#用于存放所有的数字文件
    hwLabels=np.zeros([numFiles])#用于存放对应的标签(与神经网络的不同)
    for i in range(numFiles):#遍历所有的文件
        filePath=fileList[i]#获取文件名称/路径
        digit=int(filePath.split('_')[0])#通过文件名获取标签
        hwLabels[i]=digit#直接存放数字,并非one-hot向量
        dataSet[i]=img2vector(path+'/'+filePath)#读取文件内容
    return dataSet,hwLabels
train_dataSet,train_hwLabels=readDataSet('digits/trainingDigits/')
#训练的图片,对应的标签
#3构建KNN分类器
knn=neighbors.KNeighborsClassifier(algorithm='kd_tree',n_neighbors=3)
knn.fit(train_dataSet,train_hwLabels)
#加载测试集
dataSet,hwLabels=readDataSet('digits/testDigits/')
#构建好的knn分类器对测试集进行预测,并计算预测的错误率
res=knn.predict(dataSet)#对测试集进行预测
error_num=np.sum(res!=hwLabels)#统计分类错误的数目
num=len(dataSet)#测试集的数目
print('Total num:',num,' wrong num:', error_num,' WrongRate:',error_num/float(num))


     
      结果解释:
   	  预测实例946, wrong  num 为10  WrongRate 为 0.010570824524312896 
### KNN算法实现方法与代码示例 KNN(K-Nearest Neighbor)是一种简单而有效的监督学习算法,用于分类和回归任务。其实现的核心在于计算新样本与其训练集中所有样本之间的距离,并依据这些距离选出最接近的新样本所属类别。 以下是基于Python语言的一个典型KNN算法实现: #### 距离计算函数 为了找到最近的邻居,需要定义一种距离度量方式,常用的是欧几里得距离。 ```python import numpy as np def euclidean_distance(x1, x2): return np.sqrt(np.sum((x1 - x2)**2)) ``` #### KNN分类器类 通过封装成一个类的形式,便于调用和扩展功能。 ```python class KNN: def __init__(self, k=3): self.k = k def fit(self, X_train, y_train): self.X_train = X_train self.y_train = y_train def predict(self, X_test): predictions = [] for test_sample in X_test: distances = [euclidean_distance(test_sample, train_sample) for train_sample in self.X_train] nearest_indices = np.argsort(distances)[:self.k] nearest_labels = [self.y_train[i] for i in nearest_indices] most_common_label = max(set(nearest_labels), key=list(nearest_labels).count) predictions.append(most_common_label) return predictions ``` #### 使用示例 下面是一个完整的使用案例,展示如何利用上述代码完成分类任务。 ```python from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据集并划分训练集和测试集 data = load_iris() X, y = data.data, data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 初始化KNN模型 knn_model = KNN(k=3) knn_model.fit(X_train, y_train) # 预测测试集结果 y_pred = knn_model.predict(X_test) # 输出准确率 accuracy = accuracy_score(y_test, y_pred) print(f"Accuracy: {accuracy * 100:.2f}%") ``` 此代码实现了基本的KNN分类逻辑[^2],其中`fit()`方法存储训练数据,`predict()`方法则根据输入的数据返回预测的结果。需要注意的是,实际应用中可能还需要考虑权重分配、不同的距离度量以及更复杂的参数调整等问题[^1]。 尽管如此,KNN也存在一定的局限性,比如当面对大规模数据时效率较低,或者在高维空间下可能出现维度灾难现象[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值