

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# `Modèle de démonstration : Étiqueter les intentions avec Crowd-Classifier`
<a name="sms-custom-templates-step2-demo2"></a>

Si vous choisissez un modèle personnalisé, vous atteignez le **panneau de tâches d’étiquetage personnalisé**. Dans la console, vous pouvez sélectionner à partir de plusieurs modèles de démarrage qui représentent la plupart des tâches courantes. Les modèles fournissent un point de départ à partir duquel créer votre modèle de tâche d’étiquetage personnalisé.

Dans cette démonstration, vous allez utiliser le modèle **Détection des intentions**, qui utilise l’élément `crowd-classifier` et les fonctions AWS Lambda nécessaires au traitement de vos données avant et après la tâche.

**Topics**
+ [Modèle personnalisé de démarrage de détection des intentions](#sms-custom-templates-step2-demo2-base-template)
+ [Votre modèle personnalisé de détection des intentions](#sms-custom-templates-step2-demo2-your-template)
+ [Votre fonction Lambda de pré-annotation](#sms-custom-templates-step2-demo2-pre-lambda)
+ [Votre fonction Lambda post-annotation](#sms-custom-templates-step2-demo2-post-lambda)
+ [Votre sortie de tâche d’étiquetage](#sms-custom-templates-step2-demo2-job-output)

## Modèle personnalisé de démarrage de détection des intentions
<a name="sms-custom-templates-step2-demo2-base-template"></a>

Il s’agit du modèle de détection d’intentions qui est fourni en tant que point de départ.

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<crowd-form>
  <crowd-classifier
    name="intent"
    categories="{{ task.input.labels | to_json | escape }}"
    header="Pick the most relevant intention expressed by the below text"
  >
    <classification-target>
      {{ task.input.utterance }}
    </classification-target>
    
    <full-instructions header="Intent Detection Instructions">
        <p>Select the most relevant intention expressed by the text.</p>
        <div>
           <p><strong>Example: </strong>I would like to return a pair of shoes</p>
           <p><strong>Intent: </strong>Return</p>
        </div>
    </full-instructions>

    <short-instructions>
      Pick the most relevant intention expressed by the text
    </short-instructions>
  </crowd-classifier>
</crowd-form>
```

Les modèles personnalisés utilisent le [langage du modèle Liquid](https://shopify.github.io/liquid/) et chacun des éléments entre accolades doubles est une variable. La fonction AWS Lambda de pré-annotation doit fournir un objet `taskInput` nommé et les propriétés de cet objet sont accessibles `{{ task.input.<property name> }}` comme dans votre modèle.

## Votre modèle personnalisé de détection des intentions
<a name="sms-custom-templates-step2-demo2-your-template"></a>

Dans le modèle de départ, il y a deux variables : la propriété `task.input.labels` dans la balise d’ouverture de l’élément `crowd-classifier` et le `task.input.utterance` dans le contenu de la région `classification-target`.

À moins que vous deviez offrir différents ensembles d’étiquettes avec différents énoncés, éviter d’utiliser une variable et utiliser simplement du texte vous permettra de gagner du temps de traitement et de créer moins de possibilités d’erreurs. Le modèle utilisé dans cette démonstration supprimera cette variable, mais les variables et les filtres tels que `to_json` sont décrits plus en détail dans l’article de [démonstration de `crowd-bounding-box`]().

### Personnalisez vos éléments
<a name="sms-custom-templates-step2-demo2-instructions"></a>

Deux parties des éléments personnalisés sont parfois oubliées, il s’agit des régions `<full-instructions>` et `<short-instructions>`. Les bonnes instructions permettent d’obtenir de bons résultats.

Dans les éléments qui incluent ces régions, le `<short-instructions>` apparaît automatiquement dans le volet « Instructions » situé à gauche de l’écran. Les `<full-instructions>` sont rattachées au lien « View full instructions (Affichage des instructions complètes) » situé en haut de ce volet. En cliquant sur le lien, vous ouvrez un volet avec des instructions plus détaillées.

Vous ne pouvez pas uniquement utiliser le HTML ou le CSS. JavaScript Dans ces sections, nous vous encourageons à le faire si vous pensez pouvoir fournir un ensemble solide d'instructions et d'exemples qui aideront les employés à accomplir vos tâches avec une rapidité et une précision accrues. 

**Example Testez du code avec JSFiddle**  
[https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/)  
 Effectuez un [test`<crowd-classifier>`](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/). Cet exemple est présenté par JSFiddle. Par conséquent, tous les modèles de variables sont remplacés par des valeurs codées en dur. Cliquez sur le lien « View full instructions (Affichage des instructions complètes) » pour consulter plusieurs exemples de styles CSS étendus. Vous pouvez bifurquer le projet pour tester vos propres modifications du CSS, en ajoutant des exemples d'images ou en ajoutant des JavaScript fonctionnalités étendues.

**Example : modèle final personnalisé de détection des intentions**  
Dans ce cas, l’[exemple de tâche `<crowd-classifier>`](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/) est utilisé, mais avec une variable pour `<classification-target>`. Si vous essayez de maintenir un style CSS cohérent parmi une série de tâches d’étiquetage différentes, vous pouvez inclure une feuille de style externe à l’aide d’un élément `<link rel...>`, de la même manière que vous le feriez dans n’importe quel autre document HTML.  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<crowd-form>
  <crowd-classifier
    name="intent"
    categories="['buy', 'eat', 'watch', 'browse', 'leave']"
    header="Pick the most relevant intent expressed by the text below"
  >
    <classification-target>
      {{ task.input.source }}
    </classification-target>
    
    <full-instructions header="Emotion Classification Instructions">
      <p>In the statements and questions provided in this exercise, what category of action is the speaker interested in doing?</p>
          <table>
            <tr>
              <th>Example Utterance</th>
              <th>Good Choice</th>
            </tr>
            <tr>
              <td>When is the Seahawks game on?</td>
              <td>
                eat<br>
                <greenbg>watch</greenbg>
                <botchoice>browse</botchoice>
              </td>
            </tr>
            <tr>
              <th>Example Utterance</th>
              <th>Bad Choice</th>
            </tr>
            <tr>
              <td>When is the Seahawks game on?</td>
              <td>
                buy<br>
                <greenbg>eat</greenbg>
                <botchoice>watch</botchoice>
              </td>
            </tr>
          </table>
    </full-instructions>

    <short-instructions>
      What is the speaker expressing they would like to do next?
    </short-instructions>  
  </crowd-classifier>
</crowd-form>
<style>
  greenbg {
    background: #feee23;
    display: block;
  }

  table {
    *border-collapse: collapse; /* IE7 and lower */
    border-spacing: 0; 
  }

  th, tfoot, .fakehead {
    background-color: #8888ee;
    color: #f3f3f3;
    font-weight: 700;
  }

  th, td, tfoot {
      border: 1px solid blue;
  }

  th:first-child {
    border-radius: 6px 0 0 0;
  }

  th:last-child {
    border-radius: 0 6px 0 0;
  }

  th:only-child{
    border-radius: 6px 6px 0 0;
  }

  tfoot:first-child {
    border-radius: 0 0 6px 0;
  }

  tfoot:last-child {
    border-radius: 0 0 0 6px;
  }

  tfoot:only-child{
    border-radius: 6px 6px;
  }

  td {
    padding-left: 15px ;
    padding-right: 15px ;
  }

  botchoice {
    display: block;
    height: 17px;
    width: 490px;
    overflow: hidden;
    position: relative;
    background: #fff;
    padding-bottom: 20px;
  }

  botchoice:after {
    position: absolute;
    bottom: 0;
    left: 0;  
    height: 100%;
    width: 100%;
    content: "";
    background: linear-gradient(to top,
       rgba(255,255,255, 1) 55%, 
       rgba(255,255,255, 0) 100%
    );
    pointer-events: none; /* so the text is still selectable */
  }
</style>
```

**Example Votre fichier manifeste**  
Si vous préparez votre fichier manifeste manuellement pour une tâche de classification de texte de ce type, vous devrez formater vos données de la façon suivante.  

```
{"source": "Roses are red"}
{"source": "Violets are Blue"}
{"source": "Ground Truth is the best"}
{"source": "And so are you"}
```

Il est différent du fichier manifeste utilisé pour la démonstration « [Modèle de démonstration : annotation d'images avec `crowd-bounding-box`](sms-custom-templates-step2-demo1.md) » car le `source-ref` a été utilisé comme nom de propriété et non comme `source`. L’utilisation de `source-ref` désigne les URI S3 pour les images ou d’autres fichiers qui doivent être convertis en HTTP. Dans le cas contraire, `source` doit être utilisé comme il l’est avec les chaînes de texte ci-dessus.

## Votre fonction Lambda de pré-annotation
<a name="sms-custom-templates-step2-demo2-pre-lambda"></a>

Dans le cadre de la configuration de la tâche, fournissez l'ARN d'un fichier AWS Lambda qui peut être appelé pour traiter les entrées de votre manifeste et transmettez-les au moteur de modèles. 

Cette fonction Lambda est requise pour que l’une des quatre chaînes suivantes fasse partie du nom de la fonction : `SageMaker`, `Sagemaker`, `sagemaker` ou `LabelingFunction`.

Cela s’applique à la fois aux Lambdas pré-annotation et post-annotation.

Lorsque vous utilisez la console, si vous avez des fonctions Lambda qui appartiennent à votre compte, une liste déroulante des fonctions répondant aux exigences d’appellation s’affiche pour vous permettre d’en choisir une.

Dans cet exemple très basique où vous n’avez qu’une seule variable, il s’agit principalement d’une fonction de passerelle. Vous trouverez ci-dessous un exemple de pré-étiquetage Lambda à l’aide de Python 3.7.

```
import json

def lambda_handler(event, context):
    return {
        "taskInput":  event['dataObject']
    }
```

La propriété `dataObject` de l’`event` contient les propriétés d’un objet de données dans votre manifeste.

Dans cette démonstration, qui est une simple transmission d’une variable, vous la transmettez simplement en tant que valeur `taskInput`. Si vous ajoutez des propriétés avec ces valeurs à l’objet `event['dataObject']`, elles seront disponibles pour votre modèle HTML en tant que variables Liquid au format `{{ task.input.{{<property name>}} }}`.

## Votre fonction Lambda post-annotation
<a name="sms-custom-templates-step2-demo2-post-lambda"></a>

Dans le cadre de la configuration de la tâche, vous devrez fournir l’ARN d’une fonction Lambda qui peut être appelée pour traiter les données de formulaire lorsqu’un employé effectue une tâche. Cela peut être aussi simple ou complexe que vous le souhaitez. Si vous souhaitez consolider les réponses et les noter au fur et à mesure qu’elles arrivent, vous pouvez appliquer les algorithmes de notation et/ou de consolidation de votre choix. Si vous souhaitez stocker les données brutes en vue d’un traitement hors ligne, c’est possible.

**Définissez les autorisations pour votre fonction Lambda post-annotation**  
Les données d’annotation seront stockées dans un fichier désigné par la chaîne `s3Uri` dans l’objet `payload`. Pour traiter les annotations au fur et à mesure qu’elles arrivent, même pour une simple fonction de transmission, vous devez attribuer l’accès `S3ReadOnly` à votre fonction Lambda afin qu’elle puisse lire les fichiers d’annotation.  
Dans la page de la console relative à la création de votre fonction Lambda, faites défiler le panneau **Rôle d’exécution**. Sélectionnez **Create a new role from one or more templates (Créer un rôle à partir d’un ou de plusieurs modèles)**. Nommez le rôle. Dans la liste déroulante **Modèles de stratégie**, choisissez **Autorisations en lecture seule d’un objet Amazon S3**. Enregistrez la fonction Lambda. Le rôle est enregistré et sélectionné.

L’exemple suivant concerne Python 3.7.

```
import json
import boto3
from urllib.parse import urlparse

def lambda_handler(event, context):
    consolidated_labels = []

    parsed_url = urlparse(event['payload']['s3Uri']);
    s3 = boto3.client('s3')
    textFile = s3.get_object(Bucket = parsed_url.netloc, Key = parsed_url.path[1:])
    filecont = textFile['Body'].read()
    annotations = json.loads(filecont);
    
    for dataset in annotations:
        for annotation in dataset['annotations']:
            new_annotation = json.loads(annotation['annotationData']['content'])
            label = {
                'datasetObjectId': dataset['datasetObjectId'],
                'consolidatedAnnotation' : {
                'content': {
                    event['labelAttributeName']: {
                        'workerId': annotation['workerId'],
                        'result': new_annotation,
                        'labeledContent': dataset['dataObject']
                        }
                    }
                }
            }
            consolidated_labels.append(label)

    return consolidated_labels
```

## Votre sortie de tâche d’étiquetage
<a name="sms-custom-templates-step2-demo2-job-output"></a>

La fonction de post-traitement Lambda reçoit souvent des lots de résultats de tâches dans l’objet d’événement. Ce lot sera l’objet `payload` sur lequel la fonction Lambda devra itérer.

Vous trouverez la sortie de la tâche dans un dossier nommé d’après votre tâche d’étiquetage dans le compartiment S3 cible que vous avez spécifié. Elle figurera dans un sous-dossier nommé `manifests`.

Pour une tâche de détection des intentions, la sortie que vous trouverez dans le manifeste de sortie ressemblera un peu à la démonstration ci-dessous. L’exemple a été ordonné et espacé afin que les humains aient moins de mal à le lire. La sortie réelle sera plus compressée pour la lecture par machine.

**Example Objet JSON dans votre manifeste de sortie**  

```
[
  {
    "datasetObjectId":"<Number representing item's place in the manifest>",
     "consolidatedAnnotation":
     {
       "content":
       {
         "<name of labeling job>":
         {     
           "workerId":"private.us-east-1.{{XXXXXXXXXXXXXXXXXXXXXX}}",
           "result":
           {
             "intent":
             {
                 "label":"<label chosen by worker>"
             }
           },
           "labeledContent":
           {
             "content":"<text content that was labeled>"
           }
         }
       }
     }
   },
  "datasetObjectId":"<Number representing item's place in the manifest>",
     "consolidatedAnnotation":
     {
       "content":
       {
         "<name of labeling job>":
         {     
           "workerId":"private.us-east-1.6UDLPKQZHYWJQSCA4MBJBB7FWE",
           "result":
           {
             "intent":
             {
                 "label": "<label chosen by worker>"
             }
           },
           "labeledContent":
           {
             "content": "<text content that was labeled>"
           }
         }
       }
     }
   },
     ...
     ...
     ...
]
```

Cet exemple devrait vous aider à créer et à utiliser votre propre modèle personnalisé.