[PYTHON] Maschinelles Lernen #k Nachbarschaftsmethode und deren Implementierung und verschiedene

Vorwort

Dieser Artikel ist ein Memo, das während des Studiums des Videos eines großartigen Programmierers, Herrn Sentdex, aufgenommen wurde. https://www.youtube.com/user/sentdex

Was ist K-NN? Laut WIKI: https://ja.wikipedia.org/wiki/K%E8%BF%91%E5%82%8D%E6%B3%95

Die k-Nachbarschaftsmethode ist die einfachste von fast allen Algorithmen für maschinelles Lernen. Die Klassifizierung eines Objekts wird durch Abstimmung über seine Nachbarn bestimmt (dh durch Zuweisen der häufigsten Klasse von k nächsten Nachbarn zu diesem Objekt). k ist eine positive ganze Zahl, im Allgemeinen klein. Wenn k = 1 ist, wird es nur in dieselbe Klasse wie das nächste Objekt klassifiziert. Wenn bei der Binomialklassifizierung k auf eine ungerade Zahl eingestellt ist, kann das Problem vermieden werden, dass nicht mit der gleichen Anzahl von Stimmen klassifiziert werden kann.

Ja, ein sehr demokratischer Weg. Schauen Sie sich zuerst die Grafik unten an. Es gibt 6 Datenpunkte. Was ist, wenn Sie gruppieren möchten? image.png

Vielleicht wird es so sein. Warum dann? Weil sie nahe beieinander sind. Was wir tun, heißt "Cluster". image.png

Gut. Dieses Mal gibt es bereits + und gruppierte. image.png

Ich habe jetzt einen roten Punkt. Zu welcher Gruppe gehört dieser rote Punkt? Sie werden wahrscheinlich in der + Gruppe sein. Aber wieso? Welche Art von Denkkreis haben Sie in Ihrem Kopf gedacht? image.png

Der bevorstehende rote Punkt wird wahrscheinlich in der Gruppe sein. Was ist es wieder? image.png

Letzter roter Punkt Wenn Sie hier sind, um welche Gruppe handelt es sich? Dies hängt vom Algorithmus Ihrer Wahl ab. image.png

Kommen wir zurück zur Geschichte. Vielleicht (zumindest ich) ist dieser rote Punkt näher an der + Gruppe als an der Gruppe, also ist der rote Punkt die + Gruppe! Ich hätte mich entscheiden sollen. Und wir nennen diese "Idee" K-nächste Nachbarn (K-NN). Auf Japanisch denke ich, dass es die k-Nachbarschaftsmethode ist. Alles, was ich für K-NN tun muss, ist, den Abstand zwischen den Punkten, die ich gruppieren möchte, und den anderen Punkten zu messen und zu entscheiden, welcher Gruppe ich beitreten möchte. In dem oben gezeigten Beispiel gibt es nur 2 Gruppen, aber was ist, wenn es 100 Aufgaben gibt? Was ist, wenn es ein Problem 1000 gibt? Ja, ich werde meinen Verstand verlieren ... image.png

Aber überlegen Sie es sich zweimal. Muss ich wirklich alle Punkte messen? Ich denke nicht, dass es in den meisten Fällen notwendig ist. "K" ist in K-NN definiert. Setzen wir nun K = 2. image.png

Ja, ich sehe. Wahrscheinlich ist die Stelle, an der der orangefarbene Kreis geschrieben ist, dem roten Punkt am nächsten. Daher schätze ich, dass dieser rote Punkt + Gruppe ist. image.png

Diesmal kam ein schwarzer Fleck heraus. Wenn K = 2, welcher Punkt ist der nächste? Ja, vielleicht diese beiden. Ich habe ein Problem! Es war ein Unentschieden! Das kann ich nicht beurteilen. K-NN erlaubt grundsätzlich nicht, dass dieses k gerade ist. image.png

Also setze K = 3. Wenn K = 3 ist, brauchen wir einen anderen Punkt. Vielleicht ... ist näher? Dieser schwarze Punkt ist eine Gruppe. image.png

Nach dem vorherigen Urteil gibt es also zwei und eins +. 2/3 = 66% Diese 66% sind das Vertrauen in diese Entscheidung. Und die im Voraus gemessene Entfernung wird als Euklidische Entfernung bezeichnet.

