K Apprentissage de l'algorithme du plus proche voisin (KNN)

Apprentissage automatique - K Algorithme du plus proche voisin (KNN)

Notions de base

Fondamental

Étant donné un échantillon de test, découvrez les k échantillons d'apprentissage les plus proches dans l'ensemble d'apprentissage en fonction d'une mesure de distance, puis faites des prédictions basées sur les informations de ces k "voisins".

​ ——Zhou Zhihua, livre de pastèque

Il existe un ensemble d'échantillons de données, également appelé ensemble d'échantillons d'apprentissage, et chaque donnée de l'ensemble d'échantillons a une étiquette, c'est-à-dire que nous connaissons la relation correspondante entre chaque donnée de l'ensemble d'échantillons et la catégorie à laquelle elle appartient. Après avoir saisi de nouvelles données sans étiquettes, chaque caractéristique des nouvelles données est comparée aux caractéristiques correspondantes des données dans l'ensemble d'échantillons, puis l'algorithme extrait les étiquettes de classification (top k) des données les plus similaires (voisins les plus proches) de plusieurs caractéristiques de l'échantillon. ——L'apprentissage automatique en pratique

Auto-compréhension: c'est-à-dire qu'il existe un tas d'échantillons d'ensembles d'apprentissage bien étiquetés, puis vous lancez un échantillon pour la prédiction et jugez à quelle catégorie appartient l'échantillon à prédire par l'étiquetage de l'échantillon d'apprentissage k le plus proche points de l'échantillon à prédire.

exemple

Après avoir lu le principe, vous devriez avoir une compréhension de base de cet algorithme KNN, alors jetez un œil à l'exemple ci-dessous ! (Le modèle de type provient du manuel, les données sont écrites par moi-même, juste pour comprendre l'algorithme !)


Nombre de combats, nombre de baisers et type d'évaluation de film par film

titre du film Scène de combat caméra de baisers type de film
l'amour avant l'aube 3 104 Romance
Battement 2 100 Romance
Ecoute attentivement 1 81 Romance
Luo Xiaohei Ji Ji 101 5 Film d'action
numéro d'assemblage 99 2 Film d'action
guerre apocalyptique 98 2 Film d'action
18 90 inconnu

À partir du tableau ci-dessus, nous pouvons construire le diagramme de coordonnées suivant avec les 6 informations que nous connaissons auparavant :

insérez la description de l'image ici

Utilisez ensuite la formule de distance pour calculer les k points les plus proches de « ? », et jugez le type de film de « ? » à travers ces k points. De toute évidence, on peut déterminer qu'il s'agit d'un film d'amour à travers les k points les plus proches de lui.

Ensuite, comprenez-le à travers des graphiques, comme suit :

insérez la description de l'image ici

Le carré orange et le triangle bleu sont les résultats de notre formation, et le cercle vert est l'échantillon que nous devons prédire. D'après la figure, nous pouvons constater qu'il y a deux ⭕, qui sont utilisés pour détecter les échantillons à tester et former Cercle de distance minimale pour la distance d'échantillonnage (moi-même). On constate que k = 1 et k = 3, les résultats obtenus sont différents : lorsque k = 1, le résultat prédit est un carré, et lorsque k = 3, le résultat prédit doit être un triangle. Nous avons constaté que différents k ont ​​une grande influence sur nos résultats de prédiction, alors comment choisir la valeur de ce k ? Il est également facile de découvrir à partir du tableau ci-dessus, pourquoi k est un nombre de base, pourquoi ne pas définir un nombre pair ?

Questions de base sur KNN

Comment la distance est-elle calculée ?

