📢 转载信息
原文作者:Iván Palomares Carrascosa
在本篇文章中,您将学习如何使用预训练的大型语言模型从文本中提取结构化特征,并将其与数值列相结合以训练监督分类器。
我们将涵盖的主题包括:
- 创建一个包含混合文本和数值字段的玩具数据集用于分类
- 使用Groq托管的LLaMA模型,通过Pydantic模式从票据文本中提取JSON特征
- 在工程化的表格数据集上训练和评估scikit-learn分类器
让我们不要再浪费时间了。
从文本到表格:利用LLMs进行表格数据特征工程
图片来源:Editor
引言
虽然大型语言模型(LLMs)通常用于会话目的,处理与自然语言交互相关的用例,但它们也可以协助处理复杂数据集上的特征工程等任务。具体来说,您可以利用像Groq(例如Llama系列模型)这样的提供商提供的预训练LLMs,来进行数据转换和预处理任务,包括将文本等非结构化数据转化为可用于预测机器学习模型的完全结构化的表格数据。
在本文中,我将引导您完成将结构化文本进行特征工程的完整流程,将其转化为适用于机器学习模型的表格数据 — 即,使用LLM创建的特征训练的分类器。
设置和导入
首先,我们将为这个实践示例进行所有必要的导入:
import pandas as pd
import json
from pydantic import BaseModel, Field
from openai import OpenAI
from google.colab import userdata
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.preprocessing import StandardScaler
请注意,除了常用的机器学习和数据预处理库(如scikit-learn)之外,我们还导入了OpenAI类 — 不是因为我们将直接使用OpenAI模型,而是因为许多LLM API(包括Groq的)都采用了与OpenAI相同的接口风格和规范。因此,这个类可以帮助您通过单一客户端与各种提供商进行交互,并访问广泛的LLMs,包括通过Groq访问的Llama模型,我们稍后将看到这一点。
接下来,我们设置一个Groq客户端,以启用对预训练LLM的访问,该LLM可以在执行期间通过API进行调用以进行推理:
groq_api_key = userdata.get('GROQ_API_KEY')
client = OpenAI(
base_url="https://api.groq.com/openai/v1",
api_key=groq_api_key
)
重要提示:要使上述代码正常工作,您需要为Groq定义一个API密钥。在Google Colab中,您可以通过左侧边栏的“Secrets”图标(该图标看起来像一个钥匙)来完成此操作。在这里,将您的密钥命名为'GROQ_API_KEY',然后在Groq网站上注册以获取实际密钥,并将其粘贴到值字段中。
创建玩具票据数据集
下一步是生成一个合成的、部分随机的玩具数据集以供说明。如果您有自己的文本数据集,可以随时相应地调整代码并使用您自己的数据。
import random
import time
random.seed(42)
categories = ["access", "inquiry", "software", "billing", "hardware"]
templates = {
"access": [
"I've been locked out of my account for {days} days and need urgent help!",
"I can't log in, it keeps saying bad password.",
"Reset my access credentials immediately.",
"My 2FA isn't working, please help me get into my account."
],
"inquiry": [
"When will my new credit card arrive in the mail?",
"Just checking on the status of my recent order.",
"What are your business hours on weekends?",
"Can I upgrade my current plan to the premium tier?"
],
"software": [
"The app keeps crashing every time I try to view my transaction history.",
"Software bug: the submit button is greyed out.",
"Pages are loading incredibly slowly since the last update.",
"I'm getting a 500 Internal Server Error on the dashboard."
],
"billing": [
"I need a refund for the extra charges on my bill.",
"Why was I billed twice this month?",
"Please update my payment method, the old card expired.",
"I didn't authorize this $49.99 transaction."
],
"hardware": [
"My hardware token is broken, I can't log in.",
"The screen on my physical device is cracked.",
"The card reader isn't scanning properly anymore.",
"Battery drains in 10 minutes, I need a replacement unit."
]
}
data = []
for _ in range(100):
cat = random.choice(categories)
# Injecting a random number of days into specific templates to foster variety
text = random.choice(templates[cat]).format(days=random.randint(1, 14))
data.append({
"text": text,
"account_age_days": random.randint(1, 2000),
"prior_tickets": random.choices([0, 1, 2, 3, 4, 5], weights=[40, 30, 15, 10, 3, 2])[0],
"label": cat
})
df = pd.DataFrame(data)
生成的数据集包含客户支持票据,结合了文本描述与结构化数值特征(如账户年龄和历史票据数量),以及跨越多个票据类别的类别标签。这些标签将用于在流程末尾训练和评估分类模型。
提取LLM特征
接下来,我们定义要从文本中提取的所需表格特征。特征的选择取决于领域,并且是完全可自定义的,但稍后您将使用LLM以一致的、结构化的格式提取这些字段:
class TicketFeatures(BaseModel):
urgency_score: int = Field(description="Urgency of the ticket on a scale of 1 to 5")
is_frustrated: int = Field(description="1 if the user expresses frustration, 0 otherwise")
例如,紧急程度和沮丧程度通常与特定的票据类型相关(例如,账户锁定和宕机往往比一般查询更紧急、更情绪化),因此这些信号可以帮助下游分类器比仅使用原始文本更有效地分离类别。
下一个函数是流程的关键组成部分,因为它封装了将票据文本转换为匹配我们模式的JSON对象的LLM集成。
def extract_features(text: str) -> dict:
# Sleep for 2.5 seconds for safer use under the constraints of the 30 RPM free-tier limit
time.sleep(2.5)
schema_instructions = json.dumps(TicketFeatures.model_json_schema())
response = client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=[
{
"role": "system",
"content": f"You are an extraction assistant. Output ONLY valid JSON matching this schema: {schema_instructions}"
},
{"role": "user", "content": text}
],
response_format={"type": "json_object"},
temperature=0.0
)
return json.loads(response.choices[0].message.content)
该函数为什么返回JSON对象?首先,JSON是一种要求LLM生成结构化输出的可靠方式。其次,JSON对象可以轻松地转换为Pandas Series对象,然后可以无缝地与其他列合并到现有的DataFrame中,成为新的列。以下指令可以完成此操作,并将存储在engineered_features中的新特征附加到原始数据集的其余部分:
print("1. Extracting structured features from text using LLM...")
engineered_features = df["text"].apply(extract_features)
features_df = pd.DataFrame(engineered_features.tolist())
X_raw = pd.concat([df.drop(columns=["text", "label"]), features_df], axis=1)
y = df["label"]
print("\n2. Final Engineered Tabular Dataset:")
print(X_raw)
由此产生的表格数据如下所示:
account_age_days prior_tickets urgency_score is_frustrated
0 564 0 5 1
1 1517 3 4 0
2 62 0 5 1
3 408 2 4 0
4 920 1 5 1
.. ... ... ... ...
95 884 0 4 1
96 1737 0 5 1
97 837 0 5 1
98 862 1 4 1
[100 rows x 4 columns]
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区