Scikit-LLM:在scikit-learn框架内使用LLM模型强化Python文本分析

手把手教程,Python库

使用高级语言模型如ChatGPT进行文本分类,如情感分析、文本摘要和其他文本分析任务

Photo by Patrick Tomasso on Unsplash

介绍

Scikit-LLM是一个Python包,它将OpenAI的GPT-3等大型语言模型(LLM)集成到scikit-learn框架中,用于文本分析任务。

Scikit-LLM旨在在scikit-learn框架内工作。因此,如果您熟悉scikit-learn,您将感觉在scikit-llm中像在家一样。该库提供了一系列功能,其中包括以下内容:

  • 零-shot文本分类
  • 多标签零-shot文本分类
  • 文本向量化
  • 文本翻译
  • 文本摘要
Concepts covered in this post (Image by Author)

请注意,本文所使用的所有数据集均由作者独家创建和编译。

为什么要使用这个库?

这个库的主要好处是它熟悉的scikit-learn API,特别是:

  • 您可以使用类似于scikit-learn的API,如 .fit() .fit_transform() .predict()
  • 您可以在Sklearn管道中组合scikit-llm库中的估算器(请查看本文中的最后一个示例)。

安装

您可以通过pip安装该库:

pip install scikit-llm

配置

在开始使用Scikit-LLM之前,您需要将您的OpenAI API密钥传递给Scikit-LLM。您可以查看本文以设置您的OpenAI API密钥。

from skllm.config import SKLLMConfigOPENAI_SECRET_KEY = "sk-***"OPENAI_ORG_ID = "org-***"SKLLMConfig.set_openai_key(OPENAI_SECRET_KEY)SKLLMConfig.set_openai_org(OPENAI_ORG_ID)

请注意,Scikit-LLM提供了一个方便的接口来访问OpenAI的GPT-3模型。使用这些模型是不免费的,并需要一个API密钥。虽然API成本相对较低,但根据数据量和调用频率的不同,这些成本可能会增加。因此,重要的是要仔细计划和管理您的使用,以控制成本。在开始使用Scikit-LLM之前,请始终记住查看OpenAI的定价详细信息和使用条款。

为了给您一个大致的想法,我运行了至少五次这个笔记本电脑来制作本教程,总成本为0.02美元。我必须说,我以为这个费用会更高!

零-shot文本分类

Scikit-LLM的一个特点是能够执行零-shot文本分类。Scikit-LLM提供了两个类,用于此目的:

  • ZeroShotGPTClassifier:用于单标签分类(例如情感分析),
  • MultiLabelZeroShotGPTClassifier:用于多标签分类任务。

单标签ZeroShotGPTClassifier

让我们对一些电影评论进行情感分析。为了训练,我们定义了每个评论的情感(由变量movie_review_labels定义)。我们使用这些评论和标签训练模型,以便我们可以使用训练过的模型预测新的电影评论。

电影评论的示例数据集如下:

