Copyright 2018 Google LLC.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Evaluation code

Disclaimer

  • This notebook contains experimental code, which may be changed without notice.
  • The ideas here are some ideas relevant to fairness - they are not the whole story!

Notebook summary

This notebook intends to evaluate a list of models on two dimensions:

  • "Performance": How well the model perform to classify the data (intended bias). Currently, we use the AUC.
  • "Bias": How much bias does the model contain (unintended bias). Currently, we use the pinned auc.

This script takes the following steps:

  • Defines the models to evaluate and specify their signature (expected inputs/outputs).
  • Write input function to generate 2 datasets:
    • A "performance dataset" which will be used for the first set of metrics. This dataset is supposed to be similar format to the training data (contain a piece of text and a label).
    • A "bias dataset" which will be used for the second set of metrics. This data contains a piece of text, a label but also some subgroup information to evaluate the unintended bias on.
  • Runs predictions with the export_utils.
  • Evaluate metrics.

In [1]:
%load_ext autoreload

In [2]:
%autoreload 2

In [3]:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import getpass
from IPython.display import display
import json
import nltk
import numpy as np
import pandas as pd
import pkg_resources
import os
import random
import re
import seaborn as sns

import tensorflow as tf
from tensorflow.python.lib.io import file_io

In [4]:
#from google.colab import auth
#auth.authenticate_user()

In [5]:
#!pip install -U -q git+https://github.com/conversationai/unintended-ml-bias-analysis

In [6]:
from unintended_ml_bias import model_bias_analysis

In [7]:
import input_fn_example
from utils_export.dataset import Dataset, Model
from utils_export import utils_cloudml
from utils_export import utils_tfrecords

In [8]:
os.environ['GCS_READ_CACHE_MAX_SIZE_MB'] = '0' #Faster to access GCS file + https://github.com/tensorflow/tensorflow/issues/15530

In [9]:
nltk.download('punkt')


[nltk_data] Downloading package punkt to /Users/nthain/nltk_data...
[nltk_data]   Package punkt is already up-to-date!
Out[9]:
True

Settings

Global variables


In [10]:
# User inputs
PROJECT_NAME = 'conversationai-models'

Part 1: Defining your model

An important user input is the description of the deployed models that are evaluated.

1- Defining which model will be used. $MODEL_NAMES defined the different names (format: "model_name:version").

2- Defining the model signature. Currently, the Dataset API does not detect the signature of a CMLE model, so this information is given by a Model instance. You need to describe:

  • input_spec: what the input_file should be (argument feature_keys_spec). It is a dictionary which describes the name of the fields and their types.
  • prediction_keys (argument prediction_keys). It is the name of the prediction field in the model output.
  • Name of the example key (argument example_key). A unique identifier for each sentence which will be generated by the dataset API (a.k.a. your input data does not need to have this field).
    • When using Cloud MLE for batch predictions, data is processed in an unpredictable order. To be able to match the returned predictions with your input instances, you must have instance keys defined.

In [11]:
# User inputs:
MODEL_NAMES = [
    'tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738', # ??
    'tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748', # ??
    'tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820', # ??
    'tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828', # ??
]

In [12]:
# User inputs: Model description (see above for more info).
TEXT_FEATURE_NAME = 'tokens' #Input defined in serving function called in run.py (arg: `text_feature_name`).
SENTENCE_KEY = 'comment_key' #Input key defined in serving functioncalled in run.py (arg: `example_key_name`).
#LABEL_NAME_PREDICTION_MODEL = 'scores' # Output prediction: typically $label_name/logistic
LABEL_NAME_PREDICTION_MODEL = 'probabilities' # Output prediction: typically $label_name/logistic

In [13]:
model_input_spec = {
    TEXT_FEATURE_NAME: utils_tfrecords.EncodingFeatureSpec.LIST_STRING} #library will use this automatically

model = Model(
    feature_keys_spec=model_input_spec,
    prediction_keys=LABEL_NAME_PREDICTION_MODEL,
    example_key=SENTENCE_KEY,
    model_names=MODEL_NAMES,
    project_name=PROJECT_NAME)

Part 2: Defining the input_fn


