转载

OpenAi 嵌入使用案例

2D 数据可视化
Visualizing_embeddings_in_2D.ipynb

嵌入的大小随基础模型的复杂性而变化。为了可视化这些高维数据,我们使用t-SNE算法将数据转换为二维数据。

我们根据评论者给出的星级评分为个人评论着色:

  • 1星:红色
  • 2星:深橙色
  • 3星:金色
  • 4星:绿松石
  • 5星:深绿色
使用 t-SNE 以语言可视化的亚马逊评级

可视化似乎产生了大约 3 个集群,其中一个集群大多有负面评论。

import pandas as pd
from sklearn.manifold import TSNE import matplotlib.pyplot as plt import matplotlib df = pd.read_csv('output/embedded_1k_reviews.csv') matrix = df.ada_embedding.apply(eval).to_list() # Create a t-SNE model and transform the data tsne = TSNE(n_components=2, perplexity=15, random_state=42, init='random', learning_rate=200) vis_dims = tsne.fit_transform(matrix) colors = ["red", "darkorange", "gold", "turquiose", "darkgreen"] x = [x for x,y in vis_dims] y = [y for x,y in vis_dims] color_indices = df.Score.values - 1 colormap = matplotlib.colors.ListedColormap(colors) plt.scatter(x, y, c=color_indices, cmap=colormap, alpha=0.3) plt.title("Amazon ratings visualized in language using t-SNE")
嵌入为 ML 算法的文本特征编码器
Regression_using_embeddings.ipynb

嵌入可用作机器学习模型中的常规自由文本特征编码器。如果某些相关输入是自由文本,则合并嵌入将提高任何机器学习模型的性能。嵌入还可以用作 ML 模型中的分类特征编码器。如果分类变量的名称有意义且数量众多,例如职务,则这将增加最大价值。对于此任务,相似性嵌入通常比搜索嵌入性能更好。

我们观察到,通常嵌入表示非常丰富且信息密集。例如,使用 SVD 或 PCA 降低输入的维度,即使减少 10%,通常也会导致特定任务的下游性能变差。

此代码将数据拆分为训练集和测试集,它们将用于以下两个用例,即回归和分类。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split( list(df.ada_embedding.values), df.Score, test_size = 0.2, random_state=42 )

使用嵌入特征的回归

嵌入提供了一种预测数值的优雅方法。在此示例中,我们根据评论文本预测评论者的星级。因为嵌入中包含的语义信息很高,所以即使很少有评论,预测也是不错的。

我们假设分数是 1 到 5 之间的连续变量,并允许算法预测任何浮点值。ML 算法将预测值与真实分数的距离最小化,并实现了 0.39 的平均绝对误差,这意味着预测平均偏差不到半颗星。

from sklearn.ensemble import RandomForestRegressor
rfr = RandomForestRegressor(n_estimators=100) rfr.fit(X_train, y_train) preds = rfr.predict(X_test)
使用嵌入特征进行分类
Classification_using_embeddings.ipynb

这一次,我们不是让算法预测 1 到 5 之间的任何值,而是尝试将评论的确切星数分类为 5 个类别,范围从 1 到 5 星。

训练后,模型学会预测 1 星和 5 星评论比更细微的评论(2-4 星)要好得多,这可能是由于更极端的情绪表达。

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, accuracy_score clf = RandomForestClassifier(n_estimators=100) clf.fit(X_train, y_train) preds = clf.predict(X_test)
零镜头分类
Zero-shot_classification_with_embeddings.ipynb

我们可以使用嵌入进行零镜头分类,而无需任何标记的训练数据。对于每个类,我们嵌入类名或类的简短描述。为了以零镜头的方式对一些新文本进行分类,我们将它的嵌入与所有类嵌入进行比较,并预测相似度最高的类。

from openai.embeddings_utils import cosine_similarity, get_embedding
df= df[df.Score!=3] df['sentiment'] = df.Score.replace({1:'negative', 2:'negative', 4:'positive', 5:'positive'}) labels = ['negative', 'positive'] label_embeddings = [get_embedding(label, model=model) for label in labels] def label_score(review_embedding, label_embeddings): return cosine_similarity(review_embedding, label_embeddings[1]) - cosine_similarity(review_embedding, label_embeddings[0]) prediction = 'positive' if label_score('Sample Review', label_embeddings) > 0
获取用户和产品嵌入以进行冷启动建议
User_and_product_embeddings.ipynb

