Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

So lösen Sie ein Problem auf Kaggle mit TF-Hub

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

TF-Hub ist eine Plattform zum Austausch von Fachwissen über maschinelles Lernen, das in wiederverwendbaren Ressourcen, insbesondere vorgefertigten Modulen, verpackt ist. In diesem Tutorial verwenden wir ein TF-Hub-Texteinbettungsmodul, um einen einfachen Stimmungsklassifikator mit einer angemessenen Basisgenauigkeit zu trainieren. Wir werden dann die Vorhersagen an Kaggle senden.

Ein ausführlicheres Tutorial zur Textklassifizierung mit TF-Hub und weitere Schritte zur Verbesserung der Genauigkeit finden Sie unter Textklassifizierung mit TF-Hub .

Konfiguration

pip install -q kaggle
import tensorflow as tf
import tensorflow_hub as hub
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import zipfile

from sklearn import model_selection

Da in diesem Lernprogramm ein Datensatz von Kaggle verwendet wird, muss ein API-Token für Ihr Kaggle-Konto erstellt und in die Colab-Umgebung hochgeladen werden.

import os
import pathlib

# Upload the API token.
def get_kaggle():
  try:
    import kaggle
    return kaggle
  except OSError:
    pass

  token_file = pathlib.Path("~/.kaggle/kaggle.json").expanduser()
  token_file.parent.mkdir(exist_ok=True, parents=True)

  try:
    from google.colab import files
  except ImportError:
    raise ValueError("Could not find kaggle token.")

  uploaded = files.upload()
  token_content = uploaded.get('kaggle.json', None)
  if token_content:
    token_file.write_bytes(token_content)
    token_file.chmod(0o600)
  else:
    raise ValueError('Need a file named "kaggle.json"')
  
  import kaggle
  return kaggle


kaggle = get_kaggle()

Fertig machen

Daten

Wir werden versuchen , das zu lösen Sentiment Analysis auf Movie Reviews Aufgabe von Kaggle. Der Datensatz besteht aus syntaktischen Unterphrasen der Filmkritiken von Rotten Tomatoes. Die Aufgabe besteht darin, die Phrasen auf der Skala von 1 bis 5 als negativ oder positiv zu kennzeichnen.

Sie müssen die Wettbewerbsregeln akzeptieren, bevor Sie die API zum Herunterladen der Daten verwenden können.

SENTIMENT_LABELS = [
    "negative", "somewhat negative", "neutral", "somewhat positive", "positive"
]

# Add a column with readable values representing the sentiment.
def add_readable_labels_column(df, sentiment_value_column):
  df["SentimentLabel"] = df[sentiment_value_column].replace(
      range(5), SENTIMENT_LABELS)
    
# Download data from Kaggle and create a DataFrame.
def load_data_from_zip(path):
  with zipfile.ZipFile(path, "r") as zip_ref:
    name = zip_ref.namelist()[0]
    with zip_ref.open(name) as zf:
      return pd.read_csv(zf, sep="\t", index_col=0)


# The data does not come with a validation set so we'll create one from the
# training set.
def get_data(competition, train_file, test_file, validation_set_ratio=0.1):
  data_path = pathlib.Path("data")
  kaggle.api.competition_download_files(competition, data_path)
  competition_path = (data_path/competition)
  competition_path.mkdir(exist_ok=True, parents=True)
  competition_zip_path = competition_path.with_suffix(".zip")

  with zipfile.ZipFile(competition_zip_path, "r") as zip_ref:
    zip_ref.extractall(competition_path)
  
  train_df = load_data_from_zip(competition_path/train_file)
  test_df = load_data_from_zip(competition_path/test_file)

  # Add a human readable label.
  add_readable_labels_column(train_df, "Sentiment")

  # We split by sentence ids, because we don't want to have phrases belonging
  # to the same sentence in both training and validation set.
  train_indices, validation_indices = model_selection.train_test_split(
      np.unique(train_df["SentenceId"]),
      test_size=validation_set_ratio,
      random_state=0)

  validation_df = train_df[train_df["SentenceId"].isin(validation_indices)]
  train_df = train_df[train_df["SentenceId"].isin(train_indices)]
  print("Split the training data into %d training and %d validation examples." %
        (len(train_df), len(validation_df)))

  return train_df, validation_df, test_df


