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    datab = data.astype('B')
    107    img = getattr(Image,'frombytes',Image.fromstring)('L',(nModels,nData),getattr(datab,'tobytes',datab.tostring)())
    108
    109    if addLine:
    110      img = img.convert('RGB')
    111      canvas = ImageDraw.Draw(img)
    112      if trueValues != []:
    113        canvas.line([(nModels-3,0),(nModels-3,nData)],fill=(128,0,128))
    114      else:
    115        canvas.line([(nModels-2,0),(nModels-2,nData)],fill=(128,0,128))
    116    img = img.resize((nModels*xScale,nData*yScale))
    117    return img
    118
    119
    120 -def VoteAndBuildImage(composite,data,badOnly=0,sortTrueVals=0,
    121                     xScale=10,yScale=2,addLine=1):
    122    """ collects votes on the examples and constructs an image
    123
    124      **Arguments**
    125
    126        - composte: a composite model
    127
    128        - data: the examples to be voted upon
    129
    130        - badOnly: if nonzero only the incorrect votes will be shown
    131
    132        - sortTrueVals: if nonzero the votes will be sorted so
    133          that the _trueValues_ are in order, otherwise the sort
    134          is by _values_
    135
    136        - xScale: number of pixels per vote in the x direction
    137
    138        - yScale: number of pixels per example in the y direction
    139
    140        - addLine: if nonzero, a purple line is drawn separating
    141           the votes from the examples
    142
    143      **Returns**
    144
    145        a PIL image
    146
    147
    148    """
    149    nModels = len(composite)+3
    150    print('nModels:',nModels-3)
    151
    152    res,values,trueValues,misCount = CollectVotes(composite,data,badOnly)
    153    print('%d examples were misclassified'%misCount)
    154    img = BuildVoteImage(nModels,res,values,trueValues,sortTrueVals,
    155                         xScale,yScale,addLine)
    156    return img
    157
    158 -def Usage():
    159    """ provides a list of arguments for when this is used from the command line
    160
    161    """
    162    import sys
    163
    164    print('Usage: VoteImg.py [optional arguments] <modelfile.pkl> <datafile.qdat>')
    165    print('Optional Arguments:')
    166    print('\t-o outfilename: the name of the output image file.')
    167    print('\t                The extension determines the type of image saved.')
    168    print('\t-b: only include bad (misclassified) examples')
    169    print('\t-t: sort the results by the true (input) classification')
    170    print('\t-x scale: scale the image along the x axis (default: 10)')
    171    print('\t-y scale: scale the image along the y axis (default: 2)')
    172    print('\t-d databasename: instead of using a qdat file, pull the data from')
    173    print('\t                 a database.  In this case the filename argument')
    174    print('\t                 is used to indicate the name of the table in the database.')
    175
    176    sys.exit(-1)
    177
    178  if __name__ == '__main__':
    179    import sys,getopt
    180    from rdkit.six.moves import cPickle
    181    from rdkit.ML.Data import DataUtils
    182
    183    args,extra = getopt.getopt(sys.argv[1:],'o:bthx:y:d:')
    184    if len(extra) < 2:
    185      Usage()
    186    badOnly = 0
    187    sortTrueVals = 0
    188    xScale=10
    189    yScale=2
    190    dbName = ''
    191    outFileName='foo.png'
    192    for arg,val in args:
    193      if arg == '-b':
    194        badOnly = 1
    195      elif arg == '-t':
    196        sortTrueVals = 1
    197      elif arg == '-o':
    198        outFileName = val
    199      elif arg == '-x':
    200        xScale = int(val)
    201      elif arg == '-y':
    202        yScale = int(val)
    203      elif arg == '-d':
    204        dbName = val
    205      elif arg == '-h':
    206        Usage()
    207      else:
    208        Usage()
    209    modelFile=open(extra[0],'rb')
    210    model = cPickle.load(modelFile)
    211
    212    fName= extra[1]
    213    if dbName == '':
    214      data = DataUtils.BuildQuantDataSet(fName)
    215    else:
    216      data = DataUtils.DBToQuantData(dbName,fName)
    217
    218    dataSet = data.GetNamedData()
    219
    220    img = VoteAndBuildImage(model,dataSet,badOnly=badOnly,sortTrueVals=sortTrueVals,
    221                         xScale=xScale,yScale=yScale)
    222    img.save(outFileName)
    223