Python 3 boyutlu seviye seti nasıl çizilir?
Kafamdaki görüntüyü çizmekte biraz sorun yaşıyorum. Destek Vektör Makineleri ile Kernel numarasını görselleştirmek istiyorum. Bu yüzden, bir altdüzlemle ayrılması gereken iki daireden (bir iç ve bir dış daire) oluşan iki boyutlu bazı veriler yaptım. Açıkçası bu iki boyutta mümkün değil - bu yüzden onları 3B'ye dönüştürdüm. Örnek sayısı n olsun. Şimdi bir (n, 3) -dizim (3 sütun, n satır) X veri noktası ve bir (n, 1) -dizim y var. Sklearn kullanarak doğrusal sınıflandırıcıyı
clf = svm.SVC(kernel='linear', C=1000)
clf.fit(X, y)
Veri noktalarını zaten dağılım grafiği olarak çiziyorum
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
Şimdi, ayıran hiper düzlemi yüzey grafiği olarak çizmek istiyorum. Buradaki sorunum, hiper düzlemin eksik açık temsilidir, çünkü karar işlevi yalnızca örtük bir hiper düzlem yoluyla verir decision_function = 0. Bu nedenle 4 boyutlu bir nesnenin seviye kümesini (seviye 0) çizmem gerekiyor.
Bir python uzmanı olmadığım için biri bana yardım edebilirse minnettar olurum! Ve bunun gerçekten bir SVM kullanmanın "tarzı" olmadığını biliyorum ama tezim için örnek olarak bu görüntüye ihtiyacım var.
Düzenle: mevcut "kodum"
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs, make_circles
from tikzplotlib import save as tikz_save
plt.close('all')
# we create 50 separable points
#X, y = make_blobs(n_samples=40, centers=2, random_state=6)
X, y = make_circles(n_samples=50, factor=0.5, random_state=4, noise=.05)
X2, y2 = make_circles(n_samples=50, factor=0.2, random_state=5, noise=.08)
X = np.append(X,X2, axis=0)
y = np.append(y,y2, axis=0)
# shifte X to [0,2]x[0,2]
X = np.array([[item[0] + 1, item[1] + 1] for item in X])
X[X<0] = 0.01
clf = svm.SVC(kernel='rbf', C=1000)
clf.fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
# plot the decision function
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# create grid to evaluate model
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# plot decision boundary and margins
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--','-','--'])
# plot support vectors
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k')
################## KERNEL TRICK - 3D ##################
trans_X = np.array([[item[0]**2, item[1]**2, np.sqrt(2*item[0]*item[1])] for item in X])
fig = plt.figure()
ax = plt.axes(projection ="3d")
# creating scatter plot
ax.scatter3D(trans_X[:,0],trans_X[:,1],trans_X[:,2], c = y, cmap=plt.cm.Paired)
clf2 = svm.SVC(kernel='linear', C=1000)
clf2.fit(trans_X, y)
ax = plt.gca(projection='3d')
xlim = ax.get_xlim()
ylim = ax.get_ylim()
zlim = ax.get_zlim()
### from here i don't know what to do ###
xx = np.linspace(xlim[0], xlim[1], 3)
yy = np.linspace(ylim[0], ylim[1], 3)
zz = np.linspace(zlim[0], zlim[1], 3)
ZZ, YY, XX = np.meshgrid(zz, yy, xx)
xyz = np.vstack([XX.ravel(), YY.ravel(), ZZ.ravel()]).T
Z = clf2.decision_function(xyz).reshape(XX.shape)
#ax.contour(XX, YY, ZZ, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--','-','--'])
Istenilen çıktı
Ben böyle bir şey almak istiyorum o . Genel olarak, bu makalede yaptıklarını , özellikle de "Doğrusal olmayan dönüşümler" i yeniden inşa etmek istiyorum .
Yanıtlar
Sorunuzun bir kısmı , doğrusal çekirdekli SVM ile ilgili bu soruda ele alınmaktadır . Bu kısmi bir cevap, çünkü yalnızca doğrusal çekirdekler bu şekilde gösterilebilir, yani, doğrusal çekirdek kullanılırken tahminci aracılığıyla erişilebilen hiper düzlem koordinatları sayesinde.
Diğer bir çözüm, izosurface'i bulmaktır. marching_cubes
Bu çözüm, scikit-imagearaç setinin (https://scikit-image.org3B koordinatların örgü ızgarasından belirli bir değerin eş yüzeyini bulmaya izin veren (burada, hiper düzleme olan mesafeyi temsil ettiği için 0'ı düşündüm).
Aşağıdaki kodda (sizinkinden kopyalanmış), herhangi bir çekirdek fikrini uyguluyorum (örnekte, RBF çekirdeğini kullandım) ve çıktı, kodun altında gösteriliyor. Lütfen sizin durumunuzda başka bir sorun olabilecek matplotlib ile 3B çizim ile ilgili dipnotumu inceleyin.
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from skimage import measure
from sklearn.datasets import make_blobs, make_circles
from tikzplotlib import save as tikz_save
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
plt.close('all')
# we create 50 separable points
#X, y = make_blobs(n_samples=40, centers=2, random_state=6)
X, y = make_circles(n_samples=50, factor=0.5, random_state=4, noise=.05)
X2, y2 = make_circles(n_samples=50, factor=0.2, random_state=5, noise=.08)
X = np.append(X,X2, axis=0)
y = np.append(y,y2, axis=0)
# shifte X to [0,2]x[0,2]
X = np.array([[item[0] + 1, item[1] + 1] for item in X])
X[X<0] = 0.01
clf = svm.SVC(kernel='rbf', C=1000)
clf.fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
# plot the decision function
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# create grid to evaluate model
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# plot decision boundary and margins
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--','-','--'])
# plot support vectors
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k')
################## KERNEL TRICK - 3D ##################
trans_X = np.array([[item[0]**2, item[1]**2, np.sqrt(2*item[0]*item[1])] for item in X])
fig = plt.figure()
ax = plt.axes(projection ="3d")
# creating scatter plot
ax.scatter3D(trans_X[:,0],trans_X[:,1],trans_X[:,2], c = y, cmap=plt.cm.Paired)
clf2 = svm.SVC(kernel='rbf', C=1000)
clf2.fit(trans_X, y)
z = lambda x,y: (-clf2.intercept_[0]-clf2.coef_[0][0]*x-clf2.coef_[0][1]*y) / clf2.coef_[0][2]
ax = plt.gca(projection='3d')
xlim = ax.get_xlim()
ylim = ax.get_ylim()
zlim = ax.get_zlim()
### from here i don't know what to do ###
xx = np.linspace(xlim[0], xlim[1], 50)
yy = np.linspace(ylim[0], ylim[1], 50)
zz = np.linspace(zlim[0], zlim[1], 50)
XX ,YY, ZZ = np.meshgrid(xx, yy, zz)
xyz = np.vstack([XX.ravel(), YY.ravel(), ZZ.ravel()]).T
Z = clf2.decision_function(xyz).reshape(XX.shape)
# find isosurface with marching cubes
dx = xx[1] - xx[0]
dy = yy[1] - yy[0]
dz = zz[1] - zz[0]
verts, faces, _, _ = measure.marching_cubes_lewiner(Z, 0, spacing=(1, 1, 1), step_size=2)
verts *= np.array([dx, dy, dz])
verts -= np.array([xlim[0], ylim[0], zlim[0]])
# add as Poly3DCollection
mesh = Poly3DCollection(verts[faces])
mesh.set_facecolor('g')
mesh.set_edgecolor('none')
mesh.set_alpha(0.3)
ax.add_collection3d(mesh)
ax.view_init(20, -45)
plt.savefig('kerneltrick')
Kodun çalıştırılması, Matplotlib ile aşağıdaki görüntüyü üretir; burada yeşil yarı saydam yüzey doğrusal olmayan karar sınırını temsil eder.
Dipnot: matplotlib ile 3B çizim
Matplotlib 3D'nin bazı durumlarda nesnelerin "derinliğini" yönetemeyeceğini unutmayın, çünkü zorderbu nesneninki ile çelişebilir . Bu, bazen hiper düzlemin "noktaların" üstüne "çizilmesinin nedenidir," geride "olsa bile. Bu sorun, matplotlib 3d belgelerinde ve bu yanıtta tartışılan bilinen bir hatadır .
Daha iyi işleme sonuçları elde etmek istiyorsanız , Matplotlib geliştiricilerinin önerdiği şekilde Mayavi'yi veya başka herhangi bir 3D Python çizim kitaplığını kullanmak isteyebilirsiniz .