Olej писал(а):- но принадлежит к совсем другому классу (и интуитивно и по методу KNN, которым получена картинка);
Метод KNN - 1-й из рассматриваемых - метод K ближайших соседей.
Задача классификации в машинном обучении — это задача отнесения объекта к одному из заранее определенных классов на основании его формализованных признаков. Каждый из объектов в этой задаче представляется в виде вектора в N-мерном пространстве, каждое измерение в котором представляет собой описание одного из признаков объекта.
Программа
ручной реализации метода KNN, понятной по коду как он работает: объект принадлежит к тому классу, к которому принадлежат
большинство из окружения K (3, 5, 7, ...) его соседей:
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import random
import math
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def inPoint( prompt ):
while( True ):
sys.stdout.write( prompt )
sys.stdout.flush()
s = sys.stdin.readline()
if s == '\n' or s == '': # Enter or ^D - завершение ввода
sys.stdout.write( '\r' )
return None
try:
( x, y ) = s.split()
p = ( float( x ), float( y ) )
except Exception as err:
print( 'format error: ' + str( err ) )
continue
return p
def generateData( Classes, numberOfEl = 10 ): # Genegate train data
data = []
for num in range( len( Classes ) ):
for row in range( numberOfEl ): # Choose numberOfEl random nodes with RMS=1
data.append( [ [ random.gauss( Classes[ num ][ 0 ], 1.0 ),
random.gauss( Classes[ num ][ 1 ], 1.0 ) ], num ] )
return data
print( 'training center coordinates (format: X Y ; Enter or ^D - finish)' )
centers = []
while True:
z = inPoint( 'point number {} : '.format( len( centers ) + 1 ) )
if( z == None ): break;
centers.append( z )
print( centers )
if len( sys.argv ) > 1:
train = generateData( centers, int( sys.argv[ 1 ] ) )
else:
train = generateData( centers )
print( '{} => {}'.format( len( centers ), len( train ) ) )
colors = []
groups = []
for c in range( len( centers ) ):
colors.append( matplotlib.colors.to_hex( ( random.random(), random.random(), random.random() ) ) )
groups.append( 'class #{:02d}'.format( c ) )
clist = matplotlib.colors.ListedColormap( colors )
print( groups )
def classifyKNN( trainData, testData, k ): # KNN classification procedure
def dist( a, b ): #Euclidean distance between 2-dimensional point
return math.sqrt( ( a[ 0 ] - b[ 0 ] ) ** 2 + ( a[ 1 ] - b[ 1 ] ) ** 2 )
testLabels = []
for testPoint in testData:
#Claculate distances between test point and all of the train points
testDist = [ [ dist( testPoint[ 0 ], trainData[ i ][ 0 ] ), trainData[ i ][ 1 ] ]
for i in range( len( trainData ) ) ]
#How many points of each class among nearest K
stat = [ 0 for i in range( len( trainData ) ) ]
for d in sorted( testDist )[ 0:k ]:
stat[ d[ 1 ] ] += 1
#Assign a class with the most number of occurences among K nearest neighbours
testLabels.append( sorted( zip( stat, range( len( trainData ) ) ), reverse = True )[ 0 ][ 1 ] )
return testLabels
k = 5 # numner nearest neighbours
if len( sys.argv ) > 2:
k = int( sys.argv[ 2 ] )
while True:
test = []
print( 'testing points (format: X Y ; Enter or ^D - finish)' )
while True:
z = inPoint( 'point number {} : '.format( len( test ) + 1 ) )
if( z == None ): break;
test.append( [ [ z[ 0 ], z[ 1 ] ], 0 ] )
if 0 == len( test ): break
for i in range( len( centers ) ):
plt.scatter( centers[ i ][ 0 ], centers[ i ][ 1 ],
label = groups[ i ], marker = '^',
c = colors[ i ] ) # center / legend points
plt.scatter( [ train[ i ][ 0 ][ 0 ] for i in range( len( train ) ) ],
[ train[ i ][ 0 ][ 1 ] for i in range( len( train ) ) ],
c = [ train[ i ][ 1 ] for i in range( len( train ) ) ],
cmap = clist ) # train points
labels = classifyKNN( train, test, k )
print( labels )
for i in range( len( test ) ):
plt.scatter( test[ i ][ 0 ][ 0 ], test[ i ][ 0 ][ 1 ],
s = 200, marker = '+', alpha = 0.5,
c = colors[ labels[ i ] ] ) # test points
plt.legend( groups )
# pl.legend( loc = 2 )
plt.gcf().canvas.set_window_title( 'manual implementation KNN' )
plt.show()
Код: Выделить всё
<pre>olej@ACER:~/2019_WORK/own.WORK/MachineLearning$ ./modrn.py 40 7
training center coordinates (format: X Y ; Enter or ^D - finish)
point number 1 : 0 3
point number 2 : 3 3
point number 3 : 3 0
point number 4 : 0 0
point number 5 :
[(0.0, 3.0), (3.0, 3.0), (3.0, 0.0), (0.0, 0.0)]
4 => 160
['class #00', 'class #01', 'class #02', 'class #03']
testing points (format: X Y ; Enter or ^D - finish)
point number 1 : 1 1
point number 2 : 1 2
point number 3 : 2 2
point number 4 : 2 1
point number 5 :
[3, 0, 1, 3]
testing points (format: X Y ; Enter or ^D - finish)
point number 1 :
</pre>