n8n-nodes-openai-analytics
Version:
n8n node for OpenAI Analytics
89 lines • 3.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.classifyText = void 0;
// 코사인 유사도 계산 함수
function cosineSimilarity(vecA, vecB) {
if (vecA.length !== vecB.length) {
throw new Error('벡터 길이가 일치하지 않습니다');
}
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < vecA.length; i++) {
dotProduct += vecA[i] * vecB[i];
normA += vecA[i] * vecA[i];
normB += vecB[i] * vecB[i];
}
if (normA === 0 || normB === 0) {
return 0;
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
async function classifyText(context) {
const { openai, functionThis, i } = context;
// 대상 텍스트 가져오기
const targetText = functionThis.getNodeParameter('targetText', i);
// 카테고리 목록 가져오기
const categories = functionThis.getNodeParameter('categories', i);
// 임베딩 모델 가져오기
const embeddingModel = functionThis.getNodeParameter('embeddingModel', i);
// 임계값 가져오기 (옵션)
const threshold = functionThis.getNodeParameter('threshold', i) || 0.7;
// 분류 방식 (단일/다중) 가져오기
const classificationType = functionThis.getNodeParameter('classificationType', i);
// 대상 텍스트 임베딩 생성
const targetEmbeddingResponse = await openai.embeddings.create({
model: embeddingModel,
input: targetText,
});
const targetEmbedding = targetEmbeddingResponse.data[0].embedding;
// 카테고리 텍스트 임베딩 생성
const categoryEmbeddingResponse = await openai.embeddings.create({
model: embeddingModel,
input: categories,
});
const categoryEmbeddings = categoryEmbeddingResponse.data.map(item => ({
category: categories[item.index],
embedding: item.embedding,
}));
// 유사도 계산 및 분류
const similarities = categoryEmbeddings.map(category => ({
category: category.category,
similarity: cosineSimilarity(targetEmbedding, category.embedding),
}));
// 유사도에 따라 정렬
similarities.sort((a, b) => b.similarity - a.similarity);
let results;
if (classificationType === 'single') {
// 단일 분류일 경우 가장 유사한 카테고리만 반환
const bestMatch = similarities[0];
// 임계값보다 낮으면 미분류로 처리
results = {
category: bestMatch.similarity >= threshold ? bestMatch.category : 'unclassified',
similarity: bestMatch.similarity,
classifications: similarities,
text: targetText,
threshold
};
}
else {
// 다중 분류일 경우 임계값 이상인 모든 카테고리 반환
const matchedCategories = similarities
.filter(item => item.similarity >= threshold)
.map(item => ({
category: item.category,
similarity: item.similarity,
}));
results = {
categories: matchedCategories,
allClassifications: similarities,
text: targetText,
threshold
};
}
return {
json: results,
};
}
exports.classifyText = classifyText;
//# sourceMappingURL=classifyText.js.map