# Highlighting the matching words for text classfication

**URL:** <https://support.prodi.gy/t/highlighting-the-matching-words-for-text-classfication/254>\
**Category:** Uncategorized\
**Tags:** enhancement, textcat\
**Created:** [January 27, 2018, 6:27pm UTC](https://support.prodi.gy/t/highlighting-the-matching-words-for-text-classfication/254 "2018-01-27T18:27:38Z")\
**Posts on this page:** 1\
**Showing post:** 8

<div class="post-metadata">

**Author:** ![justindujardin](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/justindujardin/32/169_2.png) [@justindujardin](https://support.prodi.gy/u/justindujardin)\
**Post date:** [February 7, 2018, 2:20am UTC](https://support.prodi.gy/t/highlighting-the-matching-words-for-text-classfication/254/8 "2018-02-07T02:20:32Z")

</div>

I created variants on `textcat.teach` and `texcat.eval` that render examples using a custom template and attention weight data from @honnibal’s example.

The [code is on Github](https://github.com/justindujardin/prodigy-scratch/blob/master/recipes/textcat_attention_weights.py), and it renders text where items with more attention have larger fonts, and those that have a bunch of attention get a special color.

![attention_weights](https://us1.discourse-cdn.com/flex020/uploads/prodigy/original/1X/4c519130b06111136d300d24d155d5efe8f31962.png)

I transform the attention weights into metadata for use in the HTML template:

```python
def attach_attention_data(input_stream, nlp, attn_weights):
    """Attach attention weights to token data with each example"""
    for item in input_stream:
        tokens_data = []
        attn_weights.clear()
        doc = nlp(item['text'])
        for index, token in enumerate(doc):
            weight = float(attn_weights[0][index][0])
            # If the change is over some threshold, add color to draw the eye
            color = 'rgba(255,0,0,0.54)' if weight > 0.025 else 'inherit'
            tokens_data.append({
                't': token.text_with_ws,
                'c': color,
                's': min(2.5, 1 + weight * 2),
                'w': weight
            })
        item['tokens'] = tokens_data
        yield item

```

The template loops over `tokens` and renders each one with a span and custom styling:

```python
<div>{{#tokens}}<span style="font-size:{{s}}em; color:{{c}};">{{t}}</span>{{/tokens}}</div>

```

It’s all wired up by attaching it to the stream inside the recipe:

```python
@recipe('attncat.eval',...)
def evaluate(...):
    ...
    nlp = spacy.load(...)
    textcat = nlp.get_pipe('textcat')
    assert textcat is not None
    with get_attention_weights(textcat) as attn_weights:
        stream = ...
        stream = attach_attention_data(stream, nlp, attn_weights)
    return {
        'view_id': 'html',
        'stream': stream,
        ...
        'config': {..., 'html_template': template_text}
    }

    ...

```

Hope it helps. If the custom template does not appear to be working, be sure you do not have an entry for `html_template` in your `prodigy.json` file, because it will override the recipe.

---

_[View the full topic](https://support.prodi.gy/t/highlighting-the-matching-words-for-text-classfication/254)._
