import numpy as np
import matplotlib.pyplot as plt
# จุดข้อมูลในสองมิติ
x = np.random.uniform(0,5,200)
y = np.random.normal(np.sin(x),0.2)
X = np.array([x,y]).T
plt.axes(aspect=1)
plt.scatter(x,y,c='C7',edgecolor='k',cmap='rainbow')
nu = 25 # จำนวนจุดในโครงข่าย ν
eta = 0.5 # อัตราการเรียนรู้ตั้งต้น
thamsam = 20 # จำนวนครั้งที่ทำซ้ำ
tau = thamsam/np.log(nu) # τ
w = [np.random.uniform(X[:,i].min(),X[:,i].max(),nu) for i in range(X.shape[1])]
w = np.array(w).T # ตำแหน่งจุดของโครงข่ายภายในพิกัดข้อมูลเดิม
c = np.arange(nu) # ตำแหน่งจุดของโครงข่ายภายในพิกัดโครงข่าย
for t in range(thamsam):
e = np.exp(-t/tau)
r_t = nu*e
eta_t = eta*e
for Xi in np.random.permutation(X):
Xi_w = Xi-w
raya2 = (Xi_w**2).sum(1) # ระยะห่างกำลังสองระหว่างแต่ละเซลล์กับจุดที่พิจารณา
c_klaisut = np.argmin(raya2) # เซลล์ใกล้สุด
d2 = (c-c_klaisut)**2 # ระยะห่างกำลังสองจากจุดใกล้สุดในพิกัดโครงข่าย
f = np.exp(-0.5*d2/r_t**2)
w += (eta_t*f)[:,None] * Xi_w # ปรับค่า w
plt.plot(w[:,0],w[:,1],'-or') # วาดจุดโครงข่าย
plt.show()
class SOM_1miti:
def __init__(self,nu=50,eta=0.1):
self.nu = nu
self.eta = eta
def rianru(self,X,n_thamsam=100):
self.tau = n_thamsam/np.log(self.nu)
w = [np.random.uniform(X[:,i].min(),X[:,i].max(),nu) for i in range(X.shape[1])]
self.w = w = np.array(w).T
c = np.arange(self.nu)
for t in range(thamsam):
e = np.exp(-t/tau)
r_t = nu*e
eta_t = eta*e
for Xi in np.random.permutation(X):
Xi_w = Xi-w
raya2 = (Xi_w**2).sum(1)
c_klaisut = np.argmin(raya2)
d2 = (c-c_klaisut)**2
f = np.exp(-0.5*d2/r_t**2)
w += (eta_t*f)[:,None] * Xi_w
def plaeng(self,X,ao_rayahang=0):
if(X.ndim==1):
x_w = X-self.w
i = np.argmin((x_w**2).sum(1))
if(ao_rayahang):
return i,np.sqrt((x_w[i]**2).sum())
else:
return i
else:
if(ao_rayahang):
c_klai = []
rayahang2 = []
for x_w_2 in ((X[:,None]-self.w)**2).sum(2):
i = np.argmin(x_w_2)
c_klai.append(i)
rayahang2.append(x_w_2[i])
rayahang = np.sqrt(np.array(rayahang2))
return np.array(c_klai),rayahang
else:
return np.array([np.argmin(x_w_2) for x_w_2 in ((X[:,None]-self.w)**2).sum(2)])
def plaengklap(self,c=None):
if(c==None):
return self.w
else:
return self.w[c]
def rianru_plaeng(self,X,n_thamsam=100,ao_rayahang=0):
self.rianru(X,n_thamsam)
return self.plaeng(X,ao_rayahang)
n = 300
theta = np.random.normal(np.linspace(0,360,n),25)
r = np.random.normal(1,0.1,n)
x = np.cos(np.radians(theta))*r
y = np.sin(np.radians(theta))*r
X = np.array([x,y]).T
si = np.linspace(0,1,n)
nu = 80
eta = 0.5
n_thamsam = 100
som = SOM_1miti(nu,eta)
som.rianru(X,n_thamsam) # เรียนรู้
x_,y_ = som.plaeng(X,1) # แปลง โดยให้คืนค่าระยะห่างมาด้วย
# หรือเขียนควบ ๒ ขั้นตอนด้วย x_,y_ = som.rianru_plaeng(X,thamsam,1)
w = som.plaengklap()
plt.axes(aspect=1)
plt.scatter(x,y,c=si,edgecolor='k',cmap='rainbow') # จุดข้อมูล
plt.plot(w[:,0],w[:,1],'-ok') # จุดโครงข่าย
plt.figure()
plt.scatter(x_,y_,c=si,edgecolor='k',cmap='rainbow') # จุดข้อมูลในพิกัดของโครงข่าย
plt.xlabel(u'ตำแหน่งบนเส้น',family='Tahoma',size=14)
plt.ylabel(u'ระยะห่าง',family='Tahoma',size=14)
plt.show()
class SOM:
def __init__(self,ruprang=(20,20),eta=0.1):
if(type(ruprang)==int):
self.ruprang = [ruprang]
else:
self.ruprang = ruprang
self.eta = eta
self.miti = len(ruprang)
self.r = max(self.ruprang)
def rianru(self,X,n_thamsam=100):
self.tau = n_thamsam/np.log(self.r)
w = [np.random.uniform(X[:,i].min(),X[:,i].max(),np.prod(self.ruprang)) for i in range(X.shape[1])]
self.w = w = np.array(w).T
c = np.meshgrid(*[np.arange(i) for i in self.ruprang],indexing='ij')
self.c = c = np.stack(c,-1).reshape(-1,self.miti)
for t in range(n_thamsam):
e = np.exp(-t/self.tau)
self.r_t = self.r*e
self.eta_t = self.eta*e
for x in np.random.permutation(X):
x_w = x-w
i = np.argmin((x_w**2).sum(1))
c_klaisut = self.c[i]
d2 = ((self.c-c_klaisut)**2).sum(1)
f = np.exp(-0.5*d2/self.r_t**2)
w += (self.eta_t*f)[:,None]*x_w
def plaeng(self,X,ao_rayahang=0):
if(X.ndim==1):
x_w = X-self.w
i = np.argmin((x_w**2).sum(1))
if(ao_rayahang):
return self.c[i],np.sqrt((x_w[i]**2).sum())
else:
return self.c[i]
else:
if(ao_rayahang):
w_klai = []
rayahang2 = []
for x_w_2 in ((X[:,None]-self.w)**2).sum(2):
i = np.argmin(x_w_2)
w_klai.append(self.c[i])
rayahang2.append(x_w_2[i])
rayahang = np.sqrt(np.array(rayahang2))
return np.array(w_klai),rayahang
else:
return np.array([self.c[np.argmin(x_w_2)] for x_w_2 in ((X[:,None]-self.w)**2).sum(2)])
def plaengklap(self,c=None):
w = self.w.reshape(list(self.ruprang)+[-1])
if(c==None):
return w.transpose(np.arange(self.miti-1,-2,-1))
elif(c.ndim==1):
return w[tuple(c)]
else:
return np.array([w[tuple(ci)] for ci in c])
def rianru_plaeng(self,X,n_thamsam=100,ao_rayahang=0):
self.rianru(X,n_thamsam)
return self.plaeng(X,ao_rayahang)
X = np.random.random([1000,3])
ruprang = [50,50]
som = SOM(ruprang,0.1)
som.rianru(X,200)
Xsom,h = som.plaeng(X,1)
m = som.plaengklap()
from mpl_toolkits.mplot3d import Axes3D
plt.imshow(m)
plt.figure(figsize=[6,6])
ax = plt.axes([0,0,1,1],projection='3d',xlim=[0,1],ylim=[0,1],zlim=[0,1])
ax.plot_surface(m[:,:,0],m[:,:,1],m[:,:,2],facecolors=m,rstride=1,cstride=1,alpha=0.8,color='b',edgecolor='k')
plt.show()
from sklearn import datasets
wine = datasets.load_wine()
X = wine.data
X = (X-X.mean(0))/X.std(0)
Xsom = SOM([100,100],eta=0.1).rianru_plaeng(X,100)
plt.axes(aspect=1)
plt.scatter(Xsom[:,0],Xsom[:,1],c=wine.target,alpha=0.6,edgecolor='k',cmap='jet')
plt.show()
ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