larsupilami73

Yingyang classification animation

Dec 16th, 2020
1,453
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.26 KB | None | 0 0
  1. #!/usr/bin/python3
  2. #
  3. #Yingyang 2D function classification:
  4. #A 4-class unbalanced dataset, for if you're tired of the classical XOR.
  5. #Using a (large) number of randomly-chosen radial basis functions (RBFs) in front of a logistic regression (LR).
  6. #The individual RBFs 'measure' the distance from their centres to a point in the dataset.
  7. #Note there's no separare test set, as this would make the script a bit more complicated and
  8. #the performance is obvious from the images.
  9. #The dataset is unbalanced (less green/yellow dots than red/blue), so it makes sense that the first
  10. #models ignore the less-present classes.
  11. #
  12. #larsupilami73
  13.  
  14.  
  15. #imports
  16. import os,sys
  17. from scipy import *
  18. import matplotlib.pyplot as plt
  19. from sklearn.linear_model import LogisticRegression
  20. from sklearn.model_selection import cross_val_score
  21.  
  22.  
  23. #generator for the yingyang dataset
  24. def yingyang(n=10000):
  25.     while (n>0):
  26.         n -=1
  27.         r = random.uniform(0,0.5)
  28.         a = random.uniform(0,2*pi)
  29.         x = 0.5 + r * cos(a)
  30.         y = 0.5 + r * sin(a)
  31.         if sqrt((x-0.25)**2 + (y-0.5)**2)<0.12:
  32.             c = 0
  33.         elif sqrt((x-0.75)**2 + (y-0.5)**2)<0.12:
  34.             c = 1
  35.         elif sqrt((x-0.25)**2 + (y-0.5)**2)<0.25:
  36.             c = 2
  37.         elif sqrt((x-0.75)**2 + (y-0.5)**2)<0.25:
  38.             c = 3
  39.         elif y > 0.5:
  40.             c = 3
  41.         else:
  42.             c = 2
  43.         yield (x,y,c)
  44.  
  45.    
  46. #main    
  47. if __name__ == '__main__':
  48.    
  49.     numframes = 25
  50.     try:
  51.         os.mkdir('frames')
  52.     except:
  53.         pass
  54.     try:
  55.         os.system('rm -f ./frames/*.png')   #remove previous run frames
  56.     except:
  57.         pass
  58.        
  59.     #generate the 'ground truth' dataset
  60.     L,C = [],[]
  61.     X,Y = [[],[],[],[]],[[],[],[],[]]
  62.     for x,y,c in yingyang():
  63.         L.append([x,y,c])
  64.         C.append(c)
  65.         X[c].append(x)
  66.         Y[c].append(y)
  67.        
  68.     L = array(L)
  69.     #savetxt('yingyang.txt',L,fmt='%.6f %.6f %i',header='yingyang dataset.\nX   Y   Class') #save it
  70.    
  71.     #plot the ground truth
  72.     fig,(ax1,ax2) = plt.subplots(1,2,figsize=(8,4))    
  73.     colors = ['green','orange','blue','red']
  74.     for c in range(4):
  75.         ax1.scatter(X[c],Y[c],s=5,c=colors[c],label='class %i'%c)
  76.     ax1.legend(loc='upper right',ncol=1,markerscale=2.0,fontsize='small')
  77.     ax1.set_xlabel('X')
  78.     ax1.set_ylabel('Y')
  79.     ax1.set_title('Ground truth')
  80.     ax1.set_aspect(1)
  81.    
  82.     #lets first try a logistic regression on the ground truth
  83.     P = array([[x_,y_] for x_,y_,c_ in L])
  84.     clf = LogisticRegression(random_state=0,solver='lbfgs',multi_class='auto')
  85.     scores = cross_val_score(clf, P, C, cv=5)
  86.     print('Only LR scores: ',scores)
  87.     print("Only LR accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
  88.    
  89.     #make a drawing to show what the logistic regression resulted in
  90.     clf.fit(P,C)
  91.     score = clf.score(P,C)
  92.     print('Train score entire dataset: %2.3g'%score)
  93.     prediction = clf.predict(P)
  94.     XP,YP = [[],[],[],[]],[[],[],[],[]]
  95.     for c,p in zip(prediction,P):
  96.         XP[c].append(p[0])
  97.         YP[c].append(p[1])
  98.    
  99.     for c in range(4):
  100.         ax2.scatter(XP[c],YP[c],s=5,c=colors[c],label=None)#'class %i'%c)
  101.     #draw the errors more clearly
  102.     fe = False
  103.     for ce,p,c in zip(prediction,P,C):
  104.         if ce != c:
  105.             if fe:
  106.              ax2.scatter([p[0]],[p[1]],s=8,linewidth=0.75,c='none',edgecolors= "black",label=None)
  107.             else:
  108.                 ax2.scatter([p[0]],[p[1]],s=8,c='none',linewidth=0.75,edgecolors= "black",label='errors')
  109.                 fe = True
  110.    
  111.     ax2.legend(loc='upper right',ncol=2,markerscale=2.0,fontsize='small')
  112.     ax2.set_xlabel('X')
  113.     #ax2.set_ylabel('Y')
  114.     ax2.set_title('LR only. Score: %2.3g'%score)
  115.     ax2.set_aspect(1)
  116.    
  117.     plt.savefig('./frames/frame%05d.png'%0)
  118.     ax2.cla()
  119.    
  120.    
  121.     #Now lets construct new features which are nonlinear functions of X and Y.
  122.     #Here we choose random radial basis functions (RBF).
  123.     #Then check how well the LR does when fed by these new features
  124.     R,S = [],[] #center positions and radii of the RBFs
  125.     for frame in range(1,numframes+1):
  126.         print('frame %i/%i'%(frame,numframes))
  127.         nrbf = frame
  128.         R.append(random.normal(size=2,loc=[0.5,0.5],scale=0.25))  #center positions of the RBFs
  129.         S.append(random.uniform(low=0.1,high=0.3))             #radii of the RBFs
  130.         Z = array([[ exp(-((p_[0]-r_[0])**2+(p_[1]-r_[1])**2)/s_**2) for r_,s_ in zip(R,S) ] for p_ in P])
  131.         clf2 = LogisticRegression(random_state=0,solver='lbfgs',multi_class='multinomial',max_iter=1000)
  132.         clf2.fit(Z,C)
  133.         score = clf2.score(Z,C)
  134.         print('Train score with %i RBFs: %2.3g'%(nrbf,score))
  135.         XP,YP = [[],[],[],[]],[[],[],[],[]]
  136.         prediction = clf2.predict(Z)
  137.         for c,p in zip(prediction,P):
  138.             XP[c].append(p[0])
  139.             YP[c].append(p[1])
  140.            
  141.         for c in range(4):
  142.             ax2.scatter(XP[c],YP[c],s=5,c=colors[c],label=None)#'class %i'%c) too many labels overloads picture
  143.        
  144.         #draw the errors more clearly
  145.         fe = False
  146.         for ce,p,c in zip(prediction,P,C):
  147.             if ce != c:
  148.                 if fe:
  149.                  ax2.scatter([p[0]],[p[1]],s=8,linewidth=0.75,c='none',edgecolors= "black",label=None)
  150.                 else:
  151.                     ax2.scatter([p[0]],[p[1]],s=8,linewidth=0.75,c='none',edgecolors= "black",label='error')
  152.                     fe = True
  153.        
  154.         ax2.legend(loc='upper right',ncol=2,markerscale=2.0,fontsize='small')
  155.         ax2.set_xlabel('X')
  156.         #ax2.set_label('Y')
  157.         ax2.set_title('%i RBFs --> LR. Score: %2.3g' %(nrbf,score))
  158.         ax2.set_aspect(1)
  159.         #draw the RBFs position and radius
  160.         #for r,s in zip(R,S):
  161.         #    ax2.add_artist(plt.Circle(r,s,linestyle='--',linewidth=0.5,alpha=0.7,fill=False))
  162.            
  163.         plt.savefig('./frames/frame%05d.png'%frame)
  164.         ax2.cla()
  165.    
  166.  
  167. plt.close()
  168.  
  169. #now assemble all the pictures in a movie
  170. print('converting to gif!')
  171. os.system('convert -delay 40 -loop 0 ./frames/*.png yingyang.gif')
  172. #or to mp4 with .mp4
  173. #print('converting to mp4!')
  174. #os.system("ffmpeg -y -r 40 -i ./frames/frame%05d.png -c:v libx264 -vf fps=20 yingyang.mp4")
  175.  
Advertisement
Add Comment
Please, Sign In to add comment