train_df, validation_df, test_df = get_data(
    "sentiment-analysis-on-movie-reviews",
    "train.tsv.zip", "test.tsv.zip")
Split the training data into 140315 training and 15745 validation examples.

train_df.head(20)

Ein Modell trainieren

class MyModel(tf.keras.Model):
  def __init__(self, hub_url):
    super().__init__()
    self.hub_url = hub_url
    self.embed = hub.load(self.hub_url).signatures['default']
    self.sequential = tf.keras.Sequential([
      tf.keras.layers.Dense(500),
      tf.keras.layers.Dense(100),
      tf.keras.layers.Dense(5),
    ])

  def call(self, inputs):
    phrases = inputs['Phrase'][:,0]
    embedding = 5*self.embed(phrases)['default']
    return self.sequential(embedding)

  def get_config(self):
    return {"hub_url":self.hub_url}
model = MyModel("https://tfhub.dev/google/nnlm-en-dim128/1")
model.compile(
    loss = tf.losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer=tf.optimizers.Adam(), 
    metrics = [tf.keras.metrics.SparseCategoricalAccuracy(name="accuracy")])
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

history = model.fit(x=dict(train_df), y=train_df['Sentiment'],
          validation_data=(dict(validation_df), validation_df['Sentiment']),
          epochs = 25)
Epoch 1/25
4385/4385 [==============================] - 11s 3ms/step - loss: 1.0242 - accuracy: 0.5859 - val_loss: 0.9890 - val_accuracy: 0.5906
Epoch 2/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9994 - accuracy: 0.5952 - val_loss: 0.9910 - val_accuracy: 0.5867
Epoch 3/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9951 - accuracy: 0.5972 - val_loss: 0.9873 - val_accuracy: 0.5931
Epoch 4/25
4385/4385 [==============================] - 11s 3ms/step - loss: 0.9933 - accuracy: 0.5967 - val_loss: 0.9851 - val_accuracy: 0.5933
Epoch 5/25
4385/4385 [==============================] - 11s 3ms/step - loss: 0.9919 - accuracy: 0.5974 - val_loss: 0.9826 - val_accuracy: 0.5936
Epoch 6/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9905 - accuracy: 0.5981 - val_loss: 0.9822 - val_accuracy: 0.5966
Epoch 7/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9902 - accuracy: 0.5989 - val_loss: 0.9780 - val_accuracy: 0.5954
Epoch 8/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9888 - accuracy: 0.5987 - val_loss: 0.9846 - val_accuracy: 0.5942
Epoch 9/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9887 - accuracy: 0.5988 - val_loss: 0.9826 - val_accuracy: 0.5940
Epoch 10/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9882 - accuracy: 0.5988 - val_loss: 0.9774 - val_accuracy: 0.6039
Epoch 11/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9878 - accuracy: 0.5991 - val_loss: 0.9818 - val_accuracy: 0.5912
Epoch 12/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9875 - accuracy: 0.5998 - val_loss: 0.9754 - val_accuracy: 0.5967
Epoch 13/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9872 - accuracy: 0.6000 - val_loss: 0.9820 - val_accuracy: 0.5979
Epoch 14/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9874 - accuracy: 0.5991 - val_loss: 0.9842 - val_accuracy: 0.5904
Epoch 15/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9869 - accuracy: 0.5993 - val_loss: 0.9791 - val_accuracy: 0.5987
Epoch 16/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9867 - accuracy: 0.5993 - val_loss: 0.9755 - val_accuracy: 0.5997
Epoch 17/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9866 - accuracy: 0.5997 - val_loss: 0.9816 - val_accuracy: 0.5940
Epoch 18/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9864 - accuracy: 0.5993 - val_loss: 0.9765 - val_accuracy: 0.6031
Epoch 19/25
4385/4385 [==============================] - 11s 3ms/step - loss: 0.9863 - accuracy: 0.5998 - val_loss: 0.9849 - val_accuracy: 0.5938
Epoch 20/25
4385/4385 [==============================] - 12s 3ms/step - loss: 0.9864 - accuracy: 0.5991 - val_loss: 0.9780 - val_accuracy: 0.6007
Epoch 21/25
4385/4385 [==============================] - 11s 3ms/step - loss: 0.9859 - accuracy: 0.5997 - val_loss: 0.9758 - val_accuracy: 0.6003
Epoch 22/25
4385/4385 [==============================] - 13s 3ms/step - loss: 0.9857 - accuracy: 0.5995 - val_loss: 0.9861 - val_accuracy: 0.5880
Epoch 23/25
4385/4385 [==============================] - 11s 3ms/step - loss: 0.9862 - accuracy: 0.5996 - val_loss: 0.9765 - val_accuracy: 0.5978
Epoch 24/25
2532/4385 [================>.............] - ETA: 4s - loss: 0.9856 - accuracy: 0.5998

