IBM Watson Recognition Service

The code below illustrates how to invoke a model built with the watson recontion service.

You need three things to make this work.

  1. your ibm bluemix api_key which you were given when you logged into the service the first time to build the model.
  2. Once your model has been built you need the classifier ID which is visible on the tool interface.
  3. you must install the watson_developer_cloud module with pip.

The documentatation for the python api is very poor. the solution here was developed by looking at the source on github.

In [11]:
import watson_developer_cloud
from watson_developer_cloud import WatsonService
from watson_developer_cloud import VisualRecognitionV3

We first create an instance of the VisualRecognitionV3 class.

In [13]:
visual_recognition = VisualRecognitionV3(
   api_key = '1fc969d38 your key here 7f7d3d27334',
   version = '2016-05-20'
)
In [16]:
classifier_id = 'galaxies_1872954591'

We can use "get_classifier()" to set and return information about the classifier

In [18]:
visual_recognition.get_classifier(classifier_id)
Out[18]:
{'classes': [{'class': 'spiral'},
  {'class': 'irregular'},
  {'class': 'elliptical'},
  {'class': 'barred spiral'}],
 'classifier_id': 'galaxies_1872954591',
 'created': '2018-02-07T01:04:49.004Z',
 'name': 'galaxies',
 'owner': '11841661-6c02-473a-9fbf-a01f2edbb35b',
 'status': 'ready'}
In [19]:
visual_recognition.list_classifiers()
Out[19]:
{'classifiers': [{'classifier_id': 'galaxies_1872954591',
   'name': 'galaxies',
   'status': 'ready'}]}

Now let's classify an image. we will try number 12 in the test set. it should be elliptical.

To invoke the classifier we will pass the url of the image.

In [73]:
i = 12
base_image_url = "https://s3-us-west-2.amazonaws.com/learn-galaxies/"
image_url = base_image_url + "bigtest/t{}.jpg".format(i)
print(image_url)
https://s3-us-west-2.amazonaws.com/learn-galaxies/bigtest/t12.jpg

The simplest way to invoke the classifier it to pass it a json parameter file containing the url and classifer id.

In [74]:
param = { "url": image_url, "classifier_ids":['galaxies_1872954591']}
In [75]:
import json
In [76]:
js = json.dumps(param)
In [67]:
x = visual_recognition.classify(parameters=js)

The classifier return a dict that contains a list of images, each of which contains a list of classifiers and each of those contain the ordered list of clasifications of the image together with the score. we have only one image and one classifier, so the following will get what we want.

In [69]:
x['images'][0]['classifiers'][0]['classes'][0]
Out[69]:
{'class': 'elliptical', 'score': 0.942975}

the following cells compute the confusion matrix for the test set and for the train set. looking at the results we see that the classifier sometimes fails to classify an image. we call that result "none".

In [78]:
results = []
for i in range(0,40):
    image_url = base_image_url + "bigtest/t{}.jpg".format(i)
    param = { "url": image_url, "classifier_ids":['galaxies_1872954591']}
    js = json.dumps(param)
    x = visual_recognition.classify(parameters=js)
    try:
        results.append(x['images'][0]['classifiers'][0]['classes'][0])
    except:
        results.append({'class': 'none', 'score': 0.0})
In [79]:
results
Out[79]:
[{'class': 'barred spiral', 'score': 0.78769},
 {'class': 'spiral', 'score': 0.720162},
 {'class': 'barred spiral', 'score': 0.924213},
 {'class': 'barred spiral', 'score': 0.943366},
 {'class': 'barred spiral', 'score': 0.939549},
 {'class': 'barred spiral', 'score': 0.866362},
 {'class': 'barred spiral', 'score': 0.720807},
 {'class': 'barred spiral', 'score': 0.911679},
 {'class': 'barred spiral', 'score': 0.620509},
 {'class': 'barred spiral', 'score': 0.620509},
 {'class': 'elliptical', 'score': 0.671764},
 {'class': 'elliptical', 'score': 0.901912},
 {'class': 'none', 'score': 0.0},
 {'class': 'elliptical', 'score': 0.907464},
 {'class': 'elliptical', 'score': 0.917073},
 {'class': 'elliptical', 'score': 0.943774},
 {'class': 'elliptical', 'score': 0.599191},
 {'class': 'elliptical', 'score': 0.930498},
 {'class': 'elliptical', 'score': 0.946319},
 {'class': 'elliptical', 'score': 0.880935},
 {'class': 'irregular', 'score': 0.904399},
 {'class': 'irregular', 'score': 0.918748},
 {'class': 'none', 'score': 0.0},
 {'class': 'irregular', 'score': 0.942527},
 {'class': 'none', 'score': 0.0},
 {'class': 'irregular', 'score': 0.747777},
 {'class': 'irregular', 'score': 0.662649},
 {'class': 'irregular', 'score': 0.949148},
 {'class': 'irregular', 'score': 0.874189},
 {'class': 'irregular', 'score': 0.917388},
 {'class': 'spiral', 'score': 0.832364},
 {'class': 'barred spiral', 'score': 0.745061},
 {'class': 'none', 'score': 0.0},
 {'class': 'barred spiral', 'score': 0.84671},
 {'class': 'barred spiral', 'score': 0.83309},
 {'class': 'barred spiral', 'score': 0.830186},
 {'class': 'barred spiral', 'score': 0.771242},
 {'class': 'barred spiral', 'score': 0.71185},
 {'class': 'spiral', 'score': 0.84639},
 {'class': 'spiral', 'score': 0.94579}]