movie_reviews = [    "这部电影绝对太棒了。情节引人入胜,角色非常真实。",    "我真的很喜欢这部电影!情节有一些意外的转折,让我一直被吸引到最后。",    "这部电影还好。不是很棒,但也不是很糟糕。一次还不错的观影体验。",    "我并不是很喜欢这部电影。情节相当可预测,角色缺乏深度。",    "这部电影不太合我的口味。感觉太慢了,情节也不够吸引人。",    "这部电影还行。既不令人印象深刻,也不令人失望。还可以。",    "这部电影让我惊叹不已!摄影非常出色,表演也是一流的。",    "我一点也不喜欢这部电影。故事不吸引人,演技也就勉强及格。",    "这部电影还算不错。它有它的时刻,但并不总是令人感到吸引。"]movie_review_labels = [    "积极",     "积极",     "中性",     "消极",     "消极",     "中性",     "积极",     "消极",     "中性"]new_movie_reviews = [    # 一条积极的评论    "这部电影太棒了!我从头到尾都被情节吸引住了。",    # 一条消极的评论    "我觉得这部电影相当无聊。情节太慢,演技也不怎么样。",    # 一条中性的评论    "这部电影还行。不是我看过的最好的,但绝对不是最差的。"]

让我们训练模型,然后检查模型对每个新评论的预测。

from skllm import ZeroShotGPTClassifier# 使用OpenAI模型初始化分类器clf = ZeroShotGPTClassifier(openai_model="gpt-3.5-turbo")# 训练模型 clf.fit(X=movie_reviews, y=movie_review_labels)  # 使用训练好的分类器预测每条新评论的情感predicted_movie_review_labels = clf.predict(X=new_movie_reviews)  for review, sentiment in zip(new_movie_reviews, predicted_movie_review_labels):    print(f"评论: {review}\n预测的情感: {sentiment}\n\n")

评论: 这部电影太棒了!我从头到尾都被情节吸引住了。预测的情感: 积极评论: 我觉得这部电影相当无聊。情节太慢,演技也不怎么样。预测的情感: 消极评论: 这部电影还行。不是我看过的最好的,但绝对不是最差的。预测的情感: 中性

如上所示,该模型正确预测了每个电影评论的情感。

多标签ZeroShotGPTClassifier

在前面的部分中,我们使用了单标签分类器([“积极”,“消极”,“中性”])。这里,我们将使用MultiLabelZeroShotGPTClassifier评估器为餐厅评论列表分配多个标签。

restaurant_reviews = [    "这里的食物美味,服务也很好。用餐体验很棒!",    "这家餐厅地理位置很好,但食物只能算是一般般。",    "服务非常慢,食物送到时已经凉了。不是一个好的体验。",    "这家餐厅的环境很美,食物也很棒。",    "食物很好,但我觉得有点贵了。",    "这家餐厅位置很方便,但服务很差。",    "食物与预期不符,但餐厅的环境真的很好。",    "美食和快速服务。位置也非常方便。",    "价格有点高,但食品质量和服务都很好。",    "这家餐厅提供了各种各样的菜肴。服务也非常快。"]restaurant_review_labels = [    ["食品", "服务"],    ["位置", "食品"],    ["服务", "食品"],    ["氛围", "食品"],    ["食品", "价格"],    ["位置", "服务"],    ["食品", "氛围"],    ["食品", "服务", "位置"],    ["价格", "食品", "服务"],    ["食品品种", "服务"]]new_restaurant_reviews = [    "食物非常好,这家餐厅位于城市的中心地带。",    "服务很慢,食物不值得这个价格。",    "这家餐厅的环境很好,但菜品种类有限。"]

我们来训练模型,然后预测新评论的标签。

from skllm import MultiLabelZeroShotGPTClassifier# 使用OpenAI模型初始化分类器clf = MultiLabelZeroShotGPTClassifier(max_labels=3)# 训练模型clf.fit(X=restaurant_reviews, y=restaurant_review_labels)# 使用训练好的分类器预测新评论的标签predicted_restaurant_review_labels = clf.predict(X=new_restaurant_reviews)for review, labels in zip(new_restaurant_reviews, predicted_restaurant_review_labels):    print(f"评论:{review}\n预测标签:{labels}\n\n")

评论:这个餐厅的食物非常好,而且位于市中心。预测标签:['食物','位置']评论:服务很慢,食物不值得这个价格。预测标签:['服务','价格']评论:这家餐厅的氛围非常好,但菜品种类有限。预测标签:['氛围','食品种类']

每条评论的预测标签都很准确。

文本向量化

Scikit-LLM提供了GPTVectorizer类,用于将输入文本转换为固定维度的向量表示。每个向量都是由浮点数数组组成的,是对应句子的表示。

让我们获取以下句子的向量表示。

from skllm.preprocessing import GPTVectorizerX = [    "AI可以革命性地改变行业。",    "机器人创造自动化解决方案。",    "物联网连接设备进行数据交换。"]vectorizer = GPTVectorizer()vectors = vectorizer.fit_transform(X)print(vectors)

[[-0.00818074 -0.02555227 -0.00994665 ... -0.00266894 -0.02135153   0.00325925] [-0.00944166 -0.00884305 -0.01260475 ... -0.00351341 -0.01211498  -0.00738735] [-0.01084771 -0.00133671  0.01582962 ...  0.01247486 -0.00829649  -0.01012453]]

在实践中,这些向量是其他机器学习模型的输入,用于分类、聚类或回归等任务,而不是直接检查向量。

文本翻译

GPT模型可以通过从一种语言准确地读取另一种语言来进行翻译。我们可以使用GPTTranslator模块将文本翻译为感兴趣的语言。

from skllm.preprocessing import GPTTranslatorfrom skllm.datasets import get_translation_datasettranslator = GPTTranslator(openai_model="gpt-3.5-turbo", output_language="English")text_to_translate = ["Je suis content que vous lisiez ce post."]# "我很高兴您正在阅读这篇文章。"translated_text = translator.fit_transform(text_to_translate)print(    f"法语文本:\n{text_to_translate[0]}\n\n翻译后的英文文本:{translated_text[0]}")

法语文本:Je suis content que vous lisiez ce post.翻译后的英文文本:I am glad that you are reading this post.

文本摘要

GPT模型非常适用于文本摘要。Scikit-LLM库提供了GPTSummarizer估算器用于文本摘要。让我们通过摘要下面的长评测来看一下。

reviews = [    (        "昨晚我在The Gourmet Kitchen用餐,感觉非常棒。 "         "服务无可挑剔,食物精致,氛围令人愉悦。 "        "我点了海鲜意大利面,煮得非常完美。 "        "葡萄酒列表也相当不错。 "        "我强烈推荐这家餐厅给任何寻找精致用餐体验的人。"    ),    (        "我今天中午去The Burger Spot吃午餐,感到惊喜。 "        "尽管是快餐店,但食物的质量非常好。 "        "我点了经典的奶酪汉堡,汉堡肉汁多味美。 "        "薯条酥脆美味。 "        "服务快捷,员工友好。 "        "这是一个快速满足的好地方。"    ),    (        "The Coffee Corner是我最喜欢的工作和享受一杯好咖啡的地方。 "        "氛围轻松,咖啡总是顶级的。 "        "他们还提供各种糕点和三明治。 "        "员工总是热情,服务快捷。 "        "我喜欢他们的拿铁,蓝莓松饼是必试之选。"    )]# 注意# string1 = "ABC"# string2 = ("A" "B" "C")# print(string1 == string2)# >>> True

请注意,上面的 reviews 是一个三个元素的列表,并且列表中的每个元素都以易于阅读的方式写出。

from skllm.preprocessing import GPTSummarizergpt_summarizer = GPTSummarizer(openai_model = "gpt-3.5-turbo", max_words = 15)summaries = gpt_summarizer.fit_transform(reviews)print(summaries)

生成每个评论的简短总结。 max_words 参数设置了摘要长度的大致上限;实际上,可能会更长一些。

在 scikit-learn 管道中使用 scikit-llm

到目前为止,以上所有例子都只使用了 Scikit-LLM 库中的估计器。如前所述,这个库的主要优点是它与 scikit-learn 平台的集成。以下示例使用 scikit-llm 估计器在 scikit-learn 管道中,并在先前说明的电影评论示例上运行 XGBoost 分类器。

from sklearn.pipeline import Pipelinefrom sklearn.preprocessing import LabelEncoderfrom skllm.preprocessing import GPTVectorizerfrom xgboost import XGBClassifier# 定义名称规范的变量以减少混淆X,y = movie_reviews, movie_review_labelsX_test, y_test = new_movie_reviews, new_movie_review_labels# 编码标签le = LabelEncoder()y_encoded = le.fit_transform(y)y_test_encoded = le.transform(y_test)# 在 scikit-learn 管道中使用 steps = [("GPT", GPTVectorizer()), ("Clf", XGBClassifier())]clf = Pipeline(steps)clf.fit(X, y_encoded)y_pred_encoded = clf.predict(X_test)# 将编码的标签恢复为实际标签 y_pred = le.inverse_transform(y_pred_encoded)print(f"\nEncoded labels (train set): {y_encoded}\n")print(f"Actual Labels (train set): {y}")print(f"Predicted labels (encoded): {y_test_encoded}\n")print("------------------\nEvaluate the performance of XGBoost Classifier:\n")for test_review, actual_label, predicted_label in zip(X_test, y_test, y_pred):    print(f"Review: {test_review}\nActual Label: {actual_label}\nPredicted Label: {predicted_label}\n")

Encoded labels (train set): [2 2 1 0 0 1 2 0 1]Actual Labels (train set): ['positive', 'positive', 'neutral', 'negative', 'negative', 'neutral', 'positive', 'negative', 'neutral']Predicted labels (encoded): [2 0 1]------------------Evaluate the performance of XGBoost Classifier:Review:The movie was fantastic! I was captivated by the storyline from beginning to end.Actual Label: positivePredicted Label: positiveReview:I found the film to be quite boring. The plot moved too slowly and the acting was subpar.Actual Label: negativePredicted Label: positiveReview:The movie was okay. Not the best I've seen, but certainly not the worst.Actual Label: neutralPredicted Label: neutral

请注意,上述仅是一个用例,旨在说明在 SKlearn 管道中集成 Scikit-LLM 估计器的可能性。

如果您喜欢本文,您可能会喜欢我在 NLP 任务中的字符串到字符串算法相关文章。

用 string2string 征服文本:一种强大的字符串到字符串算法的 Python 库

利用 string2string 进行自然语言处理任务

towardsdatascience.com

结论

Scikit-LLM 是一个强大的工具,它将高级语言模型(如 GPT-3)的功能添加到众所周知的 scikit-learn 框架中。在本教程中,我们看了一些 Scikit-LLM 的最重要的特性:1)零-shot 文本分类,2)多标签零-shot 文本分类,3)文本向量化,4)文本摘要,5)语言翻译和 6)与 scikit-learn 管道的集成。

