Cette page a été traduite par l'API Cloud Translation.
Switch to English

Encodeur de phrase universel

Voir sur TensorFlow.org Exécuter dans Google Colab Afficher la source sur GitHub Télécharger le cahier

Ce cahier explique comment accéder à Universal Sentence Encoder et l'utiliser pour les tâches de similarité et de classification de phrases.

L'encodeur de phrase universel permet d'obtenir des incorporations au niveau de la phrase aussi facile qu'il l'a toujours été pour rechercher les incorporations pour des mots individuels. Les imbrications de phrases peuvent ensuite être utilisées de manière triviale pour calculer la similarité de signification au niveau de la phrase ainsi que pour permettre de meilleures performances sur des tâches de classification en aval en utilisant des données d'apprentissage moins supervisées.

Installer

Cette section met en place l'environnement d'accès à Universal Sentence Encoder sur TF Hub et fournit des exemples d'application de l'encodeur à des mots, des phrases et des paragraphes.

 %%capture
!pip3 install seaborn
 

Des informations plus détaillées sur l'installation de Tensorflow sont disponibles à l' adresse https://www.tensorflow.org/install/ .

 
from absl import logging

import tensorflow as tf

import tensorflow_hub as hub
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import re
import seaborn as sns

module_url = "https://  tfhub.dev  /google/universal-sentence-encoder/4" 
model = hub.load(module_url)
print ("module %s loaded" % module_url)
def embed(input):
  return model(input)
 
module https://  tfhub.dev  /google/universal-sentence-encoder/4 loaded

 
word = "Elephant"
sentence = "I am a sentence for which I would like to get its embedding."
paragraph = (
    "Universal Sentence Encoder embeddings also support short paragraphs. "
    "There is no hard limit on how long the paragraph is. Roughly, the longer "
    "the more 'diluted' the embedding will be.")
messages = [word, sentence, paragraph]

# Reduce logging output.
logging.set_verbosity(logging.ERROR)

message_embeddings = embed(messages)

for i, message_embedding in enumerate(np.array(message_embeddings).tolist()):
  print("Message: {}".format(messages[i]))
  print("Embedding size: {}".format(len(message_embedding)))
  message_embedding_snippet = ", ".join(
      (str(x) for x in message_embedding[:3]))
  print("Embedding: [{}, ...]\n".format(message_embedding_snippet))
 
Message: Elephant
Embedding size: 512
Embedding: [0.008344489149749279, 0.0004808177181985229, 0.06595245748758316, ...]

Message: I am a sentence for which I would like to get its embedding.
Embedding size: 512
Embedding: [0.0508086197078228, -0.01652432419359684, 0.015737777575850487, ...]

Message: Universal Sentence Encoder embeddings also support short paragraphs. There is no hard limit on how long the paragraph is. Roughly, the longer the more 'diluted' the embedding will be.
Embedding size: 512
Embedding: [-0.028332669287919998, -0.0558621771633625, -0.01294146291911602, ...]


Exemple de tâche de similarité textuelle sémantique

Les imbrications produites par Universal Sentence Encoder sont approximativement normalisées. La similitude sémantique de deux phrases peut être trivialement calculée comme le produit interne des encodages.

 def plot_similarity(labels, features, rotation):
  corr = np.inner(features, features)
  sns.set(font_scale=1.2)
  g = sns.heatmap(
      corr,
      xticklabels=labels,
      yticklabels=labels,
      vmin=0,
      vmax=1,
      cmap="YlOrRd")
  g.set_xticklabels(labels, rotation=rotation)
  g.set_title("Semantic Textual Similarity")

def run_and_plot(messages_):
  message_embeddings_ = embed(messages_)
  plot_similarity(messages_, message_embeddings_, 90)
 

Similarité visualisée

Ici, nous montrons la similitude dans une carte de chaleur. Le graphique final est une matrice 9x9 où chaque entrée [i, j] est colorée en fonction du produit interne des encodages pour les phrases i et j .

 messages = [
    # Smartphones
    "I like my phone",
    "My phone is not good.",
    "Your cellphone looks great.",

    # Weather
    "Will it snow tomorrow?",
    "Recently a lot of hurricanes have hit the US",
    "Global warming is real",

    # Food and health
    "An apple a day, keeps the doctors away",
    "Eating strawberries is healthy",
    "Is paleo better than keto?",

    # Asking about age
    "How old are you?",
    "what is your age?",
]

run_and_plot(messages)
               
 

png

Évaluation: Benchmark STS (Semantic Textual Similarity)

Le STS Benchmark fournit une évaluation intristique du degré auquel les scores de similarité calculés à l'aide de l'intégration de phrases s'alignent sur les jugements humains. Le benchmark exige que les systèmes renvoient des scores de similarité pour une sélection diversifiée de paires de phrases. La corrélation de Pearson est ensuite utilisée pour évaluer la qualité des scores de similarité de la machine par rapport aux jugements humains.

Télécharger les données

 import pandas
import scipy
import math
import csv

sts_dataset = tf.keras.utils.get_file(
    fname="Stsbenchmark.tar.gz",
    origin="http://ixa2.si.ehu.es/stswiki/images/4/48/Stsbenchmark.tar.gz",
    extract=True)
sts_dev = pandas.read_table(
    os.path.join(os.path.dirname(sts_dataset), "stsbenchmark", "sts-dev.csv"),
    error_bad_lines=False,
    skip_blank_lines=True,
    usecols=[4, 5, 6],
    names=["sim", "sent_1", "sent_2"])
sts_test = pandas.read_table(
    os.path.join(
        os.path.dirname(sts_dataset), "stsbenchmark", "sts-test.csv"),
    error_bad_lines=False,
    quoting=csv.QUOTE_NONE,
    skip_blank_lines=True,
    usecols=[4, 5, 6],
    names=["sim", "sent_1", "sent_2"])
# cleanup some NaN values in sts_dev
sts_dev = sts_dev[[isinstance(s, str) for s in sts_dev['sent_2']]]
 
Downloading data from http://ixa2.si.ehu.es/stswiki/images/4/48/Stsbenchmark.tar.gz
417792/409630 [==============================] - 4s 10us/step

Évaluer les incorporations de phrases

 sts_data = sts_dev 

def run_sts_benchmark(batch):
  sts_encode1 = tf.nn.l2_normalize(embed(tf.constant(batch['sent_1'].tolist())), axis=1)
  sts_encode2 = tf.nn.l2_normalize(embed(tf.constant(batch['sent_2'].tolist())), axis=1)
  cosine_similarities = tf.reduce_sum(tf.multiply(sts_encode1, sts_encode2), axis=1)
  clip_cosine_similarities = tf.clip_by_value(cosine_similarities, -1.0, 1.0)
  scores = 1.0 - tf.acos(clip_cosine_similarities) / math.pi
  """Returns the similarity scores"""
  return scores

dev_scores = sts_data['sim'].tolist()
scores = []
for batch in np.array_split(sts_data, 10):
  scores.extend(run_sts_benchmark(batch))

pearson_correlation = scipy.stats.pearsonr(scores, dev_scores)
print('Pearson correlation coefficient = {0}\np-value = {1}'.format(
    pearson_correlation[0], pearson_correlation[1]))
 
Pearson correlation coefficient = 0.8036396870944293
p-value = 0.0