Prognose

Führen Sie Vorhersagen für den Validierungssatz und den Trainingssatz aus.

plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
[<matplotlib.lines.Line2D at 0x7f0eec3a5908>]

png

train_eval_result = model.evaluate(dict(train_df), train_df['Sentiment'])
validation_eval_result = model.evaluate(dict(validation_df), validation_df['Sentiment'])

print(f"Training set accuracy: {train_eval_result[1]}")
print(f"Validation set accuracy: {validation_eval_result[1]}")
4385/4385 [==============================] - 9s 2ms/step - loss: 0.9817 - accuracy: 0.6022
493/493 [==============================] - 1s 2ms/step - loss: 0.9757 - accuracy: 0.5980
Training set accuracy: 0.6022164225578308
Validation set accuracy: 0.5980311036109924

Verwirrung Matrix

Eine weitere sehr interessante Statistik, insbesondere für Probleme mit mehreren Klassen, ist die Verwirrungsmatrix . Die Verwirrungsmatrix ermöglicht die Visualisierung des Anteils korrekt und falsch beschrifteter Beispiele. Wir können leicht erkennen, wie stark unser Klassifikator voreingenommen ist und ob die Verteilung von Etiketten sinnvoll ist. Idealerweise sollte der größte Teil der Vorhersagen entlang der Diagonale verteilt sein.

predictions = model.predict(dict(validation_df))
predictions = tf.argmax(predictions, axis=-1)
predictions
<tf.Tensor: shape=(15745,), dtype=int64, numpy=array([1, 1, 2, ..., 2, 2, 2])>
cm = tf.math.confusion_matrix(validation_df['Sentiment'], predictions)
cm = cm/cm.numpy().sum(axis=1)[:, tf.newaxis]
sns.heatmap(
    cm, annot=True,
    xticklabels=SENTIMENT_LABELS,
    yticklabels=SENTIMENT_LABELS)
plt.xlabel("Predicted")
plt.ylabel("True")
Text(32.99999999999999, 0.5, 'True')

png

Wir können die Vorhersagen einfach an Kaggle zurücksenden, indem wir den folgenden Code in eine Codezelle einfügen und ausführen:

test_predictions = model.predict(dict(test_df))
test_predictions = np.argmax(test_predictions, axis=-1)

result_df = test_df.copy()

result_df["Predictions"] = test_predictions

result_df.to_csv(
    "predictions.csv",
    columns=["Predictions"],
    header=["Sentiment"])
kaggle.api.competition_submit("predictions.csv", "Submitted from Colab",
                              "sentiment-analysis-on-movie-reviews")

Überprüfen Sie nach dem Absenden die Bestenliste, um zu sehen, wie Sie es gemacht haben.