如前所述,这个库的主要优点是它与 scikit-learn 的类似 API 和其集成到 scikit-learn 管道中。但是,Scikit-LLM 的主要限制是它对 OpenAI 的重度依赖。虽然将开源模型集成到 Scikit-LLM 的路线图上,但它尚未在库中提供。因此,如果您使用 Scikit-LLM,则应知道:

  • 由于Scikit-LLM使用OpenAI模型,因此对于发往OpenAI的请求,存在API成本或速率限制。
  • Scikit-LLM的限制与OpenAI API相同,例如无法访问互联网或给定OpenAI模型的最大标记数量(在本文中,主要使用“gpt-3-turbo”模型,其最大标记数量为4096)。

Scikit-LLM是一款有前途的工具,它利用大型语言模型开启了文本分析领域的新可能性。该库可能是您工具箱的有用补充;因此,我建议您尝试一下。

📓 您可以在GitHub上找到本文的笔记本。

感谢您的阅读!

我是一位高级数据科学家和工程师,我想写有关统计学、机器学习、时间序列分析、有趣的Python库以及技巧和窍门的文章。

  • 如果您喜欢这篇文章,请在小猪AI上关注我
  • 订阅我的邮件列表
  • 让我们在LinkedIn和Twitter上建立联系

📖 阅读Esmaeil Alizadeh(以及小猪AI上成千上万的其他作家的)每个故事。订阅小猪AI以获取完整版…

小猪AI.ealizadeh.com

参考资料

GitHub – iryna-kondr/scikit-llm: 无缝集成ChatGPT等强大的语言模型到scikit-learn中以增强文本分析任务。…

无缝集成ChatGPT等强大的语言模型到scikit-learn中以增强文本分析任务。您可以…

github.com

scikit-learn

“我们使用scikit-learn支持最先进的基础研究[…]”“我认为这是我见过的最好设计的ML包。”

scikit-learn.org

如何获取OpenAI API密钥

许多应用程序和AI工具现在需要您自己携带OpenAI API密钥。您可以在OpenAI的…上生成一个。

www.howtogeek.com

最初发表于https://ealizadeh.com。