Implementierung

Lassen Sie uns zuerst den Fluss entscheiden. image.png

Datenaufbereitung

Lassen Sie es uns mit sklearn implementieren.

Zunächst muss ich einen Datensatz vorbereiten, damit ich diesen diesmal verwenden kann: https://archive.ics.uci.edu/ml/datasets/breast+cancer+wisconsin+%28original%29 Daten zu Brustkrebs.

Datenanalyse

Ich denke, das heruntergeladene wird so aussehen. image.png

Öffnen Sie brustkrebs-wisconsin.names für eine Beschreibung der Daten. Die "Bedeutung" jedes Datenwerts wird in 7 geschrieben. Von hier aus scheinen 1 bis 10 Features und 11 Label zu sein. image.png Es gibt Daten in Brustkrebs-wisconsin.data. Das wichtige Etikett ist jedoch nicht geschrieben. image.png Sie können es programmgesteuert hinzufügen, aber geben Sie es vorerst manuell ein ... image.png

Bibliotheksimport


import numpy as np
from sklearn import preprocessing,model_selection,neighbors
import pandas as pd

Mit Pandas vorverarbeiten

Die ID scheint nicht viel mit dem Datensatz zu tun zu haben, also lassen Sie sie fallen. Es steht geschrieben, dass "?" Im fehlenden Teil in Brustkrebs-wisconsin.names angezeigt wird. Da NAN ein Basis-NG ist, werden wir es hier durch -99999 ersetzen.

df=pd.read_csv('Data/Breast_Cancer_Wisconsin/breast-cancer-wisconsin.data')
df.replace('?',-99999,inplace=True)
df.drop(['id'],1,inplace=True)

Bereiten Sie X- und Y-Daten vor

Einfach ausgedrückt, X sind unbeschriftete Daten. Y sind Nur-Etiketten-Daten. Also setzt X einen DataFrame mit einer abgelegten "Klasse". Y setzt einen DataFrame nur mit "Class".

#features
x=np.array(df.drop(['class'],1))
#label
y=np.array(df['class'])

Getrennte Test- und Zugdaten

80% Zugdaten und 20% Testdaten sind getrennt.

x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,test_size=0.2)

Klassifikator vorbereiten

Da ich K-NN benutze, ist es ein K Neighbors Classifier.

clf=neighbors.KNeighborsClassifier()

Train

clf.fit(x_train,y_train)

Überprüfen Sie mit Testdaten

Ja, es sind ungefähr 96%. Es ist eine gute Genauigkeit.

accuracy=clf.score(x_test,y_test)
print(accuracy)

>0.9642857142857143

Gesamtcode

import numpy as np
from sklearn import preprocessing,model_selection,neighbors
import pandas as pd

df=pd.read_csv('Data/Breast_Cancer_Wisconsin/breast-cancer-wisconsin.data')
df.replace('?',-99999,inplace=True)
df.drop(['id'],1,inplace=True)

#features
x=np.array(df.drop(['class'],1))
#label
y=np.array(df['class'])

x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,test_size=0.2)
clf=neighbors.KNeighborsClassifier()
clf.fit(x_train,y_train)
accuracy=clf.score(x_test,y_test)
print(accuracy)

Lass uns tief graben

Von nun an werde ich KNN selbst schreiben, ohne mich auf sklearn zu verlassen. Schauen wir uns zuerst noch einmal um. Tatsächlich ist es eine Entfernung, um zu entscheiden, welche Gruppe die schwarzen Punkte machen soll. Diese Entfernung wird als "euklidische Entfernung" bezeichnet. image.png

eine Formel

Die Berechnungsformel lautet wie folgt. Entschuldigung für die hässlichen Charaktere ... Hier, i=Diemensions q = Punkt p = Differenz image.png

Zum Beispiel ist q = (1,3), p = (2,5). Euclidean Distance=2.236 image.png

Implementierung

Schreiben wir diese Formel zuerst in Python.

from math import sqrt

plot1=[1,3]
plot2=[2,5]

euclidean_distance=sqrt( (plot1[0]-plot2[0])**2 + (plot1[1]-plot2[1])**2 )

print(euclidean_distance)

