2016-06-09 14 views
7

Buduję model dla problemu klasyfikacji binarnej, gdzie każdy z moich punktów danych ma wartość 300 wymiarów (Używam 300 funkcji). Używam PassiveAggressiveClassifier z sklearn. Model radzi sobie naprawdę dobrze.Wykreślanie granicy decyzji dla danych o dużych wymiarach

Chciałbym wykreślić granicę decyzyjną modelu. Jak mogę to zrobić?

Aby odczytać dane, kreślę je w 2D za pomocą TSNE. Zmniejszyłem wymiary danych w 2 krokach - od 300 do 50, a następnie od 50 do 2 (jest to powszechna rekomendacja). Poniżej znajduje się fragment kodu dla tego samego:

from sklearn.manifold import TSNE 
from sklearn.decomposition import TruncatedSVD 

X_Train_reduced = TruncatedSVD(n_components=50, random_state=0).fit_transform(X_train) 
X_Train_embedded = TSNE(n_components=2, perplexity=40, verbose=2).fit_transform(X_Train_reduced) 

#some convert lists of lists to 2 dataframes (df_train_neg, df_train_pos) depending on the label - 

#plot the negative points and positive points 
scatter(df_train_neg.val1, df_train_neg.val2, marker='o', c='red') 
scatter(df_train_pos.val1, df_train_pos.val2, marker='x', c='green') 

Data Plot

I dostać przyzwoity wykres.

Czy istnieje sposób, w jaki mogę dodać granicę decyzji do tego wykresu, który reprezentuje faktyczną granicę decyzji mojego modelu w 300 ciemnej przestrzeni?

+1

Który używasz do redukcji wymiarów - obcięte SVD lub TSNE? Jeśli zastosujesz metodę liniową zarówno do klasyfikacji, jak i redukcji, jest to całkiem proste. –

+0

@Chester Nie sądzę, że op tworzy TES tylko po to, aby go zignorować ;-) – lejlot

Odpowiedz

5

Jednym ze sposobów jest nałożenie tory Voronoi na wykres 2D, czyli kolor w oparciu o bliskość punktów danych 2D (różne kolory dla każdej przewidywanej etykiety klasy). Zobacz najnowszy artykuł autorstwa Migut et al., 2015.

Jest to o wiele łatwiejsze niż się wydaje użyciu meshgrid i scikit za KNeighborsClassifier (jest to kres przykład przy zbiorze Iris zakończyć zamienić kilka pierwszych linii z modelem/kierunkowym):

import numpy as np, matplotlib.pyplot as plt 
from sklearn.neighbors.classification import KNeighborsClassifier 
from sklearn.datasets.base import load_iris 
from sklearn.manifold.t_sne import TSNE 
from sklearn.linear_model.logistic import LogisticRegression 

# replace the below by your data and model 
iris = load_iris() 
X,y = iris.data, iris.target 
X_Train_embedded = TSNE(n_components=2).fit_transform(X) 
print X_Train_embedded.shape 
model = LogisticRegression().fit(X,y) 
y_predicted = model.predict(X) 
# replace the above by your data and model 

# create meshgrid 
resolution = 100 # 100x100 background pixels 
X2d_xmin, X2d_xmax = np.min(X_Train_embedded[:,0]), np.max(X_Train_embedded[:,0]) 
X2d_ymin, X2d_ymax = np.min(X_Train_embedded[:,1]), np.max(X_Train_embedded[:,1]) 
xx, yy = np.meshgrid(np.linspace(X2d_xmin, X2d_xmax, resolution), np.linspace(X2d_ymin, X2d_ymax, resolution)) 

# approximate Voronoi tesselation on resolution x resolution grid using 1-NN 
background_model = KNeighborsClassifier(n_neighbors=1).fit(X_Train_embedded, y_predicted) 
voronoiBackground = background_model.predict(np.c_[xx.ravel(), yy.ravel()]) 
voronoiBackground = voronoiBackground.reshape((resolution, resolution)) 

#plot 
plt.contourf(xx, yy, voronoiBackground) 
plt.scatter(X_Train_embedded[:,0], X_Train_embedded[:,1], c=y) 
plt.show() 

Zauważ, że zamiast precyzyjnie narysować swoją granicę decyzyjną, da ci to przybliżoną ocenę miejsca, w którym powinna leżeć granica (szczególnie w regionach z kilkoma punktami danych, prawdziwa granica może od tego odbiegać). Wyrysuje on linię między dwoma punktami danych należących do różnych klas, ale umieści ją w środku (w rzeczywistości zagwarantowana jest granica decyzyjna między tymi punktami, ale niekoniecznie musi znajdować się pośrodku) .

Istnieje również kilka eksperymentalnych podejść, które lepiej przybliżają rzeczywistą granicę decyzyjną, np. this one on github

Powiązane problemy