In [14]:
def tokenizer(text, lowercase=True):
  """Converts text to a list of words.

  Args:
    text: piece of text to tokenize (string).
    lowercase: whether to include lowercasing in preprocessing (boolean).
    tokenizer: Python function to tokenize the text on.

  Returns:
    A list of strings (words).
  """
  words = nltk.word_tokenize(text.decode('utf-8'))
  if lowercase:
    words = [w.lower() for w in words]
  return words

Defining input_fn

We need to define first some input_fn which will be fed to the Dataset API. An input_fn must follow the following requirements:

  • Returns a pandas DataFrame
  • Have an argument 'max_n_examples' to control the size of the dataframe.
  • Containing at least a field $TEXT_FEATURE_NAME, which maps to a tokenized text (list of words) AND a field 'label' which is 1 for toxic (0 otherwise).

We will define two different input_fn (1 for performance, 1 for bias). The bias input_fn should also contain identity information.

Note: You can use ANY input_fn that matches those requirements. You can find a few examples of input_fn in the file input_fn_example.py (for toxicity and civil_comments dataset).


In [15]:
# User inputs: Choose which one you want to use OR create your own!
INPUT_FN_PERFORMANCE = input_fn_example.create_input_fn_biasbios(
    tokenizer,
    model_input_comment_field=TEXT_FEATURE_NAME,
    )

Part 3: Running prediction

Performance dataset


In [16]:
# User inputs
SIZE_PERFORMANCE_DATA_SET = 10000

In [17]:
# Pattern for path of tf_records
PERFORMANCE_DATASET_DIR = os.path.join(
    'gs://conversationai-models/',
    getpass.getuser(),
    'tfrecords',
    'performance_dataset_dir')
print(PERFORMANCE_DATASET_DIR)


gs://conversationai-models/nthain/tfrecords/performance_dataset_dir

In [18]:
dataset_performance = Dataset(INPUT_FN_PERFORMANCE, PERFORMANCE_DATASET_DIR)
random.seed(2018) # Need to set seed before loading data to be able to reload same data in the future
dataset_performance.load_data(SIZE_PERFORMANCE_DATA_SET, random_filter_keep_rate=0.5)