Erstellen Sie eine Funktion

Bevor wir eine Funktion erstellen, denken wir zuerst über die Idee nach. Der folgende Code versucht zunächst, den Datensatz und neue Daten zu zeichnen. Das ist richtig für die Funktion der Funktion. Daten: Train_data. vorhersagen: Dies ist Test_data. k: Wie viele Punkte bekommst du? Ich denke, sklearn hat einen Standardwert von k = 5 ... Und am Ende aktiviert es etwas Magie und erzeugt das Ergebnis!

Implementierung

from math import sqrt
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
from collections import Counter
import warnings

style.use('fivethirtyeight')

data_set={'k':[[1,2],[2,3],[3,1]]
          ,'r':[[6,5],[7,7],[8,6]]} 

new_features=[5,7]

[[plt.scatter(ii[0],ii[1],s=100,color=i) for ii in data_set[i]] for i in data_set]
plt.scatter(new_features[0],new_features[1])

def k_nearest_neighbors(data,predict,k=3):
    if len(data) >=k:
        warnings.warnings('K is set to a value less than total voting groups!')
    
    #?make some magic
    
    return vote_result

image.png

Denken Sie an ein magisches Gerät

Suchen Sie wirklich nach dieser Funktion? Wie vergleichen wir einen Datenpunkt mit einem anderen und finden den nächstgelegenen Punkt? KNN muss Vorhersagepunkte mit allen Punkten vergleichen, was ein KNN-Problem ist. Natürlich ist es möglich, Rechenzeit zu sparen, indem Sie den Radius einstellen und nur eine bestimmte Anzahl von Punkten sehen.

Implementierung

  1. Berechnen Sie alle euclidean_distane in For Loop und fügen Sie sie dem Array hinzu.
  2. Zum Beispiel [2.44, 'r'], [1.4, 'r'], [2.14, 'k'], [4.4, 'k'], [5.44, 'k'].
  3. Sortieren Sie dann das als Stimmen bezeichnete Array von klein nach groß euclidean_distane, das im vorherigen Array berechnet wurde.
  4. Speichern Sie die Beschriftung, die dieser euklidischen_Distane entspricht.
  5. Verwenden Sie Counter (Stimmen) .most_common (1), um die häufigsten Elemente zu extrahieren. Dies ist vorläufig [('r', 3)].
  6. Mit Counter (Stimmen) .most_common (1) [0] [0] kann "r" weiter abgerufen werden.
  7. Geben Sie abschließend das Ergebnis zurück.
from math import sqrt
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
from collections import Counter
import warnings

style.use('fivethirtyeight')

data_set={'k':[[1,2],[2,3],[3,1]]
          ,'r':[[6,5],[7,7],[8,6]]} 

new_features=[5,7]

[[plt.scatter(ii[0],ii[1],s=100,color=i) for ii in data_set[i]] for i in data_set]
plt.scatter(new_features[0],new_features[1])

def k_nearest_neighbors(data,predict,k=3):
    if len(data) >=k:
        warnings.warnings('K is set to a value less than total voting groups!')
    
    for group in data:
        #data_set={'k':[[1,2],[2,3],[3,1]],'r':[[6,5],[7,7],[8,6]]} 
        #iterating  ^                       ^
        for features in data[group]:
            #data_set={'k':[[1,2],[2,3],[3,1]],'r':[[6,5],[7,7],[8,6]]} 
            #iterating      ^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^
            
            #not fast and just for 2-dimensions
            #euclidean_distacnce=sqrt(  (features[0]-predict[0])**2 + features[1]-predict[1]**2 )
            
            #better
            #euclidean_distane=np.sqrt( np.sum((np.array(features)-np.array(predict))**2))
            
            euclidean_distane=np.linalg.norm( np.array(features)-np.array(predict)  )
            distance.append([euclidean_distane,group])
    
    votes=[i[1] for i in sorted(distance)[:k]]
    
    print(Counter(votes).most_common(1))
    
    vote_result=Counter(votes).most_common(1)[0][0]
            
    return vote_result

result=k_nearest_neighbors(data_set,new_features,k=3)
print(result)
[[plt.scatter(ii[0],ii[1],s=100,color=i) for ii in data_set[i]] for i in data_set]
plt.scatter(new_features[0],new_features[1],color=result)

