(Hinzugefügt am 25.02.2020) TODO: Die Gewichte von k-NN werden aus der Summe der Entfernungen ohne Verwendung der Umkehrung der Entfernungen berechnet. Es wird auf die Umkehrung der Entfernung korrigiert. (Die Berechnungsmethode von KNeighborsClassifier ist nicht falsch, aber die Berechnungsmethode meiner eigenen Funktion ist falsch.)
Mit dem KNeighbors Classifier von sklearn war es möglich, mit weniger unausgeglichenen Daten ein schweres Gewicht auf die Seite zu legen.
Ergebnis: Wir konnten den Rückruf auf der Seite der kleinen Stichprobe erhöhen.
Bilddiagramm nach
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score
%matplotlib inline
from sklearn.datasets import make_classification
data_base = make_classification(
n_samples = 10000, n_features = 2, n_informative = 2, n_redundant = 0,
n_repeated = 0, n_classes = 2, n_clusters_per_class = 2, weights = [0.9, 0.1],
flip_y = 0, class_sep = 0.5, hypercube = True, shift = 0.0,
scale = 1.0, shuffle = True, random_state =5)
df = pd.DataFrame(data_base[0], columns = ['f1', 'f2'])
df['class'] = data_base[1]
fig = plt.figure()
ax = fig.add_subplot()
for i in df.groupby('class'):
cls = i[1]
ax.plot(cls['f1'],
cls['f2'],
'o',
ms=2)
plt.show()
X = df[["f1","f2"]]
y = df["class"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
X_train = X_train.reset_index(drop=True)
X_test = X_test.reset_index(drop=True)
y_train = y_train.reset_index(drop=True)
y_test = y_test.reset_index(drop=True)
print("train", X_train.shape, y_train.shape)
print("test", X_test.shape, y_test.shape)
train (7000, 2) (7000,) test (3000, 2) (3000,)
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=5)
clf.fit(X_train, y_train)
pred = clf.predict(X_test)
result = confusion_matrix(y_test, pred)
result2 = accuracy_score(y_test, pred)
print("confusion matrix \n",result)
print("accuracy \n", result2 )
confusion matrix [[2641 67] [ 167 125]] accuracy 0.922
size_and_weight = pd.DataFrame({
'class0': [sum(clf._y == 0),1/ (sum(clf._y == 0)/ len(clf._y))],
'class1': [sum(clf._y == 1),1/ (sum(clf._y == 1)/ len(clf._y))]}).T
size_and_weight.columns = ['sample_size', 'weight']
size_and_weight
sample_size | weight | |
---|---|---|
class0 | 6292.0 | 1.112524 |
class1 | 708.0 | 9.887006 |
weights_array = pd.Categorical(clf._y)
weights_array.categories = [size_and_weight.loc[('class0'),'weight'],
size_and_weight.loc[('class1'),'weight']]
clf = KNeighborsClassifier(n_neighbors=5)
clf.fit(X_train, y_train)
neigh_dist, neigh_ind = clf.kneighbors(X_test) #Der Datenrahmen dieses Teils wird später beschrieben.
weights_array = np.array(weights_array).reshape((-1, 1))[neigh_ind,0]
pd.DataFrame(weights_array).head()
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0 | 1.112524 | 1.112524 | 1.112524 | 1.112524 | 1.112524 |
1 | 1.112524 | 1.112524 | 1.112524 | 1.112524 | 1.112524 |
2 | 1.112524 | 9.887006 | 1.112524 | 1.112524 | 1.112524 |
3 | 1.112524 | 1.112524 | 1.112524 | 1.112524 | 1.112524 |
4 | 1.112524 | 1.112524 | 1.112524 | 1.112524 | 1.112524 |
--Stellen Sie die Argumentgewichte ein, um das Gewicht zu berücksichtigen, und führen Sie sie bis zur Vorhersage aus
def tmp(array_):
global weights_array
array_ = array_ * weights_array
return array_
clf = KNeighborsClassifier(n_neighbors=5,weights=tmp)
clf.fit(X_train, y_train)
pred = clf.predict(X_test)
pred = clf.predict(X_test)
result = confusion_matrix(y_test, pred)
result2 = accuracy_score(y_test, pred)
print("confusion matrix \n",result)
print("accuracy \n", result2 )
confusion matrix [[2252 456] [ 80 212]] accuracy 0.8213333333333334
--KNeighborsClassifier klassifiziert Testdaten in die Klasse mit der größten Gesamtentfernung. (Obwohl es ein leicht kontraintuitiver Algorithmus ist, dass das Schätzergebnis in einer entfernten Klasse liegt, wird die Entfernungsberechnung nur auf die nächsten n Daten angewendet. Wenn also kein Gewicht angewendet wird, liegt die Schätzung näher an einer Mehrheitsentscheidung als an der Summe der Entfernungen. Es wird.)
Ersetzen Sie die Summe durch "Elementprodukt von sum and weight_array"
Dabei ist es notwendig, die Entsprechung zwischen den folgenden Datenrahmen zu verstehen.
neigh_dist, neigh_ind = clf.kneighbors(X_test)
pd.DataFrame(neigh_dist).tail(5)
pd.DataFrame(neigh_ind).tail(5)
pd.DataFrame(clf._y.reshape((-1, 1))[neigh_ind,0]).tail(5)
Von links von ↑ wird es zu neighbour_dist, neigh_ind, "neigh_ind class"
--DataFrame: Berechnen Sie die folgenden Zahlen für neigh_dist --index = 2998 # 2998. Testdaten --values = 0.015318 # Abstand zwischen [den 1374. Daten von X_train, die als nächstgelegene Entfernung bestimmt wurden] und [Testdaten des obigen Index]
test_index = 2998
tmp1 = pd.DataFrame(X_test.iloc[test_index])
display(tmp1.T)
train_index = 1374
tmp2 = pd.DataFrame(X_train.iloc[train_index])
display(tmp2.T)
#Berechnen Sie den euklidischen Abstand
(
sum( (tmp1.values - tmp2.values) **2 )
**(1/2)
)
array([0.01531811])
--Über neigh_dist.iloc [2998,0]: könnte aus den Trainingsdaten und den Testdaten berechnet werden.
sum(clf_knn._y == y_train) == len(y_train)
True
index_ = neigh_ind[2998,:]
pd.DataFrame(clf._y[index_]).T
-Kapitel [Details: Informationen zu benutzerdefinierten Argumenten] erläutert nur den Quellcode des KNeighborsClassifier.predict-Teils, sodass der Quellcode von git möglicherweise schneller angezeigt wird. Referenz git sklearn
Recommended Posts