In [110]:
mydict = {'spiral': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0},
          'barred spiral': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0},
          'elliptical': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0},
          'irregular': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0}}
In [82]:
keys = []
for i in range(0,10):
    keys.append('barred spiral')
for i in range(10,20):
    keys.append('elliptical')
for i in range(20,30):
    keys.append('irregular')
for i in range(30,40):
    keys.append('spiral')
In [111]:
for i in range(0,40):
    key = keys[i]
    result = results[i]['class']
    mydict[key][result]+= 1
    
In [112]:
import pandas as pd
In [118]:
df = pd.DataFrame.from_dict(mydict)
In [119]:
df.transpose()
Out[119]:
barred spiral elliptical irregular none spiral
barred spiral 9.0 0.0 0.0 0.0 1.0
elliptical 0.0 9.0 0.0 1.0 0.0
irregular 0.0 0.0 8.0 2.0 0.0
spiral 6.0 0.0 0.0 1.0 3.0
In [120]:
nms = ['spiral', 'barred spiral', 'elliptical', 'irregular', 'none']
In [121]:
for r in nms:
    if r != 'none':
        total = 0.0
        for c in nms:
            total  += df[r][c]
        for c in nms:
            df[r][c] = round(100.0*df[r][c]/total)
df.transpose()
Out[121]:
barred spiral elliptical irregular none spiral
barred spiral 90.0 0.0 0.0 0.0 10.0
elliptical 0.0 90.0 0.0 10.0 0.0
irregular 0.0 0.0 80.0 20.0 0.0
spiral 60.0 0.0 0.0 10.0 30.0
In [134]:
testdict = {'spiral': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0},
          'barred spiral': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0},
          'elliptical': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0},
          'irregular': {'spiral':0.0, 'barred spiral':0.0, 'elliptical':0.0, 'irregular':0.0, 'none': 0.0}}
In [135]:
for i in range(1,20):
    image_url = base_image_url + "bigbarred/bs{}.jpg".format(i)
    param = { "url": image_url, "classifier_ids":['galaxies_1872954591']}
    js = json.dumps(param)
    x = visual_recognition.classify(parameters=js)
    try:
        y = x['images'][0]['classifiers'][0]['classes'][0]
    except:
        y = {'class': 'none', 'score': 0.0}
    testdict['barred spiral'][y['class']]+=1
In [136]:
for i in range(1,20):
    image_url = base_image_url + "bigelliptical/e{}.jpg".format(i)
    param = { "url": image_url, "classifier_ids":['galaxies_1872954591']}
    js = json.dumps(param)
    x = visual_recognition.classify(parameters=js)
    try:
        y = x['images'][0]['classifiers'][0]['classes'][0]
    except:
        y = {'class': 'none', 'score': 0.0}
    testdict['elliptical'][y['class']]+=1
In [138]:
for i in range(1,20):
    image_url = base_image_url + "bigirregular/i{}.jpg".format(i)
    param = { "url": image_url, "classifier_ids":['galaxies_1872954591']}
    js = json.dumps(param)
    x = visual_recognition.classify(parameters=js)
    try:
        y = x['images'][0]['classifiers'][0]['classes'][0]
    except:
        y = {'class': 'none', 'score': 0.0}
    testdict['irregular'][y['class']]+=1
In [139]:
for i in range(1,20):
    image_url = base_image_url + "bigspiral/s{}.jpg".format(i)
    param = { "url": image_url, "classifier_ids":['galaxies_1872954591']}
    js = json.dumps(param)
    x = visual_recognition.classify(parameters=js)
    try:
        y = x['images'][0]['classifiers'][0]['classes'][0]
    except:
        y = {'class': 'none', 'score': 0.0}
    testdict['spiral'][y['class']]+=1
In [146]:
tdf = pd.DataFrame.from_dict(testdict)
In [147]:
for r in nms:
    if r != 'none':
        total = 0.0
        for c in nms:
            total  += tdf[r][c]
        for c in nms:
            tdf[r][c] = round(100.0*tdf[r][c]/total)
tdf.transpose()
Out[147]:
barred spiral elliptical irregular none spiral
barred spiral 100.0 0.0 0.0 0.0 0.0
elliptical 0.0 100.0 0.0 0.0 0.0
irregular 0.0 0.0 100.0 0.0 0.0
spiral 0.0 0.0 0.0 0.0 100.0
In [133]:
x
Out[133]:
{'custom_classes': 4,
 'images': [{'classifiers': [{'classes': [{'class': 'spiral',
       'score': 0.968635}],
     'classifier_id': 'galaxies_1872954591',
     'name': 'galaxies'}],
   'resolved_url': 'https://s3-us-west-2.amazonaws.com/learn-galaxies/bigspiral/s1.jpg',
   'source_url': 'https://s3-us-west-2.amazonaws.com/learn-galaxies/bigspiral/s1.jpg'}],
 'images_processed': 1}