Ja, es ist die rote Gruppe! image.png

Gehen wir noch etwas weiter

Lassen Sie uns nun reale Daten verwenden und Scikit-Learn vergleichen, mit dem es genauer ist.

  1. Verwenden Sie full_data = df.astype (float) .values.tolist (), um die Reihenfolge der Daten zufällig zu ändern.
  2. Bereiten Sie einen Datensatz für train_set und test_set vor. Verwenden Sie im Wörterbuch 2 und 4, um die Klasse in den vorherigen Brustkrebsdaten abzugleichen.
  3. train_data = full_data [: -int (test_size * len (full_data))] Wenn beispielsweise 100 full_data vorhanden sind, beträgt test_size 0,2, also 100 * 0,2 = 20. train_data = full_data [: -20] speichert 80 Datensätze als train_data.
  4. test_data = full_data [-int (test_size * len (full_data)):] Wenn beispielsweise 100 full_data vorhanden sind, beträgt test_size 0,2, also 100 * 0,2 = 20. train_data = full_data [-20:] speichert test_data in den letzten 20 Datensätzen.
  5. Die letzte For-Schleife verwendet Train_data und test_set, und obwohl test_set Gruppe 2 ist, kann gesagt werden, dass es falsch war, als die Abstimmung 4 zurückgegeben wurde, und umgekehrt war test_set die Gruppe 2 und es wurde festgestellt, dass es korrekt war, als die Abstimmung 4 zurückgab. Stellen Sie richtig auf +1 ein. Und die genaue Anzahl / Summe kann als die richtige Antwortrate bezeichnet werden.

Selbsthilfefunktion

from math import sqrt
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
from collections import Counter
import warnings
import pandas as pd
import random

style.use('fivethirtyeight')

def k_nearest_neighbors(data,predict,k=3):
    if len(data) >=k:
        warnings.warnings('K is set to a value less than total voting groups!')
    
    for group in data:
        #data_set={'k':[[1,2],[2,3],[3,1]],'r':[[6,5],[7,7],[8,6]]} 
        #iterating  ^                       ^
        for features in data[group]:
            #data_set={'k':[[1,2],[2,3],[3,1]],'r':[[6,5],[7,7],[8,6]]} 
            #iterating      ^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^
            
            #not fast and just for 2-dimensions
            #euclidean_distacnce=sqrt(  (features[0]-predict[0])**2 + features[1]-predict[1]**2 )
            
            #better
            #euclidean_distane=np.sqrt( np.sum((np.array(features)-np.array(predict))**2))
            
            euclidean_distane=np.linalg.norm( np.array(features)-np.array(predict)  )
            distance.append([euclidean_distane,group])
    
    votes=[i[1] for i in sorted(distance)[:k]]
    
    print(Counter(votes).most_common(1))
    
    vote_result=Counter(votes).most_common(1)[0][0]
            
    return vote_result

df=pd.read_csv('Data/Breast_Cancer_Wisconsin/breast-cancer-wisconsin.data')
df.replace('?',-99999,inplace=True)
df.drop(['id'],1,inplace=True)
full_data=df.astype(float).values.tolist()

#random sort your data
random.shuffle(full_data)

test_size=0.2
train_set={2:[],4:[]}
test_set={2:[],4:[]}

train_data=full_data[:-int(test_size*len(full_data))]#first 80%
test_data=full_data[-int(test_size*len(full_data)):] #last 20%

'''
for i in train_data:
    #train_set[i[-1]] is the class data from train_set:2 or 4.
    #.append(i[:-1]) is the function to take all the data (unless the class) to the list 
    train_set[i[-1]].append(i[:-1])

for i in test_data:
    test_set[i[-1]].append(i[:-1])
'''
correct=0
total=0

for group in test_set:
    #loop the class'2' and '4'
    for data in test_set[group]:
        #take the data from set'2' and '4'
        vote=k_nearest_neighbors(train_set,data,k=5)
        if group == vote:
            correct+=1
        total+=1
        

print('Accuracy:',correct/total)

>Accuracy: 0.9640287769784173

sklearn Function

Code wie gewohnt.

