Package rdkit :: Package ML :: Package MLUtils :: Module VoteImg

[hide private]
[frames] | no frames]

# Source Code for Module rdkit.ML.MLUtils.VoteImg

      1  ## Automatically adapted for numpy.oldnumeric Jun 27, 2008 by -c
      2
      3  #
      4  #  Copyright (C) 2000  greg Landrum
      5  #
      6
      7  """ functionality for generating an image showing the results of a composite model voting on a data set
      8
      9    Uses *Numeric* and *PIL*
     10
     11  """
     12  from __future__ import print_function
     13  import numpy
     14  from PIL import Image, ImageDraw
     15
     16 -def CollectVotes(composite,data,badOnly):
     17    """ collects the votes from _composite_ for the examples in _data_
     18
     19      **Arguments**
     20
     21        - composite: a composite model
     22
     23        - data: a list of examples to run through _composite_
     24
     25        - badOnly: if set only bad (misclassified) examples will be kept
     26
     27      **Returns**
     28
     29        a 4-tuple containing:
     30
     31          1) the expanded list of vote details (see below)
     32
     33          2) the list of predicted results
     34
     35          3) the list of true results
     36
     37          4) the number of miscounted examples
     38
     39
     40      **Notes**
     41
     42  pp      - the expanded list of vote details consists of:
     43
     44          '[ vote1, vote2, ... voteN, 0, res, trueRes]'
     45
     46          where _res_ is the predicted results and _trueRes_ is the actual result.
     47          The extra zero is included to allow a line to be drawn between the votes
     48          and the results.
     49
     50    """
     51    res = []
     52    values = []
     53    trueValues = []
     54    misCount = 0
     55    for pt in data:
     56      val,err = composite.ClassifyExample(pt)
     57      predict = pt[-1]
     58      if not badOnly or val != predict:
     59        values.append(val)
     60        trueValues.append(predict)
     61        if val != predict:
     62          misCount = misCount + 1
     63        res.append(composite.GetVoteDetails()+[0,val,pt[-1]])
     64    return res,values,trueValues,misCount
     65
     66 -def BuildVoteImage(nModels,data,values,trueValues=[],
     67                     sortTrueVals=0,xScale=10,yScale=2,
     68                     addLine=1):
     69    """ constructs the actual image
     70
     71      **Arguments**
     72
     73        - nModels: the number of models in the composite
     74
     75        - data: the results of voting
     76
     77        - values: predicted values for each example
     78
     79        - trueValues: true values for each example
     80
     81        - sortTrueVals: if nonzero the votes will be sorted so
     82          that the _trueValues_ are in order, otherwise the sort
     83          is by _values_
     84
     85        - xScale: number of pixels per vote in the x direction
     86
     87        - yScale: number of pixels per example in the y direction
     88
     89        - addLine: if nonzero, a purple line is drawn separating
     90           the votes from the examples
     91
     92      **Returns**
     93
     94        a PIL image
     95
     96    """
     97    nData = len(data)
     98    data = numpy.array(data,numpy.integer)
     99    if sortTrueVals and trueValues != []:
    100      order = numpy.argsort(trueValues)
    101    else:
    102      order = numpy.argsort(values)
    103    data = [data[x] for x in order]
    104    maxVal = max(numpy.ravel(data))
    105    data = data * 255 / maxVal
    106    img = Image.fromstring('L',(nModels,nData),data.astype('B').tostring())
    107
    108    if addLine:
    109      img = img.convert('RGB')
    110      canvas = ImageDraw.Draw(img)
    111      if trueValues != []:
    112        canvas.line([(nModels-3,0),(nModels-3,nData)],fill=(128,0,128))
    113      else:
    114        canvas.line([(nModels-2,0),(nModels-2,nData)],fill=(128,0,128))
    115    img = img.resize((nModels*xScale,nData*yScale))
    116    return img
    117
    118
    119 -def VoteAndBuildImage(composite,data,badOnly=0,sortTrueVals=0,
    120                     xScale=10,yScale=2,addLine=1):
    121    """ collects votes on the examples and constructs an image
    122
    123      **Arguments**
    124
    125        - composte: a composite model
    126
    127        - data: the examples to be voted upon
    128
    129        - badOnly: if nonzero only the incorrect votes will be shown
    130
    131        - sortTrueVals: if nonzero the votes will be sorted so
    132          that the _trueValues_ are in order, otherwise the sort
    133          is by _values_
    134
    135        - xScale: number of pixels per vote in the x direction
    136
    137        - yScale: number of pixels per example in the y direction
    138
    139        - addLine: if nonzero, a purple line is drawn separating
    140           the votes from the examples
    141
    142      **Returns**
    143
    144        a PIL image
    145
    146
    147    """
    148    nModels = len(composite)+3
    149    print('nModels:',nModels-3)
    150
    151    res,values,trueValues,misCount = CollectVotes(composite,data,badOnly)
    152    print('%d examples were misclassified'%misCount)
    153    img = BuildVoteImage(nModels,res,values,trueValues,sortTrueVals,
    154                         xScale,yScale,addLine)
    155    return img
    156
    157 -def Usage():
    158    """ provides a list of arguments for when this is used from the command line
    159
    160    """
    161    import sys
    162
    163    print('Usage: VoteImg.py [optional arguments] <modelfile.pkl> <datafile.qdat>')
    164    print('Optional Arguments:')
    165    print('\t-o outfilename: the name of the output image file.')
    166    print('\t                The extension determines the type of image saved.')
    167    print('\t-b: only include bad (misclassified) examples')
    168    print('\t-t: sort the results by the true (input) classification')
    169    print('\t-x scale: scale the image along the x axis (default: 10)')
    170    print('\t-y scale: scale the image along the y axis (default: 2)')
    171    print('\t-d databasename: instead of using a qdat file, pull the data from')
    172    print('\t                 a database.  In this case the filename argument')
    173    print('\t                 is used to indicate the name of the table in the database.')
    174
    175    sys.exit(-1)
    176
    177  if __name__ == '__main__':
    178    import sys,getopt
    179    from rdkit.six.moves import cPickle
    180    from rdkit.ML.Data import DataUtils
    181
    182    args,extra = getopt.getopt(sys.argv[1:],'o:bthx:y:d:')
    183    if len(extra) < 2:
    184      Usage()
    185    badOnly = 0
    186    sortTrueVals = 0
    187    xScale=10
    188    yScale=2
    189    dbName = ''
    190    outFileName='foo.png'
    191    for arg,val in args:
    192      if arg == '-b':
    193        badOnly = 1
    194      elif arg == '-t':
    195        sortTrueVals = 1
    196      elif arg == '-o':
    197        outFileName = val
    198      elif arg == '-x':
    199        xScale = int(val)
    200      elif arg == '-y':
    201        yScale = int(val)
    202      elif arg == '-d':
    203        dbName = val
    204      elif arg == '-h':
    205        Usage()
    206      else:
    207        Usage()
    208    modelFile=open(extra[0],'rb')
    209    model = cPickle.load(modelFile)
    210
    211    fName= extra[1]
    212    if dbName == '':
    213      data = DataUtils.BuildQuantDataSet(fName)
    214    else:
    215      data = DataUtils.DBToQuantData(dbName,fName)
    216
    217    dataSet = data.GetNamedData()
    218
    219    img = VoteAndBuildImage(model,dataSet,badOnly=badOnly,sortTrueVals=sortTrueVals,
    220                         xScale=xScale,yScale=yScale)
    221    img.save(outFileName)
    222