#! /usr/bin/env python3 # def perceptron_test ( ): #*****************************************************************************80 # ## perceptron_test() demonstrates the perceptron algorithm. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 28 June 2019 # # Author: # # John Burkardt # import matplotlib.pyplot as plt import numpy as np import platform print ( '' ) print ( 'perceptron_test' ) print ( ' Python version: %s' % ( platform.python_version ( ) ) ) print ( ' The Perceptron.' ) print ( ' Data file: index, rpm, vibration, rating' ) print ( ' Rating is 0 for bad, 1 for good.' ) print ( ' Use the perceptron algorithm to determine a' ) print ( ' classifier f(rpm,vibration) -> {0, 1}' ) # # Read the data file. # print ( '' ) print ( ' Generator Ratings' ) data = np.loadtxt ( 'generators.txt' ) # # Copy columns of data into variables. # rpm = data[:,1] vib = data[:,2] grade = data[:,3] # # Count the number of cases. # n = len ( rpm ) print ( '' ) print ( ' Number of generators = %d' % ( n ) ) # # Part 1. # rpm_min = np.min ( rpm ) rpm_max = np.max ( rpm ) vib_min = np.min ( vib ) vib_max = np.max ( vib ) good = ( grade == +1.0 ) bad = ( grade == 0.0 ) n_good = len ( good ) n_bad = len ( bad ) bad_rpm_mean = np.mean ( rpm[bad] ) bad_vib_mean = np.mean ( vib[bad] ) good_rpm_mean = np.mean ( rpm[good] ) good_vib_mean = np.mean ( vib[good] ) print ( ' %d good generators, and %d bad generators' % ( n_good, n_bad ) ) print ( ' %g <= RPM <= %g' % ( rpm_min, rpm_max ) ) print ( ' %g <= VIB <= %g' % ( vib_min, vib_max ) ) print ( ' GOOD: mean RPM = %g, mean VIB = %g' % ( good_rpm_mean, good_vib_mean ) ) print ( ' BAD: mean RPM = %g, mean VIB = %g' % ( bad_rpm_mean, bad_vib_mean ) ) print ( ' %g <= VIB <= %g' % ( vib_min, vib_max ) ) plt.plot ( rpm[good], vib[good], 'b+', rpm[bad], vib[bad], 'ro' ) plt.xlabel ( '<-- RPM -->' ) plt.ylabel ( '<-- VIB -->' ) plt.title ( 'Generator Ratings' ) plt.grid ( True ) plt.axis ( 'equal' ) filename = 'perceptron_data.png' plt.savefig ( filename ) plt.show ( block = False ) print ( ' Graphics saved as "%s"' % ( filename ) ) plt.close ( ) # # Part 2. # # # Work with normalized data. # r = ( rpm - np.min ( rpm ) ) / ( np.max ( rpm ) - np.min ( rpm ) ) v = ( vib - np.min ( vib ) ) / ( np.max ( vib ) - np.min ( vib ) ) # # Perceptron algorithm. # alpha = 0.01 m = 3 w = np.ones ( m ) / m x = np.zeros ( [ n, 3 ] ) x[:,0] = 1.0 x[:,1] = np.copy ( r ) x[:,2] = np.copy ( v ) e = 1 step = 0 while ( e != 0 and step < 100 ): e = 0 step = step + 1 for i in range ( 0, n ): f = ( 0 < np.dot ( x[i,:], w[:] ) ) e = e + ( grade[i] != f ) w = w + alpha * np.dot ( x[i,:], ( grade[i] - f ) ) w = w / np.linalg.norm ( w ) if ( e == 0 ): print ( ' All training data classified on step %d' % ( step ) ) else: print ( ' Iteration terminated without convergence on step %d' % ( step ) ) # # Report. # print ( '' ) print ( ' Perceptron weights:' ) print ( ' f(x) = %g + %g * r + %g * v' % ( w[0], w[1], w[2] ) ) print ( '' ) print ( '' ) print ( ' Index x*w (0' ) plt.ylabel ( '<-- VIB -->' ) plt.title ( 'Generator Ratings Classifier' ) plt.grid ( True ) plt.axis ( 'equal' ) filename = 'perceptron_classifier.png' plt.savefig ( filename ) plt.show ( block = False ) print ( ' Graphics saved as "%s"' % ( filename ) ) plt.close ( ) # # Terminate. # print ( '' ) print ( 'perceptron_test' ) print ( ' Normal end of execution.' ) return def timestamp ( ): #*****************************************************************************80 # ## timestamp() prints the date as a timestamp. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 April 2013 # # Author: # # John Burkardt # import time t = time.time ( ) print ( time.ctime ( t ) ) return None if ( __name__ == '__main__' ): timestamp ( ) perceptron_test ( ) timestamp ( )