import numpy as np
from sklearn import preprocessing,model_selection,neighbors
import pandas as pd

df=pd.read_csv('Data/Breast_Cancer_Wisconsin/breast-cancer-wisconsin.data')
df.replace('?',-99999,inplace=True)

df.drop(['id'],1,inplace=True)

#features
x=np.array(df.drop(['class'],1))
#label
y=np.array(df['class'])

x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,test_size=0.4)

clf=neighbors.KNeighborsClassifier()
clf.fit(x_train,y_train)

accuracy=clf.score(x_test,y_test)

>Accuracies: 0.9671428571428571

Fazit

… Die richtige Antwortrate ändert sich nicht viel, aber die Berechnungsgeschwindigkeit ist mit sklearn deutlich schneller.

Schließlich

Nun, ich denke, es gibt noch viele andere Möglichkeiten, ohne KNN zu klassifizieren. Angenommen, Sie haben diese Art von linearen Daten. image.png Vielleicht? Schreiben Sie diese Zeilen zuerst ... image.png Und ein neuer roter Punkt wird herauskommen. image.png Ist es möglich, mit Square Error zu rechnen? image.png Angenommen, Sie haben solche nichtlinearen Daten. image.png Wenn Sie eine Linie erzwingen, ist es vielleicht so? image.png In diesem Fall können Sie KNN verwenden, um dies sofort herauszufinden. image.png

Es ist schwer zu tun Vielen Dank, dass Sie bis zum Ende bei uns bleiben! Ich freue mich darauf, Sie wieder zu kontaktieren!

Recommended Posts

Maschinelles Lernen #k Nachbarschaftsmethode und deren Implementierung und verschiedene
Maschinelles Lernen ④ K-nächster Nachbar Zusammenfassung
[Maschinelles Lernen] OOB (Out-Of-Bag) und sein Verhältnis
Zusammenfassung der Klassifizierung und Implementierung von Algorithmen für maschinelles Lernen
[Maschinelles Lernen] Schreiben Sie die Methode des nächsten Nachbarn in Python selbst und erkennen Sie handgeschriebene Zahlen.
Ich habe die Methode des maschinellen Lernens und ihre Implementierungssprache anhand der Tag-Informationen von Qiita betrachtet
Maschinelles Lernen: k-Nächste Nachbarn
Einführung in das maschinelle Lernen ~ Zeigen wir die Tabelle der K-Methode für den nächsten Nachbarn ~ (+ Fehlerbehandlung)
K Nachbarschaftsmethode (Mehrklassenklassifikation)
Maschinelles Lernen und mathematische Optimierung
[Deep Learning von Grund auf neu] Implementierung der Momentum-Methode und der AdaGrad-Methode
Eine einfache Python-Implementierung der k-Neighborhood-Methode (k-NN)
Bedeutung des maschinellen Lernens und des Mini-Batch-Lernens
Klassifikation und Regression beim maschinellen Lernen
Organisation von Plattformen für maschinelles Lernen und tiefes Lernen
Algorithmus für maschinelles Lernen (Gradientenabstiegsmethode)
Spezifische Implementierungsmethode zum Hinzufügen früherer Leistungsdaten von Pferden, um die Menge des maschinellen Lernens zu bestimmen
Grundlegendes maschinelles Lernverfahren: ③ Vergleichen und untersuchen Sie die Auswahlmethode für die Merkmalsmenge
Implementierung und Experiment der konvexen Clustering-Methode
[Python] [scikit-learn] k-Einführung in das Memo der Methode des nächsten Nachbarn
"Verwendbare" One-Hot-Codierungstechnik für maschinelles Lernen
Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
Persönliche Notizen und Links zum maschinellen Lernen ① (Maschinelles Lernen)
Erstellen einer Umgebung für Python und maschinelles Lernen (macOS)
"OpenCV-Python Tutorials" und "Praktisches maschinelles Lernsystem"
Bewertungsmethode des Regressionsproblems des maschinellen Lernens (mittlerer quadratischer Fehler und Entscheidungskoeffizient)
Maschinelles Lernen
Studieren Sie maschinelles Lernen und Informatik. Ressourcenliste
Maschinelles Lernen Aufteilung der Trainingsdaten und Lernen / Vorhersage / Verifizierung