我们可以通过平均用户的所有评论来获得用户嵌入。同样,我们可以通过平均有关该产品的所有评论来获得产品嵌入。为了展示这种方法的有用性,我们使用 50k 条评论的子集来涵盖每个用户和每个产品的更多评论。

我们在单独的测试集上评估这些嵌入的有用性,在该测试集中,我们将用户和产品嵌入的相似性绘制为评级的函数。有趣的是,基于这种方法,甚至在用户收到产品之前,我们就可以比随机更好地预测他们是否喜欢该产品。

按分数分组的箱线图
user_embeddings = df.groupby('UserId').ada_embedding.apply(np.mean)
prod_embeddings = df.groupby('ProductId').ada_embedding.apply(np.mean)
聚类
Clustering.ipynb

聚类是理解大量文本数据的一种方法。嵌入对于此任务很有用,因为它们提供了每个文本的语义上有意义的向量表示。因此,以无监督的方式,聚类将发现我们数据集中的隐藏分组。

在这个例子中,我们发现了四个不同的集群:一个专注于狗粮,一个关注负面评论,两个关注正面评论。

使用 t-SNE 在语言 2d 中可视化识别的集群
import numpy as np
from sklearn.cluster import KMeans matrix = np.vstack(df.ada_embedding.values) n_clusters = 4 kmeans = KMeans(n_clusters = n_clusters, init='k-means++', random_state=42) kmeans.fit(matrix) df['Cluster'] = kmeans.labels_
使用嵌入进行文本搜索
Semantic_text_search_using_embeddings.ipynb

为了检索最相关的文档,我们使用查询的嵌入向量和每个文档之间的余弦相似性,并返回得分最高的文档。

from openai.embeddings_utils import get_embedding, cosine_similarity
def search_reviews(df, product_description, n=3, pprint=True): embedding = get_embedding(product_description, model='text-embedding-ada-002') df['similarities'] = df.ada_embedding.apply(lambda x: cosine_similarity(x, embedding)) res = df.sort_values('similarities', ascending=False).head(n) return res res = search_reviews(df, 'delicious beans', n=3)
使用嵌入进行代码搜索
Semantic_text_search_using_embeddings.ipynb

为了检索最相关的文档,我们使用查询的嵌入向量和每个文档之间的余弦相似性,并返回得分最高的文档。

from openai.embeddings_utils import get_embedding, cosine_similarity
def search_reviews(df, product_description, n=3, pprint=True): embedding = get_embedding(product_description, model='text-embedding-ada-002') df['similarities'] = df.ada_embedding.apply(lambda x: cosine_similarity(x, embedding)) res = df.sort_values('similarities', ascending=False).head(n) return res res = search_reviews(df, 'delicious beans', n=3)
使用嵌入的建议
Recommendation_using_embeddings.ipynb

由于嵌入向量之间的距离越短表示更大的相似性,因此嵌入可用于推荐。

下面,我们说明一个基本的推荐器。它接受字符串列表和一个“源”字符串,计算它们的嵌入,然后返回字符串的排名,从最相似到最不相似排列。作为一个具体示例,下面的链接笔记本将此函数的一个版本应用于 AG 新闻数据集(采样到 2,000 篇新闻文章描述),以将前 5 篇最相似的文章返回到任何给定的源文章。

def recommendations_from_strings(
strings: List[str], index_of_source_string: int, model="text-embedding-ada-002", ) -> List[int]: """Return nearest neighbors of a given string.""" # get embeddings for all strings embeddings = [embedding_from_string(string, model=model) for string in strings] # get the embedding of the source string query_embedding = embeddings[index_of_source_string] # get distances between the source embedding and other embeddings (function from embeddings_utils.py) distances = distances_from_embeddings(query_embedding, embeddings, distance_metric="cosine") # get indices of nearest neighbors (function from embeddings_utils.py) indices_of_nearest_neighbors = indices_of_nearest_neighbors_from_distances(distances) return indices_of_nearest_neighbors