Quand j'ai vu cet algorithme, la première chose à laquelle j'ai pensé a été, comment calculer la distance la plus courte de cet algorithme ? Ce qui me vient à l'esprit c'est un article vierge, comment la distance est-elle calculée, ne se voit-elle pas avec les yeux ? (Puis j'ai découvert que je suis vraiment vieux et que je ne peux plus rien faire)

Distance euclidienne : la distance en ligne droite entre deux points

officiel:

insérez la description de l'image ici

Bien sûr, si vous utilisez cette formule, vous devez calculer la distance entre l'échantillon à tester et chaque échantillon d'apprentissage, puis filtrer pour laisser les k échantillons inférieurs, et utiliser les étiquettes des k échantillons pour juger les résultats de prédiction de les échantillons à tester.

Manhattan Distance : Aussi connue sous le nom de City Block Range. La somme des distances absolues entre deux points sur l'axe des coordonnées.

Officiel :

insérez la description de l'image ici

Ceci est plus adapté aux classifications prédictives avec des dimensions plus élevées (plus de fonctionnalités).

La plupart de ce qui précède consiste à utiliser la distance euclidienne. Après tout, c'est simple et direct, et le plus important est que nous le comprenions tous !

Laissez-moi vous dire quelle méthode je préfère :

Prenez directement le point de l'échantillon à tester comme point central du cercle, puis déterminez un rayon minimum, et élargissez progressivement le rayon jusqu'à ce que le nombre d'échantillons d'apprentissage dans notre cercle> = k, puis jugez le nombre d'échantillons d'apprentissage à tester en fonction du nombre d'échantillons d'apprentissage dans le cercle Le type de prévision pour l'échantillon.

Comment k définit-il la taille ?

À travers les cas carrés et triangulaires de l'exemple, nous pouvons voir que l'impact des différentes valeurs de k est différent et que sa capacité de généralisation est relativement faible.Après tout, par rapport à d'autres algorithmes, il n'a pas d'apprentissage (formation ) le processus de.

valeur k Influence
C est trop gros L'étiquette de prédiction est stable, trop plate et la classification est floue, et cela fonctionnera également pour les échantillons voisins éloignés
trop petit Il est facile de provoquer un surajustement et est trop sensible aux points d'échantillonnage des voisins

Le résultat sur le réseau est : essayer constamment la valeur K optimale par validation croisée, commencer par sélectionner une valeur K plus petite, augmenter continuellement la valeur de K, puis calculer la variance de l'ensemble de vérification et enfin trouver une valeur K plus appropriée .

Pourquoi k n'est-il pas défini comme un nombre pair ?

Pourquoi ne pas définir un nombre pair, c'est tout à fait éviter l'intrication. Les échantillons d'apprentissage en KNN n'ont ni ni ni , ni ceci ni cela, c'est certain ! Définir un nombre impair, alors il est impossible d'avoir un résultat nul. (Bien sûr, on parle ici de classification binaire ! Le reste de la classification doit être conçu pour k. Par exemple, 4, 7... peuvent être utilisés pour trois classifications. Bref, c'est pour éviter les situations relatives)

Avantages et inconvénients de KNN

Examinons d'abord le processus général de KNN, comme suit :

  1. Collecte des données : tout moyen légitime
  2. Préparer les données : format de données structuré, c'est-à-dire les points dans les coordonnées des échantillons d'apprentissage dans la classification binaire, pour déterminer x, y et (x, y) des échantillons d'apprentissage
  3. Analyse des données : tout moyen légitime
  4. Algorithmes d'entraînement : non applicables ! Donc non
  5. Algorithme de test : calcul du taux d'erreur
  6. Utilisez l'algorithme : commencez par saisir les données d'échantillon et les résultats de sortie structurés, exécutez l'algorithme knn pour déterminer à quelle catégorie appartient l'échantillon d'entrée, puis traitez-le.
avantage défaut
haute précision pas de processus de formation
insensible aux valeurs aberrantes grande complexité de calcul
Aucune saisie de données supposée complexité spatiale élevée

Code

Première écriture (2022.10.25)

Collecte de données, traitement, écriture de code, veuillez lire ci-dessous :

Le siège de l'Université Jimei et les zones environnantes sont interceptés à partir de la carte Baidu, et les données sont divisées en deux parties selon la figure suivante. Une partie est l'échantillon de données sur le campus jmu. Nous définissons l'étiquette comme jmu, et l'autre une partie se trouve à l'extérieur du campus de l'Université Jimei. Pour l'échantillon de données, nous définissons son étiquette comme unjmu, et jugeons s'il se trouve au siège de l'école jmu ou à l'extérieur du siège de l'école jmu par leurs coordonnées horizontales et verticales.

insérez la description de l'image ici

Ensemble d'entraînement:

Sélectionnez un bâtiment sur la carte informations de localisation personnalisées étiqueter
Yuzhou (3,85) jmu
grandeur (15,70) jmu
Lu Da (7,58) jmu
Lu Zhenwan (17,62) jmu
Hôtel Atour (33,28) unjmu
Bibliothèque Kah Kee (30,100) jmu
Wanda (10,10) unjmu
Zhou Mapo (2,1) unjmu
Réparation automobile Xinjie (45,31) unjmu
Gouvernement du district de Jimei (50,40) unjmu
Jardin Guangsha (53,55) unjmu
Radio et télévision Jimei (60,58) unjmu
Bureau des tremblements de terre (52,15) unjmu

Ensemble d'essai:

Emplacement étiqueter
(5, 7) unjmu
(10,100) jmu
(49,49) jmu
(35,40) unjmu

Pas grand chose à dire, poste le code :

import matplotlib.pyplot as plt
import numpy as np
import math
class KNN:
    def __init__(self, x_train, x_test, k):
        # 保留测试点与所以训练样本的距离
        self.distance =  np.zeros((len(x_test), len(x_train)))
        # 保留预测结果
        self.predicted = []
        # KNN中k的取值(不懂看上面基本知识点)
        self.k = k

   # KNN核心算法
    def knn(self, x_test, x_train, y_train):
        print(y_train)
        for i in range(len(x_test)):
            for j in range(len(x_train)):
                self.distance[i][j] = self.knn_distance(x_test[i], x_train[j])
            self.predicted.append(self.knn_predicted(self.distance[i], y_train))
        return self.predicted

    # 利用欧拉公式计算距离
    def knn_distance(self, x1, x2):
        dis = math.sqrt(math.pow((x1[0]-x2[0]),2) + math.pow((x1[1]-x2[1]),2))
        return dis

    def knn_predicted(self, distances, y_train):
        #利用numpy的argsort方法获取前K小样本的索引
        k_predicted_index = distances.argsort()[:self.k]
        # 由于对一些库的函数学习不深,所以选择下面我自己可以实现的方法
        count_jmu = 0
        count_other =0
        for i in range(len(k_predicted_index)):
            if(y_train[k_predicted_index[i]] == 'jmu'):
                count_jmu += 1
            else:
                count_other += 1
        if(count_jmu > count_other):
            return 'jmu'
        else:
            return 'unjmu'
# 自定义训练数据集
x_train = [[3, 85], [15, 70], [7, 58], [17,62], [33,28], [30,100], [10,10], [2,1], [45,31], [50,40], [53,55], [60,58], [52,15]]
y_train = ['jmu', 'jmu', 'jmu', 'jmu', 'unjmu','jmu' ,'unjmu' ,'unjmu' ,'unjmu' ,'unjmu' ,'unjmu' ,'unjmu' ,'unjmu']

# 自定义测试数据集
x_test = [[5,7], [10,100], [19,49], [35,40]]
y_test = ['unjum','jum','unjum','jum']

# 设置KNN中的k
k = 3
knn = KNN(x_train, x_test, k)

# 获得测试集的预测结果
pred = knn.knn(x_test, x_train, y_train)
print(pred)

La sortie affiche :

insérez la description de l'image ici

Amélioration (2022.10.28)

数据集:
链接:https://pan.baidu.com/s/1yrDGiK9yXFxB_JyC3Q5ycg
提取码:1234

如果你觉得上面的描述或者代码不够清晰,请看这里,对于上述的代码,如果想要改变数据集好像很困难,而且变化不大,不易于修改,所以进行了一定的精炼,请看下面:

代码:

首先,对于python来说,典型的黑盒子,我们需要导入我们所需方法的库进行调用。

import matplotlib.pyplot as plt
import numpy as np
import math
import pandas as pd
from sklearn.model_selection import train_test_split

然后,根据KNN的算法思想进行编写KNN主体函数

class KNN:
    def __init__(self, x_train, x_test, k):
        # 保存距离
        self.distance =  np.zeros((len(x_test), len(x_train)))
        # 预测结果
        self.predicted = []
        # knn中的k值
        self.k = k  
    # knn的主要函数 
    def knn(self, x_test, x_train, y_train):
        for i in range(len(x_test)):
            for j in range(len(x_train)):
                self.distance[i][j] = self.knn_distance(x_test[i], x_train[j])
            self.predicted.append(self.knn_predicted(self.distance[i], y_train))
        return self.predicted

# 欧式距离的计算
    def knn_distance(self, x1, x2):
        dis = math.sqrt(math.pow((x1[0]-x2[0]),2) + math.pow((x1[1]-x2[1]),2))
        return dis

# 预测knn函数
    def knn_predicted(self, distances, y_train):
        k_predicted_index = distances.argsort()[:self.k]
        count_jmu = 0
        count_other =0
        for i in range(len(k_predicted_index)):
            if(y_train[k_predicted_index[i]] == 'jmu'):
                count_jmu += 1
            else:
                count_other += 1
        if(count_jmu > count_other):
            return 'jmu'
        else:
            return 'unjmu'

通过绘制测试集和训练集的样本分布来视觉上查看预测结果

# 绘图(看数据集分布)
def paint(x_train, x_test):
# 绘制图像, X、Y是存储unjmu的数据,X1、Y1存储的是jmu的数据,Z是用于过渡
    X = []
    X1 = []
    X2 = []
    Y = []
    Y1 = []
    X2 = []
    Z = []
    # 根据训练样本获取x、y
    x_train = np.array( x_train)
    X = x_train[:,0]
    Y = x_train[:,1]

    # 对数据进行处理,根据训练集的数据以及label划分出jmu的点和unjum的点
    for i in range(len(y_train)):
        if(y_train[i] == 'jmu'):
            Z.append(i)
            X1.append(X[i])
            Y1.append(Y[i])
    X = np.delete(X,Z)
    Y = np.delete(Y,Z)
    
    # 绘制测试集的数据准备
    x_test = np.array(x_test)
    X2 = x_test[:,0]
    Y2 = x_test[:,1] 

    # 绘图,红色为jmu的数据,绿色是unjmu数据,蓝色为测试样本
    plt.scatter(X, Y, color = 'g')
    plt.scatter(X1, Y1, color ='r')
    plt.scatter(X2, Y2, color ='b')
# 数据处理,将csv获得的数据变成列表
def data_tolist(x_train, x_test, y_train, y_test):
    x_train = np.array(x_train)
    x_train = x_train.tolist()

    y_train = np.array(y_train)
    y_train = y_train.tolist()

    x_test = np.array(x_test)
    x_test = x_test.tolist()

    y_test = np.array(y_test)
    y_test = y_test.tolist()

    return x_train, x_test, y_train, y_test
# 计算精确度
def predicted(pred, y_test):
    count = 0
    for i in range(len(pred)):
        if(y_test[i] == pred[i]):
            count += 1
    pred1 = count / len(y_test)
    return pred1
# 利用panda库进行对csv文件的读取和处理操作
data=pd.read_csv("D:/桌面/1.csv")
X = data.iloc[:,:2]
Y = data.iloc[:,2]

# 划分数据集,并且将数据集转换成list类型,0.8的训练集,0.2的测试集
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)

x_train, x_test, y_train, y_test = data_tolist(x_train, x_test, y_train, y_test)

paint(x_train, x_test)

for i in range(len(x_train)):
    if (i%2 != 0):
        k = i
        knn = KNN(x_train, x_test, k)
        pred = knn.knn(x_test, x_train, y_train)
        print(y_test)
        print(f"预测结果:{
      
      pred}")
        predicte = predicted(pred, y_test)
        print(f"k = {
      
      k}时,测试精度为:{
      
      predicte}")

insérez la description de l'image ici

注:红色定义为jmu样本,蓝色为待遇测样本,绿色为unjmu样本

结果分析

以上面增强代码和运行结果进行分析,去十次结果(理应进行对k=0,到k=len(x_train)进行分析),之所以取10十因为k取值越大,其实结果过于模糊,说白了k越大,等于比较数据集那个label的样本数更多了。

k = ? predicate
1 1
3 0.83333
5 1
7 1
9 1
11 0.83333
13 0.83333
15 0.83333
21 0.66666
23 0.66666

从上表看:貌似k取越小越好,k越大预测的精度就越差了,这是为什么呢?难道k真的取值越小越好吗?

首先来说第一个问题:

k越大精度就越差,为什么呢?

首先,先分析一下我的数据集,我的数据集中label为unjmu的样本和jmu的样本数量上是不匹配的,unjmu的样本明显大于jmu,那么在k取值越大的情况下unjmu的样本就会在那些label标签为jmu中的作用越大,导致将label将jmu样本预测成unjmu。所以说,当k大于一定的值时,预测结果和样本数据集标签种类的数量关系会被放大。

再说一下第二个问题:

k取越小越好吗?
看下图:

insérez la description de l'image ici

L'échantillon à prédire dans la boîte est unjmu, mais l'étiquette la plus proche de lui est une étiquette mal étiquetée par les humains. Si k est plus petit, mieux c'est, alors k = 1 (plus proche voisin) doit être pris, mais dans ce cas , l'échantillon nécessite 0 erreur dans une large mesure. , mais toute étiquette erronée peut entraîner une erreur dans le résultat de la prédiction, et il est difficile d'obtenir une erreur nulle dans un ensemble de données étiqueté manuellement. (Tout comme lorsque j'ai commencé à écrire des données, il y a eu une erreur d'écriture d'étiquette). Par conséquent, la valeur de k n'est pas aussi petite que possible.

Pour résumer : Alors, comment k doit-il définir la taille ? Dans la proposition ci-dessus de la question de base de KNN, la méthode de validation croisée est mentionnée, vous pouvez l'essayer. Je pense personnellement que la valeur de k est principalement liée aux aspects suivants :

  1. La taille de l'ensemble de données. (S'il est trop grand, k ne peut pas prendre une valeur trop petite, sinon le surajustement sera grave ; s'il est trop petit, k ne peut pas prendre une valeur grande, sinon l'ambiguïté sera trop forte)
  2. Exemple de type d'étiquette. (Il y a plus de types, donc la possibilité d'erreurs d'étiquetage est plus grande)
  3. La dimension des données de l'échantillon. (Il est préférable d'utiliser différentes formules de calcul de distance pour différentes dimensions, et les méthodes de calcul sont différentes, donc k vaut la peine d'être choisi et doit être ajusté)

Je suppose que tu aimes

Origine blog.csdn.net/weixin_51961968/article/details/127534931
conseillé
Classement