Processing unstructured data to structured data

Text Analysis with large language models

Emi Tanaka

4th June 2025

These slides are best viewed on a modern browser like Google Chrome on a desktop or laptop. You can navigate the slides using the left and right arrows.

Unstructured data

  • Unstructured data lacks a predefined schema and can be highly variable in form.
  • Some examples of unstructured data include:
    • Texts (e.g., emails, articles, social media posts, support tickets)
    • Images and videos (e.g., photos, video recordings)
    • Audio files (e.g., podcasts, voice recordings)
    • Sensor data (e.g., IoT devices)

Processing to structured data

  • Unstructured data is hard to query, analyse or automate without first processing into structured data.
  • Processing unstructured data to structured data can be done using various methods, including:
    • Text extraction and parsing:
      • Rule-based system (e.g. regular expression)
      • Manual labelling
    • Image recognition and classification
    • Audio transcription

LLMs as text extractor

  • Trained on a diverse corpora and has a general “understanding” of natural language
library(ellmer)
chat <- chat_openai(model = "gpt-4.1",
                    system_prompt = '
Extract the following fields from the text:
- Customer name
- Complaint category
- Date
- Product

Text: "Hi, I\'m Alex. My AC Model X-200 failed yesterday."

Output:
{ "name": "Alex", "category": "product failure", "date": "yesterday", "product": "AC Model X-200" }')
  • From one shot training above, we have
chat$chat("Hey there, I'm Emi and my apple watch malfunctioned today.")
{ "name": "Emi", "category": "product malfunction", "date": "today", "product":
"apple watch" }

Structured chat with LLM

  • Prompt engineering for structured data, however, doesn’t guarantee the adherance to the desired schema.
  • Certain LLM has been trained specifically for structured chat output:
  • In the first instance, you have to define the JSON schema for the output.

JSON schema

  • JSON is one of the most popular format for exchanging data
{
    "name": "user_data",
    "strict": true,
    "schema": {
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "description": "The name of the user"
            },
            "username": {
                "type": "string",
                "description": "The username of the user. Must start with @"
            },
            "email": {
                "type": "string",
                "description": "The email of the user"
            }
        },
        "additionalProperties": false,
        "required": [
            "name", "username", "email"
        ]
    }
}
JSON type R class
“string” “character”
“number” “numeric”
“boolean” “logical”
“integer” “integer”
“enum” “factor”
“object” “list”
“array” “vector” or “data.frame”

JSON schema with ellmer

  • In R, you can write the schema as a list (it will convert to JSON object for you).
  • The list has to have a particular structure.
  • In the top level, you need to create the list using type_object().
  • In the schema, you’ll need to specify:
    • the names of the elements,
    • their types (e.g. type_number for a numerical output),
    • whether its’ strictly required or not, and
    • (optionally) the descriptions of the elements.

Extracting structured output with ellmer

schema <- type_object(name = type_string("Customer name"),
                      category = type_enum("Complaint category",
                                           values = c("product failure", "other")),
                      date = type_string("Date of the issue"),
                      product = type_string("Product name"))

chat <- chat_openai(model = "gpt-4.1")
chat$chat_structured("Hey there, I'm Emi and my apple watch malfunctioned today.", 
                     type = schema)
$name
[1] "Emi"

$category
[1] "product failure"

$date
[1] "2024-06-08"

$product
[1] "Apple Watch"

Exercise 5

Go to Exercise 5

Next slide

Back to start