English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

用Python实现KNN分类算法

本文实例为大家分享了Python KNN分类算法的具体代码,供大家参考,具体内容如下

KNN分类算法应该算得上是机器学习中最简单的分类算法了,所谓KNN即为K-Le classificateur KNN (K plus proches voisins). Avant de procéder à la classification, le classificateur KNN lit une grande quantité de données d'échantillons marquées avec des étiquettes de classification en tant que données de référence pour la classification. Lorsqu'il classe un échantillon dont la catégorie est inconnue, il calcule la taille de la différence entre l'échantillon actuel et tous les échantillons de référence; cette taille de différence est mesurée par la distance entre les points de données dans l'espace multidimensionnel des caractéristiques des échantillons, ce qui signifie que si deux points d'échantillons sont plus proches dans l'espace multidimensionnel de leurs données de caractéristiques, alors la différence entre ces deux points d'échantillons est plus petite, et la probabilité qu'ils appartiennent à la même catégorie est plus grande. L'algorithme de classification KNN utilise cette cognition de base, en calculant la distance entre le point d'échantillon à prédire et tous les échantillons de l'espace de référence, et en trouvant les K points d'échantillons de référence les plus proches de ce point d'échantillon, en calculant la proportion du nombre le plus élevé de catégories dans ces K échantillons les plus proches, et en prenant cette catégorie comme résultat de prédiction.

Le modèle KNN est très simple, il ne nécessite pas d'entraînement du modèle, chaque prédiction nécessite de calculer la distance entre ce point et tous les points connus, par conséquent, avec l'augmentation du nombre d'échantillons de référence, les coûts de calcul du classificateur KNN augmentent proportionnellement, et KNN n'est pas adapté aux ensembles de données d'échantillons peu nombreux. Après que KNN ait été proposé, de nombreuses améliorations des algorithmes ont été proposées par de nombreuses personnes, visant à améliorer à la fois la vitesse et l'exactitude de l'algorithme, mais tous sont basés sur le principe que "plus les distances sont proches, plus les chances de similitude sont grandes". Ici, j'ai utilisé Python pour réaliser l'algorithme le plus ancien de KNN, le jeu de données utilise le jeu de données Iris très utilisé dans le cours de machine learning, et j'ai ajouté une petite quantité de données bruit à la base de données originale, pour tester la robustesse de l'algorithme KNN.

Le jeu de données utilise le jeu de données Iris,Lien de téléchargement.

