%pip install --quiet --upgrade instructor tqdm
[notice] A new release of pip is available: 23.0.1 -> 24.1.2
[notice] To update, run: pip install --upgrade pip
Note: you may need to restart the kernel to use updated packages.
If you have a bunch of data in a messy format (user-input text, usually), an LLM is a great way to pull out the useful parts. Instructor can help you take that content and turn it into structured data!
Let’s start by installing Instructor. We’ll also install tqdm, which allows for some nice progress bars.
[notice] A new release of pip is available: 23.0.1 -> 24.1.2
[notice] To update, run: pip install --upgrade pip
Note: you may need to restart the kernel to use updated packages.
First we’ll use Instructor on a single line of code. In this case, extracting structured data from an article.
Each article has a summary, a list of sources, a language and and a category. Each “source” has both a name and an optional title.
You’ll need your own OpenAI API key to serve as your username and password when connecting Instructor to GPT. You can get yours here. Feel free to email me to borrow one of my API keys, you can find me at js4571@columbia.edu
import instructor
from pydantic import BaseModel, Field
from openai import OpenAI
from typing import Optional, List
from typing_extensions import Literal
class Person(BaseModel):
name: str = Field(description="Person's name")
title: Optional[str] = Field(description="Person's title, if available")
class Article(BaseModel):
summary: str = Field(description="Brief, one-sentence summary (in English)")
sources: List[Person] = Field(description="People mentioned in the article")
language_code: str = Field(description="Two-letter language code of original text")
category: Literal["politics", "sports", "international", "other"]
# Add your own API key
client = instructor.from_openai(OpenAI(api_key='sk-proj-XXXXXXXXXXXXXXXXXXXX'))
The article we’ll be analyzing is below.
article = """
"Elections européennes : Emmanuel Macron dénonce « l'hypocrisie » du RN
Le chef de l'Etat a déploré mercredi depuis Bruxelles que les « peurs profitent aux réponses les plus simplistes » dans la campagne pour le scrutin du 9 juin, fustigeant ceux qui dénoncent l'Union européenne tout en engrangeant les « dividendes silencieux ».
Vous pouvez partager un article en cliquant sur les icônes de partage en haut à droite de celui-ci.
La reproduction totale ou partielle d'un article, sans l'autorisation écrite et préalable du Monde, est strictement interdite.
Pour plus d'informations, consultez nos conditions générales de vente.
Pour toute demande d'autorisation, contactez syndication@lemonde.fr.
En tant qu'abonné, vous pouvez offrir jusqu'à cinq articles par mois à l'un de vos proches grâce à la fonctionnalité « Offrir un article ».
https://www.lemonde.fr/elections-europeennes/article/2024/04/17/elections-europeennes-emmanuel-macron-denonce-l-hypocrisie-du-rn_6228404_1168667.html
Interrogé en marge de son déplacement à Bruxelles sur la campagne des élections européennes, Emmanuel Macron a déploré que les « peurs profitent aux réponses les plus simplistes », mercredi 17 avril. Il a également fustigé « l'hypocrisie » de ceux qui dénoncent l'Union européenne mais en engrangent les « dividendes silencieux ».
« Je pense qu'il y a beaucoup de peurs, d'inquiétudes dans le moment que nous vivons et que ces colères profitent toujours aux réponses les plus simplistes », a déclaré le chef de l'Etat français lors de son arrivée dans la capitale belge avant la tenue d'un sommet européen, au cours d'un bref échange avec la presse aux côtés de la tête de liste de son camp aux européennes, Valérie Heyer. « Il y a aujourd'hui une espèce d'hypocrisie du débat et j'espère qu'en rentrant dans les prochaines semaines dans celui-ci, cette hypocrisie sera levée », a ajouté M. Macron, visant en creux le Rassemblement national (RN), dont la liste est conduite par Jordan Bardella.
Il s'agissait de la première apparition publique du chef de l'Etat et de Mme Hayer depuis le début de la campagne, avant qu'ils n'assistent ensemble à une réunion du groupe Renew Europe.
Vous pouvez partager un article en cliquant sur les icônes de partage en haut à droite de celui-ci.
La reproduction totale ou partielle d'un article, sans l'autorisation écrite et préalable du Monde, est strictement interdite.
Pour plus d'informations, consultez nos conditions générales de vente.
Pour toute demande d'autorisation, contactez syndication@lemonde.fr.
En tant qu'abonné, vous pouvez offrir jusqu'à cinq articles par mois à l'un de vos proches grâce à la fonctionnalité « Offrir un article ».
https://www.lemonde.fr/elections-europeennes/article/2024/04/17/elections-europeennes-emmanuel-macron-denonce-l-hypocrisie-du-rn_6228404_1168667.html
L'extrême droite ciblée par le camp présidentiel
La candidate du camp présidentiel peine pour l'instant à imprimer sa marque dans la campagne. La liste Renaissance reste largement distancée dans les sondages par celle du Rassemblement national (RN), qui ne cesse de creuser l'écart et caracole à plus de 30 % d'intentions de vote. Donnée autour de 16 % d'intentions, elle est également talonnée par celle du PS-Place publique, menée par Raphaël Glucksmann.
Le camp présidentiel est en outre suspendu à une entrée en campagne du chef de l'Etat, dont les contours n'ont pour l'heure pas été précisés, alors que le premier ministre, Gabriel Attal, reste pour l'heure discret en la matière. Ce dernier fait le pari que la campagne ne démarrera réellement que dans la dernière ligne droite, un mois avant le scrutin du 9 juin, mais l'exécutif cible ces dernières semaines l'extrême droite, qu'il considère comme son principal adversaire dans le scrutin.
Vous pouvez partager un article en cliquant sur les icônes de partage en haut à droite de celui-ci.
La reproduction totale ou partielle d'un article, sans l'autorisation écrite et préalable du Monde, est strictement interdite.
Pour plus d'informations, consultez nos conditions générales de vente.
Pour toute demande d'autorisation, contactez syndication@lemonde.fr.
En tant qu'abonné, vous pouvez offrir jusqu'à cinq articles par mois à l'un de vos proches grâce à la fonctionnalité « Offrir un article ».
https://www.lemonde.fr/elections-europeennes/article/2024/04/17/elections-europeennes-emmanuel-macron-denonce-l-hypocrisie-du-rn_6228404_1168667.html
Depuis Bruxelles, Emmanuel Macron a fait un premier pas dans l'offensive en vue du scrutin du 9 juin, ciblant ainsi sans le nommer le RN, et ses contradictions sur la question européenne, l'économie ou encore la diplomatie. « Ceux qui parfois il y a cinq ans disaient “la solution c'est sortir de l'euro”, ceux qui ne votent même pas la politique agricole commune mais ensuite disent à la maison aux agriculteurs “je vous défends”, ceux qui systématiquement ont essayé d'affaiblir l'Europe en quelque sorte ont les dividendes silencieux de notre propre politique proeuropéenne », a asséné Emmanuel Macron.
« Ils expliquent, “nous, on va rendre notre pays plus fort”. Si leur politique avait été suivie depuis cinq ans, on ne serait pas là pour parler de la même façon de notre Europe ! », a-t-il poursuivi, avant d'ajouter : « Ils auraient soigné [le Covid-19] à l'hydroxychloroquine, pris le vaccin russe, divisé l'Europe suite à l'agression russe. Ils n'auraient pris aucune sanction [contre la Russie], l'Ukraine aurait déjà été abandonnée. Et ils auraient abandonné aussi l'ambition européenne en matière de recherche et de technologie. »
"""
Now we will send the article to GPT, along with the Article
formatter. that describes what we want back.
The result was saved as result
, which we can look at nicely by printing out result.model_dump()
. It’s kind of complicated – there are a lot of sources! – which is why we’re using pretty printing.
{'category': 'politics',
'language_code': 'fr',
'sources': [{'name': 'Emmanuel Macron', 'title': 'President of France'},
{'name': 'Jordan Bardella',
'title': 'Head of the RN list for the European elections'},
{'name': 'Valérie Heyer',
'title': "Head of Macron's camp list for the European elections"},
{'name': 'Gabriel Attal', 'title': 'Prime Minister of France'},
{'name': 'Raphaël Glucksmann',
'title': 'Head of the PS-Place publique list for the European '
'elections'}],
'summary': "Emmanuel Macron critiques the 'hypocrisy' of the National Rally "
'(RN) during the European elections campaign.'}
You will often want to use Instructor not just with one element of data, but with many. Let’s try again with a spreadsheet of content!
Again, you’ll need your own OpenAI API key to serve as your username and password when connecting Instructor to GPT. You can get yours here. Feel free to email me to borrow one of my API keys, you can find me at js4571@columbia.edu
import pandas as pd
pd.options.display.max_colwidth = 500
df = pd.read_csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vQlfNIJOmGYG1vK1RkI5sa2R3_0fZohl7FIPwVN6HenlY-RZzzuIAiZ3E2GLITI6bANbYT7Wm1Lk_UA/pub?gid=228719919&single=true&output=csv")
df.head()
URL | content | |
---|---|---|
0 | https://www.nytimes.com/2024/04/17/us/politics/senate-alejandro-mayorkas-impeachment-charge.html | Senate Dismisses Impeachment Charges Against Mayorkas Without a Trial\n\nDemocrats quickly swept aside the articles of impeachment accusing the homeland security secretary of refusing to enforce immigration laws and breach of public trust, calling them unconstitutional.\n\nThe Senate on Wednesday dismissed the impeachment case against Alejandro N. Mayorkas, the homeland security secretary, voting along party lines before his trial got underway to sweep aside two charges accusing him of faili... |
1 | https://www.washingtonpost.com/national-security/2024/04/17/niger-air-force-whistleblower/ | Defying Niger exit order leaves U.S. troops vulnerable, whistleblower says\n\nDeployed Americans are in limbo, unable to do their jobs or go home while State Department seeks to extend military presence, complaint contends\n\nA senior U.S. Air Force leader deployed in Niger is raising an alarm over the Biden administration’s reluctance to heed an eviction notice from the military junta that last year overthrew the West African nation’s democratically elected government.\n\nThe airman, in a p... |
2 | https://www.washingtonpost.com/sports/2024/04/17/jake-irvin-nationals-dodgers-road-trip/ | Jake Irvin delivers as Nationals beat Dodgers again to close road trip\n\nLOS ANGELES — It was only fitting that Jake Irvin’s start Wednesday afternoon at Dodger Stadium ended the way it did: with a high fastball in on the hands of Los Angeles catcher Will Smith.\n\nIt was the sixth pitch of the at-bat. The Washington Nationals right-hander had thrown five fastballs in a row. For his sixth pitch, he didn’t deviate from the plan: He fired a fastball by Smith, notching his sixth strikeout in t... |
3 | https://www.lanacion.com.ar/economia/ante-inversores-en-washington-caputo-defendio-la-estrategia-fiscal-y-reafirmo-el-compromiso-para-nid17042024/ | Ante inversores en Washington, Caputo defendió la estrategia fiscal y reafirmó el compromiso para levantar el cepo\n\nEl jefe del Palacio de Hacienda participó de un seminario organizado por el banco J.P. Morgan\n\nWASHINGTON.- El ministro de Economía, Luis Caputo, llegó al seminario del banco de inversión J.P. Morgan en el Park Hyatt hotel poco después de las tres de la tarde, hora local, un rato después de aterrizar en Washington, junto con el secretario de Finanzas, Pablo Quirno. El títul... |
4 | https://www.lemonde.fr/elections-europeennes/article/2024/04/17/elections-europeennes-emmanuel-macron-denonce-l-hypocrisie-du-rn_6228404_1168667.html | Elections européennes : Emmanuel Macron dénonce « l’hypocrisie » du RN\n\nLe chef de l’Etat a déploré mercredi depuis Bruxelles que les « peurs profitent aux réponses les plus simplistes » dans la campagne pour le scrutin du 9 juin, fustigeant ceux qui dénoncent l’Union européenne tout en engrangeant les « dividendes silencieux ».\n\nVous pouvez partager un article en cliquant sur les icônes de partage en haut à droite de celui-ci. \nLa reproduction totale ou partielle d’un article, sans l’a... |
Before we get started I’m going to turn on tqdm, which gives us a nice progress bar as we go through each row. If we didn’t have a progress bar we’d never know how much longer we had to wait!
The process
function takes the content
column, then sends it to GPT to get a response. You can find a list of available models on OpenAI’s website, but gpt-4o
is a good combination of quality and price.
def process(row):
article = row['content']
result = client.chat.completions.create(
model="gpt-4o",
response_model=Article,
messages=[{"role": "user", "content": article}],
)
# Convert the dictionary into a pandas series
return pd.Series(result.model_dump())
# Run process for every row in the dataframe
ai_df = df.progress_apply(process, axis=1)
ai_df.head()
100%|██████████| 6/6 [00:54<00:00, 9.04s/it]
summary | sources | language_code | category | |
---|---|---|---|---|
0 | The Senate dismissed impeachment charges against Homeland Security Secretary Alejandro N. Mayorkas before trial, ruling the charges unconstitutional, with votes largely along party lines. | [{'name': 'Alejandro N. Mayorkas', 'title': 'Homeland Security Secretary'}, {'name': 'Chuck Schumer', 'title': 'Senator, Majority Leader'}, {'name': 'Lisa Murkowski', 'title': 'Senator'}, {'name': 'Mitch McConnell', 'title': 'Senator, Minority Leader'}, {'name': 'Mike Lee', 'title': 'Senator'}, {'name': 'John Thune', 'title': 'Senator'}, {'name': 'Mia Ehrenberg', 'title': 'Spokeswoman for the Department of Homeland Security'}] | en | politics |
1 | A senior U.S. Air Force leader in Niger has filed a whistleblower complaint accusing U.S. embassy officials of suppressing intelligence to maintain the appearance of a good relationship with Niger's junta, leaving U.S. troops vulnerable and unable to do their jobs or go home. | [{'name': 'Kathleen FitzGibbon', 'title': 'Ambassador'}, {'name': 'Nora J. Nelson-Richter', 'title': 'Air Force Col. and Defense Attaché'}, {'name': 'Dusty Johnson', 'title': 'Rep. (R-S.D.)'}] | en | politics |
2 | Jake Irvin's impressive performance leads Nationals to a 2-0 victory over the Dodgers, concluding their road trip with a series win. | [{'name': 'Jake Irvin', 'title': 'Washington Nationals right-hander'}, {'name': 'Luis García Jr.', 'title': 'second baseman'}, {'name': 'Dave Martinez', 'title': 'Manager'}] | en | sports |
3 | Luis Caputo defendió la estrategia fiscal y reafirmó el compromiso para levantar el cepo ante inversores en Washington, destacando los avances económicos del gobierno de Javier Milei. | [{'name': 'Luis Caputo', 'title': 'Ministro de Economía'}, {'name': 'Pablo Quirno', 'title': 'Secretario de Finanzas'}, {'name': 'Nicolás Posse', 'title': 'Jefe de Gabinete'}, {'name': 'Pierre-Olivier Gourinchas', 'title': 'Economista jefe del FMI'}] | es | politics |
4 | French President Emmanuel Macron criticizes the National Rally's (RN) "hypocrisy" in the European elections campaign, denouncing their anti-EU stance while benefiting from EU policies. | [{'name': 'Emmanuel Macron', 'title': 'President of France'}, {'name': 'Jordan Bardella', 'title': 'Head of the National Rally's list in the European elections'}, {'name': 'Valérie Heyer', 'title': 'Head of Macron's camp list in the European elections'}, {'name': 'Gabriel Attal', 'title': 'Prime Minister of France'}, {'name': 'Raphaël Glucksmann', 'title': 'Head of the PS-Place publique list'}] | fr | politics |
Now we can combine the AI results with the original dataframe and save it to a CSV file.
URL | content | summary | sources | language_code | category | |
---|---|---|---|---|---|---|
0 | https://www.nytimes.com/2024/04/17/us/politics/senate-alejandro-mayorkas-impeachment-charge.html | Senate Dismisses Impeachment Charges Against Mayorkas Without a Trial\n\nDemocrats quickly swept... | The Senate dismissed impeachment charges against Homeland Security Secretary Alejandro N. Mayork... | [{'name': 'Alejandro N. Mayorkas', 'title': 'Homeland Security Secretary'}, {'name': 'Chuck Schu... | en | politics |
1 | https://www.washingtonpost.com/national-security/2024/04/17/niger-air-force-whistleblower/ | Defying Niger exit order leaves U.S. troops vulnerable, whistleblower says\n\nDeployed Americans... | A senior U.S. Air Force leader in Niger has filed a whistleblower complaint accusing U.S. embass... | [{'name': 'Kathleen FitzGibbon', 'title': 'Ambassador'}, {'name': 'Nora J. Nelson-Richter', 'tit... | en | politics |
2 | https://www.washingtonpost.com/sports/2024/04/17/jake-irvin-nationals-dodgers-road-trip/ | Jake Irvin delivers as Nationals beat Dodgers again to close road trip\n\nLOS ANGELES — It was o... | Jake Irvin's impressive performance leads Nationals to a 2-0 victory over the Dodgers, concludin... | [{'name': 'Jake Irvin', 'title': 'Washington Nationals right-hander'}, {'name': 'Luis García Jr.... | en | sports |
3 | https://www.lanacion.com.ar/economia/ante-inversores-en-washington-caputo-defendio-la-estrategia... | Ante inversores en Washington, Caputo defendió la estrategia fiscal y reafirmó el compromiso par... | Luis Caputo defendió la estrategia fiscal y reafirmó el compromiso para levantar el cepo ante in... | [{'name': 'Luis Caputo', 'title': 'Ministro de Economía'}, {'name': 'Pablo Quirno', 'title': 'Se... | es | politics |
4 | https://www.lemonde.fr/elections-europeennes/article/2024/04/17/elections-europeennes-emmanuel-m... | Elections européennes : Emmanuel Macron dénonce « l’hypocrisie » du RN\n\nLe chef de l’Etat a dé... | French President Emmanuel Macron criticizes the National Rally's (RN) "hypocrisy" in the Europea... | [{'name': 'Emmanuel Macron', 'title': 'President of France'}, {'name': 'Jordan Bardella', 'title... | fr | politics |
Beautiful, right??
One fun part of Instructor is validating responses, to be able to do follow-up questions with GPT to make sure the responses are correct.
The approach below makes sure emails have an @
symbol in them.
import instructor
from pydantic import BaseModel, Field, field_validator
from openai import OpenAI
from typing import Optional, List
from typing_extensions import Literal
class Comment(BaseModel):
name: str = Field(description="Submitter name")
email: str = Field(description="Submitter email address")
position: Literal["for", "against", "neutral"] = Field("Position on the regulation")
@field_validator("email")
@classmethod
def validate_email(cls, value):
if value and '@' not in value:
raise ValueError("Email missing @")
return value
# Add your own API key
client = instructor.from_openai(OpenAI(api_key='sk-proj-XXXXXXXXXXXXXXXXXXXX'))
In the example below, Mulberry is hiding his email address by using (at)
and (dot)
. While GPT will usually correctly translate it into mulberry@catmail.com
, we can be super certain by demanding that all email addresses have an @
in them.
We set a maximum number of retries to allow a back-and-forth conversation with the LLM up to 3 times. And the final answer is… perfect!