OpenAI의 임베딩 API는 여러 개의 텍스트 입력을 한 번에 처리할 수 있다. 이 방식은 반복적으로 API를 호출하는 것보다 효율적이며, 결과 정리도 간단하다.
예시 데이터:
articles = [
{"headline": "Economic Growth Continues Amid Global Uncertainty", "topic": "Business"},
{"headline": "Interest rates fall to historic lows", "topic": "Business"},
{"headline": "Scientists Make Breakthrough Discovery in Renewable Energy", "topic": "Science"},
...
]
헤드라인 텍스트만 추출:
headline_text = [article['headline'] for article in articles]
임베딩 요청:
response = client.embeddings.create(
model="text-embedding-3-small",
input=headline_text
)
response_dict = response.model_dump()
결과 임베딩을 기사에 연결:
for i, article in enumerate(articles):
article['embedding'] = response_dict['data'][i]['embedding']
이제 각 기사에 해당하는 임베딩 벡터가 포함되며, 후속 분석이 가능해진다.
각 텍스트에 대한 임베딩은 고정된 길이의 벡터를 반환한다. 예를 들어 text-embedding-3-small
모델은 항상 1536차원의 벡터를 생성한다.
len(articles[0]['embedding']) # 결과: 1536
고차원 벡터는 시각화가 어렵기 때문에, t-SNE 등의 기법을 사용해 2차원으로 축소한다. 축소 과정에서는 일부 정보 손실이 발생하지만, 텍스트 간 의미적 거리를 시각적으로 확인할 수 있다는 장점이 있다.
t-SNE 적용 예시:
from sklearn.manifold import TSNE
import numpy as np
embeddings = [article['embedding'] for article in articles]
tsne = TSNE(n_components=2, perplexity=5)
embeddings_2d = tsne.fit_transform(np.array(embeddings))
시각화 코드:
import matplotlib.pyplot as plt
plt.scatter(embeddings_2d[:, 0], embeddings_2d[:, 1])
topics = [article['topic'] for article in articles]
for i, topic in enumerate(topics):
plt.annotate(topic, (embeddings_2d[i, 0], embeddings_2d[i, 1]))
plt.show()
이 과정을 통해 같은 주제의 기사가 시각적으로 가까이 모여 있는 것을 확인할 수 있다. 이는 임베딩이 의미를 잘 포착하고 있음을 보여준다.