#! /usr/bin/env python3 # def generator_perceptron ( ): #*****************************************************************************80 # ## generator_perceptron demonstrates the perceptron algorithm on generator data. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 17 October 2019 # # Author: # # John Burkardt # import matplotlib.pyplot as plt import numpy as np import platform from perceptron_gradient import perceptron_gradient print ( '' ) print ( 'generator_perceptron' ) print ( ' Python version: %s' % ( platform.python_version ( ) ) ) print ( ' The Perceptron.' ) print ( ' Data file: index, rpm, vibration, rating' ) print ( ' Rating is 0 for failing, 1 for active.' ) 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 ( 'generator_data.txt' ) # # Copy columns of data into variables. # rpm = data[:,1] vib = data[:,2] act = data[:,3] # # Count the number of cases. # m = len ( rpm ) print ( '' ) print ( ' Number of generators = %d' % ( m ) ) # # Part 1. # rpm_min = np.min ( rpm ) rpm_max = np.max ( rpm ) vib_min = np.min ( vib ) vib_max = np.max ( vib ) good = ( 0.0 < act ) bad = ( act <= 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 = 'generator_data.png' plt.savefig ( filename ) plt.show ( ) print ( ' Graphics saved as "%s"' % ( filename ) ) # # 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. # x = np.zeros ( [ m, 3 ] ) x[:,0] = 1.0 x[:,1] = r x[:,2] = v y = np.copy ( act ) alpha = 0.01 stepmax = 100 w0 = np.ones ( 3 ) / 3.0 w, e, step = perceptron_gradient ( x, y, alpha, stepmax, w0 ) # step = 0 # while ( step < 100 ): # e = 0 # step = step + 1 # for i in range ( 0, m ): # y = np.dot ( w[:], x[i,:] ) # f = ( 0 < y ) # e = e + ( act[i] != f ) # w = w + alpha * np.dot ( ( act[i] - f ), x[i,:] ) # w = w / np.linalg.norm ( w ) # if ( e == 0 ): # break 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 ( 'Perceptron Classifier for Generator Ratings' ) plt.grid ( True ) plt.axis ( 'equal' ) filename = 'generator_perceptron.png' plt.savefig ( filename ) plt.show ( ) print ( ' Graphics saved as "%s"' % ( filename ) ) # # Terminate. # print ( '' ) print ( 'generator_perceptron' ) print ( ' Normal end of execution.' ) return if ( __name__ == '__main__' ): generator_perceptron ( )