Le jeu de données contient90 données (jeu d'entraînement), divisées en2classes, chaque classe45données, chaque donnée4attributs 

Sepal.Length (longueur de la sépale), en cm;
Sepal.Width (largeur de la sépale), en cm;
Petal.Length (longueur de la pétale), en cm;
Petal.Width (largeur de la pétale), en cm;

Types de classification : Iris Setosa (Iris de montagne), Iris Versicolour (Iris multicolore)
Avant, je travaillais principalement avec C++Récemment, j'ai appris Python, aujourd'hui, je veux l'utiliser pour réaliser KNN pour pratiquer, voici le code :

#coding=utf-8
import math
#定义鸢尾花的数据类
class Iris:
 data=[]
 label=[]
 pass
#定义一个读取莺尾花数据集的函数
def load_dataset(filename="Iris_train.txt"):
 f=open(filename)
 line=f.readline().strip()
 propty=line.split(',')#属性名
 dataset=[]#保存每一个样本的数据信息
 label=[]#保存样本的标签
 while line:
 line=f.readline().strip()
 if(not line):
 
 temp=line.split(','),
 content=[]
 for i in temp[0:-1]:
 content.append(float(i))
 dataset.append(content)
 label.append(temp[-1])
 total=Iris()
 total.data=dataset
 total.label=label
 return total#返回数据集
#定义一个Knn分类器类
class KnnClassifier:
 def __init__(self,k,type="Euler"):#初始化的时候定义正整数K和距离计算方式
 self.k=k
 self.type=type
 self.dataloaded=False
 def load_traindata(self,traindata):#加载数据集
 self.data=traindata.data
 self.label=traindata.label
 self.label_set=set(traindata.label)
 self.dataloaded=True#是否加载数据集的标记
 def Euler_dist(self,x,y):# 欧拉距离计算方法,x、y都是向量
 sum=0
 for i,j in zip(x,y):
 sum+=math.sqrt((i-j)**2)
 return sum
 def Manhattan_dist(self,x,y):#曼哈顿距离计算方法,x、y都是向量
 sum=0
 for i,j in zip(x,y):
 sum+=abs(i-j)
 return sum
 def predict(self,temp):#预测函数,读入一个预测样本的数据,temp是一个向量
 if(not self.dataloaded):#判断是否有训练数据
 print "No train_data load in"
 return
 distance_and_label=[]
 if(self.type=="Euler"):#判断距离计算方式,欧拉距离或者曼哈顿距离
 for i,j in zip(self.data,self.label):
 dist=self.Euler_dist(temp,i)
 distance_and_label.append([dist,j])
 else:
 if(self.type=="Manhattan"):
 for i,j in zip(self.data,self.label):
 dist=self.Manhattan_dist(temp,i)
 distance_and_label.append([dist,j])
 else:
 print "erreur de choix de type"
 #Obtenir la distance et l'étiquette de catégorie des K échantillons les plus proches
 neighborhood=sorted(distance_and_label,cmp=lambda x,y : cmp(x[0],y[0]))[0:self.k]
 neighborhood_class=[]
 for i in neighborhood:
 neighborhood_class.append(i[1])
 class_set=set(neighborhood_class)
 neighborhood_class_count=[]
 print "Dans les K voisins les plus proches :"
 #Compter le nombre de catégories dans les K points les plus proches
 for i in class_set:
 a=neighborhood_class.count(i)
 neighborhood_class_count.append([i,a])
 print "classe: ",i," count: ",a
 result=sorted(neighborhood_class_count,cmp=lambda x,y : cmp(x[1],y[1))[-1][0]
 print "resultat: ",result
 return result#retourner la catégorie prédite
if __name__ == '__main__':
 traindata=load_dataset()#données d'entraînement
 testdata=load_dataset("Iris_test.txt")#données de test
 #Créer un classifieur Knn avec K20, par défaut pour le calcul de la distance d'Euler
 kc=KnnClassifier(20)
 kc.load_traindata(traindata)
 predict_result=[]
 #Prédire les résultats de tous les échantillons à prédire dans le jeu de test testdata
 for i,j in zip(testdata.data,testdata.label):
 predict_result.append([i,kc.predict(i),j])
 correct_count=0
 # Comparer les résultats de prédiction et les résultats corrects pour calculer le taux de précision de cette prédiction
 for i in predict_result:
 if(i[1==i[2) :
 correct_count+=1
 ratio=float(correct_count)/len(predict_result)
 print "ratio de prédiction correcte",ratio

Dans le jeu de test11résultats de classification des points de l'échantillon à tester :

Dans les k voisins les plus proches :
classe : Iris-compte de setosa : 20
résultat : Iris-setosa
Dans les k voisins les plus proches :
classe : Iris-compte de setosa : 20
résultat : Iris-setosa
Dans les k voisins les plus proches :
classe : Iris-compte de setosa : 20
résultat : Iris-setosa
Dans les k voisins les plus proches :
classe : Iris-compte de setosa : 20
résultat : Iris-setosa
Dans les k voisins les plus proches :
classe : Iris-compte de setosa : 20
résultat : Iris-setosa
Dans les k voisins les plus proches :
classe : Iris-compte de versicolor : 20
résultat : Iris-versicolor
Dans les k voisins les plus proches :
classe : Iris-compte de versicolor : 20
résultat : Iris-versicolor
Dans les k voisins les plus proches :
classe : Iris-compte de versicolor : 20
résultat : Iris-versicolor
Dans les k voisins les plus proches :
classe : Iris-compte de versicolor : 20
résultat : Iris-versicolor
Dans les k voisins les plus proches :
classe : Iris-compte de versicolor : 20
résultat : Iris-versicolor
Dans les k voisins les plus proches :
classe : Iris-compte de setosa : 18
classe : Iris-compte de versicolor : 2
résultat : Iris-setosa
ratio de prédiction correcte 0.909090909091

Il y a de nombreuses méthodes pour calculer la distance dans KNN, différentes méthodes s'appliquent à différents ensembles de données, ce code n'a implémenté que deux méthodes de calcul : la distance d'Euler et la distance de Manhattan ; les données du jeu de test sont extraites du jeu de données original, la quantité de données n'est pas grande, les résultats ne peuvent pas bien refléter les performances de KNN, donc les résultats de l'exécution du programme ne doivent être pris que comme une référence.

Voici la totalité du contenu de cet article, j'espère qu'il vous aidera dans vos études, et j'espère que vous soutiendrez également le tutoriel à crier.

Déclaration : le contenu de cet article est extrait du réseau, propriété des auteurs respectifs, le contenu est contribué et téléchargé par les utilisateurs d'Internet de manière spontanée, ce site n'a pas de propriété, n'a pas été traité par l'éditeur humain et n'assume aucune responsabilité juridique connexe. Si vous trouvez du contenu présumé enfreignant les droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu présumé enfreignant les droits d'auteur.)