O'Reilly Japan - 実践 コンピュータビジョン
実践コンピュータビジョン サンプルプログラム
相変わらずの上記urlの写経。
k近傍法とは?
次のurlが視覚的にもとっても分かりやすいです
qiita.com
教師データとテストデータの作成
…といっても、中身は同じである points_normal.pkl と points_normal_test.pkl が
以下のscriptで作成されます。
import numpy
import pickle
n = 200
def main():
make_dots_pair_1()
make_dots_pair_2()
def make_dots_pair_1():
class_1 = 0.6 * numpy.random.randn(n,2)
class_2 = 1.2 * numpy.random.randn(n,2) + numpy.array([5,1])
labels = numpy.hstack((numpy.ones(n),-numpy.ones(n)))
with open('points_normal.pkl', 'w') as f:
pickle.dump(class_1,f)
pickle.dump(class_2,f)
pickle.dump(labels,f)
with open('points_normal_test.pkl', 'w') as f:
pickle.dump(class_1,f)
pickle.dump(class_2,f)
pickle.dump(labels,f)
def make_dots_pair_2():
class_1 = 0.6 * numpy.random.randn(n,2)
r = 0.8 * numpy.random.randn(n,1) + 5
angle = 2*numpy.pi * numpy.random.randn(n,1)
class_2 = numpy.hstack((r*numpy.cos(angle),r*numpy.sin(angle)))
labels = numpy.hstack((numpy.ones(n),-numpy.ones(n)))
with open('points_ring.pkl', 'w') as f:
pickle.dump(class_1,f)
pickle.dump(class_2,f)
pickle.dump(labels,f)
if __name__ == '__main__':
main()
k-NN実行
import numpy
import pickle
import matplotlib
matplotlib.use('Agg')
import matplotlib.pylab as plb
KNN_MODEL = None
def load_model_and_test_data():
with open('points_normal.pkl', 'r') as f:
class_1 = pickle.load(f)
class_2 = pickle.load(f)
labels = pickle.load(f)
global KNN_MODEL
KNN_MODEL = KnnClassifier(labels, numpy.vstack((class_1,class_2)))
with open('points_normal_test.pkl', 'r') as f:
class_1 = pickle.load(f)
class_2 = pickle.load(f)
labels = pickle.load(f)
return class_1, class_2, labels
def my_classify(x,y):
return numpy.array([KNN_MODEL.classify([xx,yy]) for (xx,yy) in zip(x,y)])
def plot_2D_boundary(plot_range,points,decisionfcn,labels,values=[0]):
""" plot_range:(xmin,xmax,ymin,ymax)、points:クラスの点のリスト、
decisionfcn:評価関数、
labels:各クラスについてdecisionfcnが返すラベルのリスト、
values:表示する判別の輪郭のリスト """
clist = ['b','r','g','k','m','y']
x = numpy.arange(plot_range[0],plot_range[1],.1)
y = numpy.arange(plot_range[2],plot_range[3],.1)
xx,yy = numpy.meshgrid(x,y)
xxx,yyy = xx.flatten(),yy.flatten()
zz = numpy.array(decisionfcn(xxx,yyy))
zz = zz.reshape(xx.shape)
plb.contour(xx,yy,zz)
for i in range(len(points)):
d = decisionfcn(points[i][:,0],points[i][:,1])
correct_ndx = labels[i]==d
incorrect_ndx = labels[i]!=d
plb.plot(points[i][correct_ndx,0],points[i][correct_ndx,1],
'*',color=clist[i])
plb.plot(points[i][incorrect_ndx,0],points[i][incorrect_ndx,1],
'o',color=clist[i])
plb.axis('equal')
class KnnClassifier(object):
def __init__(self,labels,samples):
""" 教師データを使って分類器を初期化する """
self.labels = labels
self.samples = samples
def classify(self,point,k=3):
""" pointを教師データ中のk個の最近傍を使って分類し、
ラベルを返す """
dist = numpy.array([L2dist(point,s) for s in self.samples])
ndx = dist.argsort()
votes = {}
for i in range(k):
label = self.labels[ndx[i]]
votes.setdefault(label,0)
votes[label] += 1
return max(votes, key=lambda x: votes.get(x))
def L2dist(p1,p2):
return numpy.sqrt( sum( (p1-p2)**2) )
def main():
class_1, class_2, labels = load_model_and_test_data()
plot_2D_boundary([-6,6,-6,6], [class_1,class_2], my_classify,[1,-1])
plb.savefig( '8_1_1.png' )
if __name__ == '__main__':
main()
↑こう書くと↓こう出力されます