chatgpt-sentiment-loop

textmining
nlp
transformer
chatgpt
sentiment
Published

December 5, 2023

Aufgabe

Fragen Sie ChatGPT via API zum Sentiment der ersten zwei Texte aus dem Germeval-2018-Datensatz (Train).

Hinweise:

  • Beachten Sie die Standardhinweise des Datenwerks.
  • Nutzen Sie Python, nicht R.
  • Das Verwenden der OpenAI-API kostet Geld. 💸 Informieren Sie sich vorab. Um auf die API zugreifen zu können, müssen Sie sich ein Konto angelegt haben und über ein Guthaben verfügen.











Lösung

OpenAI hat eine neue API (Stand: 2023-11-23), V1.3.5. Der Code der alten API bricht. 💔 \(\square\)

Die richtige venv nutzen:

library(reticulate)
#virtualenv_create("chatgpt")
use_virtualenv("chatgpt")

Check zu Python:

reticulate::py_config()
python:         /Users/sebastiansaueruser/.virtualenvs/chatgpt/bin/python
libpython:      /Users/sebastiansaueruser/.pyenv/versions/3.11.1/lib/libpython3.11.dylib
pythonhome:     /Users/sebastiansaueruser/.virtualenvs/chatgpt:/Users/sebastiansaueruser/.virtualenvs/chatgpt
version:        3.11.1 (main, Oct  4 2023, 18:12:06) [Clang 15.0.0 (clang-1500.0.40.1)]
numpy:          /Users/sebastiansaueruser/.virtualenvs/chatgpt/lib/python3.11/site-packages/numpy
numpy_version:  1.26.2

NOTE: Python version was forced by use_python() function

Ggf. noch Module installieren:

#reticulate::py_install("pandas")

Module importieren:

from openai import OpenAI
import pandas as pd
import time 
import tiktoken  # Token zählen

Versionen der importierten Module:

pd.__version__
'2.1.3'
```{zsh}
pip list | grep openai
```

[notice] A new release of pip is available: 23.3.1 -> 23.3.2
[notice] To update, run: pip install --upgrade pip
openai             1.3.5

Wir brauchen >= 1.35.

Daten importieren:

csv_file_path_train = 'https://github.com/sebastiansauer/pradadata/raw/master/data-raw/germeval_train.csv'

germeval_train = pd.read_csv(csv_file_path_train)

Die ersten paar Texte herausziehen:

n_tweets = 2
tweets_first_few = germeval_train["text"].head(n_tweets).tolist()
tweets_first_few
['@corinnamilborn Liebe Corinna, wir würden dich gerne als Moderatorin für uns gewinnen! Wärst du begeisterbar?', '@Martin28a Sie haben ja auch Recht. Unser Tweet war etwas missverständlich. Dass das BVerfG Sachleistungen nicht ausschließt, kritisieren wir.']

Prompt definieren:

prompt_stem  = "Als KI mit Exertise in natürlicher Sprache und Emotionserkennung ist es Ihre Aufgabe, das Sentiment des folgenden Textes zu erkennen. Bitte antworten Sie nur mit einem Wort, entweder 'positiv', 'neutral' oder 'negativ'. Dieses Wort soll die Insgesamt-Einschätzung des Sentiments des Textes zusammenfassen. Nach dem Doppelpunkt folt der Text, dessen Sentiment Sie einschätzen sollen: \n"

Mit “List Comprehension” können wir die Tweets jeweils mit dem Prompt verknüpfen:

prompts = [prompt_stem + tweet for tweet in tweets_first_few]
prompts[0]
"Als KI mit Exertise in natürlicher Sprache und Emotionserkennung ist es Ihre Aufgabe, das Sentiment des folgenden Textes zu erkennen. Bitte antworten Sie nur mit einem Wort, entweder 'positiv', 'neutral' oder 'negativ'. Dieses Wort soll die Insgesamt-Einschätzung des Sentiments des Textes zusammenfassen. Nach dem Doppelpunkt folt der Text, dessen Sentiment Sie einschätzen sollen: \n@corinnamilborn Liebe Corinna, wir würden dich gerne als Moderatorin für uns gewinnen! Wärst du begeisterbar?"

Check: Wie viele Elemente hat die Liste prompts?

len(prompts)
2

Check: Wie viele Tokens hat jeder String (jeder Prompt)?

Wir definieren eine Helper-Funktion:

def count_tokens(string: str, encoding_name: str) -> int:
    encoding = tiktoken.get_encoding(encoding_name)
    num_tokens = len(encoding.encode(string))
    return num_tokens

Und zählen:

encoding_name = "cl100k_base"

num_tokens_list = [count_tokens(prompt, encoding_name) for prompt in prompts]

for i, num_tokens in enumerate(num_tokens_list):
    print(f"The number of tokens in Prompt {[i]} is {num_tokens}.")
The number of tokens in Prompt [0] is 142.
The number of tokens in Prompt [1] is 153.

Mehr Infos zum Encoding bei ChatGPT finden sich hier.

Laut OpenAI kostet 1k Token für das Modell gpt-3.5-turbo-1106 $0.001.

Anmelden bei OpenAI:

client = OpenAI()
Note

Dieses Anmeldeverfahren setzt voraus, dass in .Renviron die Variable OPENAI_API_KEY hinterlegt ist. \(\square\)

Anfrage an die API, in eine Funktion gepackt:

def get_completion(prompt, client_instance, model="gpt-3.5-turbo"):
  messages = [{"role": "user", "content": prompt}]
  response = client_instance.chat.completions.create(
    model=model,
    messages=messages,
    max_tokens=50,
    temperature=0,
  )
  return response.choices[0].message.content

Und jetzt als Schleife. Ergebnisliste anlegen, am Anfang noch leer:

results = []
start_time = time.time()

for prompt in prompts:
  result = get_completion(prompt, client) 
  results.append(result)

end_time = time.time()
end_time - start_time
2.179842948913574

Voilà:

print(results)
['positiv', 'neutral']