Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- #
- #XOR 2D function classification:
- #The XOR function in the plane is not linearly separable: a single straight line in the cannot divide the classes (reds and blues),
- #so a simple logistic regression (LR) fails.
- #Using a (large) number of randomly-chosen radial basis functions (RBFs) enables linear separation.
- #The individual RBFs 'measure' the distance from their centres to a point in the dataset.
- #Note there's no separare test set, as this would make the script a bit more complicated and
- #the performance is obvious from the images.
- #
- #larsupilami73
- #imports
- import os,sys
- from scipy import *
- import matplotlib.pyplot as plt
- from sklearn.linear_model import LogisticRegression
- from sklearn.model_selection import cross_val_score
- #generator for the xor dataset
- def xor(n=10000):
- while (n>0):
- n -=1
- x = random.uniform(0,1)
- y = random.uniform(0,1)
- if (x<0.5 and y<0.5) or (x>0.5 and y>0.5):
- c = 0
- else:
- c = 1
- yield (x,y,c)
- #main
- if __name__ == '__main__':
- numframes = 25
- try:
- os.mkdir('frames')
- except:
- pass
- try:
- os.system('rm -f ./frames/*.png') #remove previous run frames
- except:
- pass
- #generate the 'ground truth' dataset
- L,C = [],[]
- X,Y = [[],[],[],[]],[[],[],[],[]]
- for x,y,c in xor():
- L.append([x,y,c])
- C.append(c)
- X[c].append(x)
- Y[c].append(y)
- L = array(L)
- #savetxt('xor.txt',L,fmt='%.6f %.6f %i',header='xor dataset.\nX Y Class') #save it
- #plot the ground truth
- fig,(ax1,ax2) = plt.subplots(1,2,figsize=(8,4))
- colors = ['blue','red']
- for c in range(2):
- ax1.scatter(X[c],Y[c],s=5,c=colors[c],label='class %i'%c)
- ax1.legend(loc='upper right',ncol=1,markerscale=2.0)
- ax1.set_xlabel('X')
- ax1.set_ylabel('Y')
- ax1.set_title('Ground truth XOR')
- #lets first try a logistic regression on the ground truth
- P = array([[x_,y_] for x_,y_,c_ in L])
- clf = LogisticRegression(random_state=0,solver='lbfgs',multi_class='auto')
- scores = cross_val_score(clf, P, C, cv=5)
- print('Only LR scores: ',scores)
- print("Only LR accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
- #make a drawing to show what the logistic regression resulted in
- clf.fit(P,C)
- score = clf.score(P,C)
- print('Train score entire dataset: %2.3g'%score)
- prediction = clf.predict(P)
- XP,YP = [[],[],[],[]],[[],[],[],[]]
- for c,p in zip(prediction,P):
- XP[c].append(p[0])
- YP[c].append(p[1])
- for c in range(2):
- ax2.scatter(XP[c],YP[c],s=5,c=colors[c],label='class %i'%c)
- #draw the errors more clearly
- fe = False
- for ce,p,c in zip(prediction,P,C):
- if ce != c:
- if fe:
- ax2.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label=None)
- else:
- ax2.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label='errors')
- fe = True
- ax2.legend(loc='upper right',ncol=1,markerscale=2.0)
- ax2.set_xlabel('X')
- ax2.set_ylabel('Y')
- ax2.set_title('LR only. Score: %2.3g'%score)
- plt.savefig('./frames/frame%05d.png'%0)
- ax2.cla()
- #Now lets construct new features which are nonlinear functions of X and Y.
- #Here we choose random radial basis functions (RBF).
- #Then check how well the LR does when fed by these new features
- R,S = [],[] #center positions and radii of the RBFs
- for frame in range(1,numframes+1):
- print('frame %i/%i'%(frame,numframes))
- nrbf = frame
- R.append(random.normal(size=2,loc=[0.5,0.5],scale=0.25)) #center positions of the RBFs
- S.append(random.uniform(low=0.1,high=0.3)) #radii of the RBFs
- 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])
- clf2 = LogisticRegression(random_state=0,solver='lbfgs',multi_class='multinomial',max_iter=1000)
- clf2.fit(Z,C)
- score = clf2.score(Z,C)
- print('Train score with %i RBFs: %2.3g'%(nrbf,score))
- XP,YP = [[],[],[],[]],[[],[],[],[]]
- prediction = clf2.predict(Z)
- for c,p in zip(prediction,P):
- XP[c].append(p[0])
- YP[c].append(p[1])
- for c in range(2):
- ax2.scatter(XP[c],YP[c],s=5,c=colors[c],label='class %i'%c)
- #draw the errors more clearly
- fe = False
- for ce,p,c in zip(prediction,P,C):
- if ce != c:
- if fe:
- plt.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label=None)
- else:
- plt.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label='error')
- fe = True
- ax2.legend(loc='upper right',ncol=1,markerscale=2.0)
- ax2.set_xlabel('X')
- ax2.set_label('Y')
- ax2.set_title('%i RBFs --> LR. Score: %2.3g' %(nrbf,score))
- #draw the RBFs position and radius
- for r,s in zip(R,S):
- ax2.add_artist(plt.Circle(r,s,linestyle='--',linewidth=0.5,alpha=0.7,fill=False))
- plt.savefig('./frames/frame%05d.png'%frame)
- ax2.cla()
- plt.close()
- #now assemble all the pictures in a movie
- print('converting to gif!')
- os.system('convert -delay 40 -loop 0 ./frames/*.png xor.gif')
- #or to mp4 with .mp4
- #print('converting to mp4!')
- #os.system("ffmpeg -y -r 40 -i ./frames/frame%05d.png -c:v libx264 -vf fps=20 xor.mp4")
Advertisement
Add Comment
Please, Sign In to add comment