INFO:tensorflow:input_fn is compatible with the `Dataset` class.
/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/tensorflow/python/client/session.py:1711: UserWarning: An interactive session is already active. This can cause out-of-memory errors in some cases. You must explicitly call `InteractiveSession.close()` to release resources held by the other session(s).
  warnings.warn('An interactive session is already active. This can '

In [19]:
dataset_performance.show_data()


Out[19]:
tokens gender label
0 [in, her, role, ,, she, is, a, member, of, an,... F 17
1 [his, blog, www.donaldhtaylorjr.blogspot.com, ... M 25
2 [he, has, primarily, reported, for, the, atlan... M 12
3 [andrea, 's, area, of, expertise, is, in, whol... F 25
4 [dr., milane, was, trained, as, a, national, c... F 25
5 [he, is, also, visiting, associate, professor,... M 25
6 [her, research, focuses, on, the, trafficking,... F 25
7 [he, has, been, licensed, to, practice, law, i... M 3
8 [after, a, two-year, postdoctoral, fellowship,... M 25
9 [prior, to, teaching, ,, she, was, an, account... F 31
10 [jackie, 's, works, are, published, in, academ... F 25
11 [her, research, topic, was, the, investigation... F 25
12 [she, graduated, with, honors, in, 2012, ., ha... F 17
13 [his, research, focuses, on, the, japan, air, ... M 25
14 [she, directed, the, 2014, peabody, award-winn... F 10
15 [he, lends, his, exceptional, surgical, skills... M 30
16 [he, teaches, courses, ranging, from, core, un... M 25
17 [her, major, fields, of, interest, are, develo... F 25
18 [dr., cole, honors, several, insurance, carrie... M 23
19 [she, practices, in, the, areas, of, business,... F 3
20 [she, has, obtained, her, phd, in, eu, law, fr... F 25
21 [his, photographs, are, reminiscent, of, silho... M 22
22 [he, earned, his, ph.d., at, the, university, ... M 25
23 [his, inter-, disciplinary, research, interest... M 25
24 [she, earned, her, ph.d., in, communication, s... F 25
25 [his, current, projects, examine, intergenerat... M 25
26 [he, has, served, as, an, expert, witness, in,... M 0
27 [she, 's, called, in, some, of, the, parent, o... F 31
28 [nneka, has, recently, become, interested, in,... F 3
29 [she, writes, regularly, for, faith, and, lead... F 20
... ... ... ...
9970 [he, was, previously, an, assistant, professor... M 25
9971 [aside, from, filmmaking, ,, he, ’, s, an, avi... M 10
9972 [he, lives, in, dallas, with, his, wife, and, ... M 29
9973 [he, exhibited, in, institutions, like, kultur... M 22
9974 [he, has, represented, numerous, municipalitie... M 3
9975 [his, works, include, portrait, ,, glamour, an... M 22
9976 [he, began, using, haskell, during, his, senio... M 29
9977 [he, has, been, involved, with, streaming, med... M 2
9978 [he, has, also, produced, lecture, courses, fo... M 25
9979 [after, completing, her, degrees, at, the, uni... F 23
9980 [this, is, a, slightly, edited, version, of, h... F 12
9981 [she, received, her, b.sc, ., in, nutrition, f... F 8
9982 [she, is, the, author, of, pelo, bueno, y, otr... F 24
9983 [she, obtained, her, bachelor, of, science, de... F 23
9984 [dr., kanchan, singh, practices, at, singh, de... M 30
9985 [prior, to, joining, fresh, 'n, fit, cuisine, ... F 8
9986 [he, worked, on, staff, at, aopa, pilot, magaz... M 12
9987 [he, started, working, on, these, themes, duri... M 18
9988 [his, research, aims, to, understand, the, con... M 25
9989 [he, received, the, ph.d., degree, in, measuri... M 25
9990 [he, currently, practices, at, johns, hopkins,... M 30
9991 [she, received, her, m.a, ., in, secondary, ed... F 31
9992 [his, research, interests, lie, in, the, study... M 25
9993 [she, graduated, with, honors, in, 2000, ., ha... F 26
9994 [chris, primarily, teaches, anatomy, and, phys... M 31
9995 [always, responsive, to, the, specific, geogra... F 2
9996 [he, has, worked, on, numerous, projects, that... M 29
9997 [he, graduated, from, the, academy, of, visual... M 22
9998 [most, of, his, writing, is, from, the, middle... M 12
9999 [he, is, currently, on, the, good, news, poetr... M 24

10000 rows × 3 columns


In [20]:
dataset_performance.show_data().shape


Out[20]:
(10000, 3)

In [21]:
dataset_performance.show_data().columns


Out[21]:
Index([u'tokens', u'gender', u'label'], dtype='object')

In [22]:
CLASS_NAMES = range(33)

In [23]:
INPUT_DATA = 'gs://conversationai-models/biosbias/dataflow_dir/data-preparation-20190220165938/eval-00000-of-00003.tfrecord'
record_iterator = tf.python_io.tf_record_iterator(path=INPUT_DATA)
string_record = next(record_iterator)
example = tf.train.Example()
example.ParseFromString(string_record)
text = example.features.feature
print(example)


features {
  feature {
    key: "comment_text"
    value {
      bytes_list {
        value: " In her role, she is a member of an innovative team-based care model which has been recognized by Wall Street Journal and the Robert Wood Johnson Foundation. A process improvement leader with a passion for serving vulnerable populations, Amberly was recognized by her colleagues with the first Daisy Award for Extraordinary Nurses at Cambridge Health Alliance. Amberly holds a BS in Nursing from Valparaiso University and a Masters in Public Health from the University of Massachusetts Amherst. read more"
      }
    }
  }
  feature {
    key: "gender"
    value {
      bytes_list {
        value: "F"
      }
    }
  }
  feature {
    key: "title"
    value {
      int64_list {
        value: 17
      }
    }
  }
}


In [24]:
# Set recompute_predictions=False to save time if predictions are available.
dataset_performance.add_model_prediction_to_data(model, recompute_predictions=False, class_names=CLASS_NAMES)


INFO:tensorflow:Model is compatible with the `Dataset` instance.
WARNING:tensorflow:Using past predictions. the data must match exactly (same number of lines and same order).

In [25]:
def _load_predictions(pred_file):
    with file_io.FileIO(pred_file, 'r') as f:
      # prediction file needs to fit in memory.
      try:
        predictions = [json.loads(line) for line in f]
      except:
        predictions = []
    return predictions

model_name_tmp = MODEL_NAMES[0]
prediction_file = dataset_performance.get_path_prediction(model_name_tmp)
print(prediction_file)
prediction_file = os.path.join(prediction_file,
                                 'prediction.results-00000-of-00001')
print(len(_load_predictions(prediction_file)[0]['probabilities']))


gs://conversationai-models/nthain/tfrecords/performance_dataset_dir/prediction_data_tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738
33

In [ ]:

Post processing


In [26]:
test_performance_df = dataset_performance.show_data()

In [27]:
test_bias_df = test_performance_df.copy()

Analyzing final results


In [28]:
test_performance_df.head()


Out[28]:
tokens gender label tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_0 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_1 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_2 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_3 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_4 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_5 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_6 ... tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_23 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_24 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_25 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_26 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_27 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_28 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_29 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_30 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_31 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_32
0 [in, her, role, ,, she, is, a, member, of, an,... F 17 0.001687 1.814099e-11 0.002681 0.009853 0.004227 0.055716 0.003005 ... 0.003351 0.013561 0.002040 0.001682 4.412969e-04 6.086852e-17 0.001606 0.001379 0.014635 0.000032
1 [his, blog, www.donaldhtaylorjr.blogspot.com, ... M 25 0.014774 2.716771e-13 0.005496 0.022347 0.003845 0.084480 0.000096 ... 0.010309 0.001055 0.001062 0.006205 9.439933e-07 5.250679e-18 0.001204 0.000150 0.015252 0.000779
2 [he, has, primarily, reported, for, the, atlan... M 12 0.016779 8.870694e-16 0.001688 0.071343 0.000560 0.029823 0.000032 ... 0.018767 0.022292 0.077598 0.033979 8.196229e-05 3.315851e-11 0.007313 0.002565 0.118167 0.001603
3 [andrea, 's, area, of, expertise, is, in, whol... F 25 0.017742 1.019689e-15 0.017150 0.052085 0.002097 0.052322 0.002627 ... 0.001580 0.145462 0.000637 0.000337 3.909138e-04 1.304484e-21 0.011515 0.000922 0.029867 0.000001
4 [dr., milane, was, trained, as, a, national, c... F 25 0.015531 1.783027e-12 0.196227 0.016471 0.002690 0.000040 0.001384 ... 0.013445 0.003754 0.220090 0.081232 7.920414e-05 2.406181e-13 0.150817 0.014913 0.071632 0.000142

5 rows × 135 columns


In [29]:
test_bias_df.head()


Out[29]:
tokens gender label tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_0 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_1 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_2 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_3 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_4 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_5 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_6 ... tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_23 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_24 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_25 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_26 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_27 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_28 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_29 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_30 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_31 tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828_32
0 [in, her, role, ,, she, is, a, member, of, an,... F 17 0.001687 1.814099e-11 0.002681 0.009853 0.004227 0.055716 0.003005 ... 0.003351 0.013561 0.002040 0.001682 4.412969e-04 6.086852e-17 0.001606 0.001379 0.014635 0.000032
1 [his, blog, www.donaldhtaylorjr.blogspot.com, ... M 25 0.014774 2.716771e-13 0.005496 0.022347 0.003845 0.084480 0.000096 ... 0.010309 0.001055 0.001062 0.006205 9.439933e-07 5.250679e-18 0.001204 0.000150 0.015252 0.000779
2 [he, has, primarily, reported, for, the, atlan... M 12 0.016779 8.870694e-16 0.001688 0.071343 0.000560 0.029823 0.000032 ... 0.018767 0.022292 0.077598 0.033979 8.196229e-05 3.315851e-11 0.007313 0.002565 0.118167 0.001603
3 [andrea, 's, area, of, expertise, is, in, whol... F 25 0.017742 1.019689e-15 0.017150 0.052085 0.002097 0.052322 0.002627 ... 0.001580 0.145462 0.000637 0.000337 3.909138e-04 1.304484e-21 0.011515 0.000922 0.029867 0.000001
4 [dr., milane, was, trained, as, a, national, c... F 25 0.015531 1.783027e-12 0.196227 0.016471 0.002690 0.000040 0.001384 ... 0.013445 0.003754 0.220090 0.081232 7.920414e-05 2.406181e-13 0.150817 0.014913 0.071632 0.000142

5 rows × 135 columns

Part 4: Run evaluation metrics

Performance metrics

Data Format

At this point, our performance data is in DataFrame df, with columns:

  • label: True if the comment is Toxic, False otherwise.
  • < model name >: One column per model, cells contain the score from that model. You can run the analysis below on any data in this format. Subgroup labels can be generated via words in the text as done above, or come from human labels if you have them.

Run AUC


In [30]:
import sklearn.metrics as metrics

In [31]:
test_performance_df.label.value_counts()


Out[31]:
25    3295
3      890
22     661
12     542
26     507
23     494
17     481
31     427
30     343
7      268
2      265
18     209
16     202
24     197
29     194
10     185
6      156
0      141
8      102
5       87
20      67
4       58
32      50
19      41
9       39
11      37
27      32
21      30
Name: label, dtype: int64

In [32]:
test_performance_df['label'] == 3


Out[32]:
0       False
1       False
2       False
3       False
4       False
5       False
6       False
7        True
8       False
9       False
10      False
11      False
12      False
13      False
14      False
15      False
16      False
17      False
18      False
19       True
20      False
21      False
22      False
23      False
24      False
25      False
26      False
27      False
28       True
29      False
        ...  
9970    False
9971    False
9972    False
9973    False
9974     True
9975    False
9976    False
9977    False
9978    False
9979    False
9980    False
9981    False
9982    False
9983    False
9984    False
9985    False
9986    False
9987    False
9988    False
9989    False
9990    False
9991    False
9992    False
9993    False
9994    False
9995    False
9996    False
9997    False
9998    False
9999    False
Name: label, Length: 10000, dtype: bool

In [33]:
_model = 'tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738'
_class = 3
test_performance_df['{}_{}'.format(_model, _class)]


Out[33]:
0       0.009853
1       0.022347
2       0.071343
3       0.052085
4       0.016471
5       0.101164
6       0.011855
7       0.001939
8       0.577954
9       0.128116
10      0.014246
11      0.022629
12      0.050127
13      0.205395
14      0.038603
15      0.045960
16      0.652514
17      0.099024
18      0.055800
19      0.167238
20      0.056128
21      0.073346
22      0.040896
23      0.046719
24      0.066602
25      0.015700
26      0.018788
27      0.099245
28      0.744404
29      0.054567
          ...   
9970    0.025056
9971    0.032513
9972    0.059166
9973    0.030145
9974    0.146219
9975    0.132243
9976    0.061952
9977    0.497093
9978    0.154263
9979    0.033800
9980    0.041427
9981    0.000079
9982    0.071002
9983    0.961150
9984    0.017224
9985    0.113003
9986    0.040686
9987    0.729384
9988    0.025192
9989    0.066657
9990    0.025502
9991    0.011763
9992    0.007214
9993    0.004737
9994    0.044174
9995    0.125944
9996    0.199613
9997    0.018891
9998    0.218019
9999    0.052486
Name: tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738_3, Length: 10000, dtype: float64

In [34]:
auc_list = []
for _model in MODEL_NAMES:
    for _class in CLASS_NAMES:
        fpr, tpr, thresholds = metrics.roc_curve(
            test_performance_df['label'] == _class,
            test_performance_df['{}_{}'.format(_model, _class)])
        _auc = metrics.auc(fpr, tpr)
        auc_list.append(_auc)
        print ('Auc for class {} model {}: {}'.format(_class, _model, _auc))


Auc for class 0 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.472880379306
Auc for class 1 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: nan
Auc for class 2 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.494346987625
Auc for class 3 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.5094779166
Auc for class 4 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.579115768006
Auc for class 5 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.495869234756
Auc for class 6 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.468048349118
Auc for class 7 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.485770898896
Auc for class 8 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.491489665173
Auc for class 9 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.47350564638
Auc for class 10 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.488175572414
Auc for class 11 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.52613046651
Auc for class 12 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.496119960142
Auc for class 13 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: nan
Auc for class 14 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: nan
Auc for class 15 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: nan
Auc for class 16 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.520060671101
Auc for class 17 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.502598042781
Auc for class 18 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.471809136308
Auc for class 19 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.589720292223
Auc for class 20 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.464268809982
Auc for class 21 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.451838849883
Auc for class 22 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.501252940388
Auc for class 23 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.522887952293
Auc for class 24 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.50126994171
Auc for class 25 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.502592883032
Auc for class 26 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.4976489476
Auc for class 27 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.413984124197
Auc for class 28 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: nan
Auc for class 29 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.485232058639
Auc for class 30 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.475149523707
Auc for class 31 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.512695371032
Auc for class 32 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.443107537688
Auc for class 0 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.473124962683
Auc for class 1 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: nan
Auc for class 2 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.502436065161
Auc for class 3 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.497505395972
Auc for class 4 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.533997183665
Auc for class 5 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.516225645878
Auc for class 6 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.479381557424
Auc for class 7 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.503250547509
Auc for class 8 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.501472866374
Auc for class 9 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.511796004417
Auc for class 10 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.472370750781
Auc for class 11 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.503774777488
Auc for class 12 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.482292660736
Auc for class 13 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: nan
Auc for class 14 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: nan
Auc for class 15 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: nan
Auc for class 16 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.509781244505
Auc for class 17 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.511501561927
Auc for class 18 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.466850476392
Auc for class 19 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.616544907291
Auc for class 20 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.517680398972
Auc for class 21 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.48543965229
Auc for class 22 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.498092928991
Auc for class 23 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.527383088967
Auc for class 24 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.516476102053
Auc for class 25 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.498915515
Auc for class 26 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.498317975812
Auc for class 27 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.439794843499
Auc for class 28 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: nan
Auc for class 29 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.509969175195
/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/sklearn/metrics/ranking.py:571: UndefinedMetricWarning: No positive samples in y_true, true positive value should be meaningless
  UndefinedMetricWarning)
Auc for class 30 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.493638808206
Auc for class 31 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.508299713945
Auc for class 32 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.457780904523
Auc for class 0 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.496740926496
Auc for class 1 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: nan
Auc for class 2 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.499153608357
Auc for class 3 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.499355443456
Auc for class 4 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.519405656255
Auc for class 5 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.510566062676
Auc for class 6 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.480932677982
Auc for class 7 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.492101760004
Auc for class 8 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.521062880598
Auc for class 9 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.46758254629
Auc for class 10 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.475540747064
Auc for class 11 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.540092938467
Auc for class 12 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.486065994621
Auc for class 13 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: nan
Auc for class 14 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: nan
Auc for class 15 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: nan
Auc for class 16 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.488949553253
Auc for class 17 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.512517147563
Auc for class 18 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.480352770023
Auc for class 19 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.524139214683
Auc for class 20 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.531170784555
Auc for class 21 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.486539618857
Auc for class 22 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.493480481944
Auc for class 23 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.493649014345
Auc for class 24 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.519584546531
Auc for class 25 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.502616827295
Auc for class 26 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.499241317853
Auc for class 27 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.527983296549
Auc for class 28 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: nan
Auc for class 29 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.513514238074
Auc for class 30 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.505267708646
Auc for class 31 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.526942603747
Auc for class 32 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.416369849246
Auc for class 0 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.492310370551
Auc for class 1 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: nan
Auc for class 2 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.510422808191
Auc for class 3 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.497258969647
Auc for class 4 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.533468253803
Auc for class 5 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.51988275004
Auc for class 6 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.446890074912
Auc for class 7 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.470106311844
Auc for class 8 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.480683362454
Auc for class 9 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.519891680117
Auc for class 10 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.498969861354
Auc for class 11 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.49575049304
Auc for class 12 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.496308597575
Auc for class 13 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: nan
Auc for class 14 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: nan
Auc for class 15 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: nan
Auc for class 16 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.497497468669
Auc for class 17 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.498361194233
Auc for class 18 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.454219503411
Auc for class 19 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.554294558911
Auc for class 20 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.510198929845
Auc for class 21 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.443848211301
Auc for class 22 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.511251516464
Auc for class 23 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.527593056506
Auc for class 24 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.517610635095
Auc for class 25 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.507171714086
Auc for class 26 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.494850664384
Auc for class 27 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.433402513042
Auc for class 28 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: nan
Auc for class 29 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.529500137723
Auc for class 30 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.485269677036
Auc for class 31 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.513662670014
Auc for class 32 model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.429722613065

In [55]:
def get_class_from_col_name(col_name):
    pattern = r'^.*_(\d+)$'
    return int(re.search(pattern, col_name).group(1))

In [62]:
def find_best_class(df, model_name, class_names):
    model_class_names = ['{}_{}'.format(model_name, class_name) for class_name in class_names]
    sub_df = df[model_class_names]
    df['{}_class'.format(model_name)] = sub_df.idxmax(axis=1).apply(get_class_from_col_name)

In [63]:
for _model in MODEL_NAMES:
    find_best_class(test_performance_df, _model, CLASS_NAMES)

In [64]:
accuracy_list = []
for _model in MODEL_NAMES:
    is_correct = (test_performance_df['{}_class'.format(_model)] == test_performance_df['label'])
    _acc = sum(is_correct)/len(is_correct)
    accuracy_list.append(_acc)
    print ('Accuracy for model {}: {}'.format(_model, _acc))


Accuracy for model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132738: 0.0572
Accuracy for model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132748: 0.0639
Accuracy for model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132820: 0.0681
Accuracy for model tf_trainer_tf_gru_attention_multiclass_biosbias_glove:v_20190306_132828: 0.0623

Unintended Bias Metrics

Data Format

At this point, our bias data is in DataFrame df, with columns:

  • label: True if the comment is Toxic, False otherwise.
  • < model name >: One column per model, cells contain the score from that model.
  • < subgroup >: One column per identity, True if the comment mentions this identity.

You can run the analysis below on any data in this format. Subgroup labels can be generated via words in the text as done above, or come from human labels if you have them.


In [35]:
identity_terms_civil_included = []
for _term in input_fn_example.identity_terms_civil:
    if sum(test_bias_df[_term]) >= 20:
        print ('keeping {}'.format(_term))
        identity_terms_civil_included.append(_term)


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-35-d94e49a61360> in <module>()
      1 identity_terms_civil_included = []
      2 for _term in input_fn_example.identity_terms_civil:
----> 3     if sum(test_bias_df[_term]) >= 20:
      4         print ('keeping {}'.format(_term))
      5         identity_terms_civil_included.append(_term)

/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/pandas/core/frame.pyc in __getitem__(self, key)
   2137             return self._getitem_multilevel(key)
   2138         else:
-> 2139             return self._getitem_column(key)
   2140 
   2141     def _getitem_column(self, key):

/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/pandas/core/frame.pyc in _getitem_column(self, key)
   2144         # get column
   2145         if self.columns.is_unique:
-> 2146             return self._get_item_cache(key)
   2147 
   2148         # duplicate columns & possible reduce dimensionality

/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/pandas/core/generic.pyc in _get_item_cache(self, item)
   1840         res = cache.get(item)
   1841         if res is None:
-> 1842             values = self._data.get(item)
   1843             res = self._box_item_values(item, values)
   1844             cache[item] = res

/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/pandas/core/internals.pyc in get(self, item, fastpath)
   3841 
   3842             if not isna(item):
-> 3843                 loc = self.items.get_loc(item)
   3844             else:
   3845                 indexer = np.arange(len(self.items))[isna(self.items)]

/Users/nthain/Documents/repos/conversationai-models/model_evaluation/.venv/lib/python2.7/site-packages/pandas/core/indexes/base.pyc in get_loc(self, key, method, tolerance)
   2525                 return self._engine.get_loc(key)
   2526             except KeyError:
-> 2527                 return self._engine.get_loc(self._maybe_cast_indexer(key))
   2528 
   2529         indexer = self.get_indexer([key], method=method, tolerance=tolerance)

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'male'

In [ ]:
test_bias_df['model_1'] = test_bias_df['tf_gru_attention_civil:v_20181109_164318']
test_bias_df['model_2'] = test_bias_df['tf_gru_attention_civil:v_20181109_164403']
test_bias_df['model_3'] = test_bias_df['tf_gru_attention_civil:v_20181109_164535']
test_bias_df['model_4'] = test_bias_df['tf_gru_attention_civil:v_20181109_164630']

In [ ]:
MODEL_NAMES = ['model_1', 'model_2', 'model_3', 'model_4']

In [ ]:
bias_metrics = model_bias_analysis.compute_bias_metrics_for_models(test_bias_df, identity_terms_civil_included, MODEL_NAMES, 'label')

In [ ]:
model_bias_analysis.plot_auc_heatmap(bias_metrics, MODEL_NAMES)

In [ ]:
model_bias_analysis.plot_aeg_heatmap(bias_metrics, MODEL_NAMES)

In [ ]: