JS에서 컨텐츠 기반 권장 엔진 구축
나는 Python이 이 임무를 완성하는 더 좋은 언어 선택일 수 있다는 것을 깨달았지만, 나는 자바스크립트에 대해 매우 익숙해서 내가 완전히 익숙하지 않은 언어로 엔진을 조립하는 추가 부담을 지고 싶지 않다.
위키백과에 따르면 내용 기반 추천 엔진은 다음과 같다.
“Recommender systems or recommendation systems (sometimes replacing “system” with a synonym such as a platform or engine) are a subclass of information filtering system that seeks to predict the ‘rating’ or ‘preference’ that user would give to an item.”
추천 엔진은 주동적인 필터 시스템으로 사용자가 알고 있는 정보에 따라 사용자에게 제공하는 정보를 개성화시킨다.이 정보는 Google Vision에서 처음 선택한 이미지와 반환된 데이터입니다.
가장 좋은 것은 본고가 끝날 때, 우리는 사용자의 초기 이미지 선택에 따라 사용자에게 더 많은 이미지를 추천할 수 있을 것이다.
이해득실
우리가 토론하기 전에우리 원인을 이야기합시다.이런 종류의 엔진이 이렇게 환영받는 데는 이유가 있지만, 그것을 사용하지 않을 이유도 있다.
찬성 의견
속이다
내용 기반 추천 엔진이 어떻게 작동하는지
내용 기반 추천 엔진은 사용자가 제공한 데이터를 처리합니다. (이 예에서 그림을 선택하십시오.)이러한 데이터를 바탕으로 우리는 사용자에게 건의를 제기할 수 있다.
우리의 예에서 우리의 스크립트는 다음과 같은 절차를 통해 진행될 것이다.
용어 빈도(TF) 및 역문서 빈도(IDF) 개념은 용어의 상대적 중요성을 결정하는 데 사용됩니다.이렇게 하면 우리는 여현의 유사성 개념을 이용하여 무엇을 추천할지 확정할 수 있다.우리는 전체 문장에서 이 문제들을 토론할 것이다.
TF는 문서에 단어가 나타나는 빈도일 뿐입니다.IDF는 전체 문서 라이브러리에서 용어의 빈도수입니다.그것은 한 단어의 희귀성을 의미하며, 희귀어의 점수를 높이는 데 도움이 된다.TD-IDF를 사용하는 이유는 고립된 항목뿐만 아니라 전체 문서 자료 라이브러리의 용어도 고려하기 때문이다.이 모델은 문서에서 단어의 중요성(국부적 중요성)과 전체 자료 라이브러리에서의 단어의 중요성(전체적 중요성)을 결합시켰다
여현 유사성은 문서의 유사성을 확정하는 데 쓰이는 도량으로 크기와 무관하다.수학적으로 말하자면, 그것은 두 벡터 사이의 여현각을 측정하는 것이다.컨텍스트에서 벡터는 키 및 TF-IDF를 값으로 포함하는 객체입니다.이 값은 벡터의 폭값이라고도 부른다.
1. 교육
훈련 엔진의 첫 번째 단계는 데이터를 사용할 수 있고 관리하기 쉬운 구조로 포맷하는 것이다.Google Cloud Vision에서 반환된 레이블 데이터는 다음과 같습니다.
{
"1.jpg": [
{
"locations": [],
"properties": [],
"mid": "/m/0c9ph5",
"locale": "",
"description": "Flower",
"score": 0.9955990314483643,
"confidence": 0,
"topicality": 0.9955990314483643,
"boundingPoly": null
},
{
"locations": [],
"properties": [],
"mid": "/m/04sjm",
"locale": "",
"description": "Flowering plant",
"score": 0.9854584336280823,
"confidence": 0,
"topicality": 0.9854584336280823,
"boundingPoly": null
},
[...]
]
}
1.a 형식
이 연습에서 우리는 대상의 최고급 키(
1.jpg
와 그룹의 각 대상description
만 주목한다.그러나 우리는 모든 설명이 하나의 문자열에 있기를 바란다.이것은 우리로 하여금 앞으로 그것들을 더욱 쉽게 처리하게 할 것이다.우리는 데이터가 다음과 같은 개체 그룹에 있기를 바란다.
const formattedData = [
{
id: '1.jpg',
content: 'flower flowering plant plant petal geraniaceae melastome family geranium wildflower geraniales perennial plant'
}
]
데이터를 포맷하기 위해서 우리는 다음 함수를 통해 그것을 실행할 것이다.이것은 우리가 엔진을 계속 훈련하는 데 필요한 모든 데이터 그룹을 되돌려 줄 것이다.우리는 교체를 더욱 쉽게 하기 위해 Object.entries
를 사용한다.DN 선언:The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs...
그리고 우리는 bt
Object.entries
가 만든 그룹을 순환하여 필요한 속성을 추출하고 desc
그룹에 추가합니다.마지막으로, 우리는 desc
그룹의 내용을 연결하고 content
속성에 기록합니다.이 formatted
수조는 우리의 어료 라이브러리다.const formatData = data => {
let formatted = [];
for (const [key, labels] of Object.entries(data)) {
let tmpObj = {};
const desc = labels.map(l => {
return l.description.toLowerCase();
});
tmpObj = {
id: key,
content: desc.join(" ")
};
formatted.push(tmpObj);
}
return formatted;
};
1.b TF-IDF 및 벡터
위에서 설명한 바와 같이 TF는 단지 하나의 용어가 문서에 나타난 횟수일 뿐이다.
예:
// In the data set below the TF of plant is 3
{
id: '1.jpg',
content: 'flower flowering plant plant petal geraniaceae melastome family geranium wildflower geraniales perennial plant'
}
IDF의 계산은 좀 복잡합니다.공식:javascript에서는 다음과 같은 방식으로 이루어집니다.
var idf = Math.log((this.documents.length) / docsWithTerm );
위의 값(TF 및 IDF)만 있으면 TF-IDF를 계산할 수 있습니다.그것은 단지 TF 곱하기 IDF일 뿐이다.const tdidf = tf * idf;
다음 단계에서는 문서의 TF-IDF를 계산하고 키의 항목과 TF-IDF의 값(벡터)을 포함하는 벡터를 만듭니다.우리는 natural
과vector-object
npm 패키지에 의존하여 이 점을 쉽게 실현할 수 있다.tfidf.addDocument
는 우리의 재산을 표시할 것이다.content
메서드는 TD, IDF 및 TD-IDF를 포함하는 객체 배열을 반환하는 새로운 처리 문서를 나열합니다.하지만 우리는 TF-IDF에만 관심을 갖는다./**
* Generates the TF-IDF of each term in the document
* Create a Vector with the term as the key and the TF-IDF as the value
* @example - example vector
* {
* flowers: 1.2345
* }
*/
const createVectorsFromDocs = processedDocs => {
const tfidf = new TfIdf();
processedDocs.forEach(processedDocument => {
tfidf.addDocument(processedDocument.content);
});
const documentVectors = [];
for (let i = 0; i < processedDocs.length; i += 1) {
const processedDocument = processedDocs[i];
const obj = {};
const items = tfidf.listTerms(i);
for (let j = 0; j < items.length; j += 1) {
const item = items[j];
obj[item.term] = item.tfidf;
}
const documentVector = {
id: processedDocument.id,
vector: new Vector(obj)
};
documentVectors.push(documentVector);
}
현재 이미지의 id tfidf.listTerms
를 id와 벡터로 포함하는 대상 그룹이 있습니다.우리의 다음 단계는 문서 간의 유사성을 계산하는 것이다.1.c 여현 유사도와 점적 계산 유사도 사용
교육 단계의 마지막 단계는 파일 간의 유사성을 계산하는 것이다.우리는 다시
1.jpg
가방을 사용하여 여현의 유사성을 계산한다.계산이 끝난 후, 우리는 그것을 하나의 그룹에 넣습니다. 이 그룹은 이미지 id와 훈련에서 추천한 모든 이미지를 포함합니다.마지막으로, 우리는 그것들을 정렬하여, 가장 높은 여현의 유사성을 가진 항목이 수조에서 첫 번째로 위치하도록 한다./**
* Calculates the similarities between 2 vectors
* getCosineSimilarity creates the dotproduct and the
* length of the 2 vectors to calculate the cosine
* similarity
*/
const calcSimilarities = docVectors => {
// number of results that you want to return.
const MAX_SIMILAR = 20;
// min cosine similarity score that should be returned.
const MIN_SCORE = 0.2;
const data = {};
for (let i = 0; i < docVectors.length; i += 1) {
const documentVector = docVectors[i];
const { id } = documentVector;
data[id] = [];
}
for (let i = 0; i < docVectors.length; i += 1) {
for (let j = 0; j < i; j += 1) {
const idi = docVectors[i].id;
const vi = docVectors[i].vector;
const idj = docVectors[j].id;
const vj = docVectors[j].vector;
const similarity = vi.getCosineSimilarity(vj);
if (similarity > MIN_SCORE) {
data[idi].push({ id: idj, score: similarity });
data[idj].push({ id: idi, score: similarity });
}
}
}
// finally sort the similar documents by descending order
Object.keys(data).forEach(id => {
data[id].sort((a, b) => b.score - a.score);
if (data[id].length > MAX_SIMILAR) {
data[id] = data[id].slice(0, MAX_SIMILAR);
}
});
return data;
무대 뒤에서 vector-object
방법은 많은 일을 할 수 있다.이것은 두 개의 벡터를 취하고 단일 (표량) 수를 되돌려주는 점적을 생성합니다.그것은 두 벡터 중 각 분량을 더하는 간단한 곱셈입니다.
a = [1.7836, 3]
b = [4, 0.5945]
a.b = 1.7836 * 4 + 3 *0.5945 = 8.9176
점적을 계산한 후, 우리는 모든 문서의 벡터 값을 표량 값으로 줄일 수 있을 뿐이다.이것은 모든 값의 제곱근을 자신에게 곱하여 실현한 것이다.다음 getCosineSimilarity
방법은 이 계산을 진행하고 있습니다.const getLength = () => {
let l = 0;
this.getComponents().forEach(k => {
l += this.vector[k] * this.vector[k];
});
return Math.sqrt(l);
}
실제 여현 유사성 공식은 다음과 같습니다.javascript에서는 다음과 같습니다.
const getCosineSimilarity = (vector) => {
return this.getDotProduct(vector) / (this.getLength() * vector.getLength());
}
교육 완료!!2. 우리의 건의를 얻는다
현재 우리는 이미 훈련 단계를 마쳤기 때문에 우리는 간단하게 훈련 데이터에서 추천하는 이미지를 요청할 수 있다.
const getSimilarDocuments = (id, trainedData) => {
let similarDocuments = trainedData[id];
if (similarDocuments === undefined) {
return [];
}
return similarDocuments;
};
이것은 추천 이미지와 여현의 유사성 점수를 포함하는 대상 그룹을 되돌려줍니다.// e.g
[ { id: '14.jpg', score: 0.341705472305971 },
{ id: '9.jpg', score: 0.3092133517794513 },
{ id: '1.jpg', score: 0.3075994367748345 } ]
총결산
나는 네가 따라갈 수 있기를 바란다.나는 이 연습에서 많은 것을 배웠는데, 그것은 확실히 내가 기계 학습에 대한 흥미를 불러일으켰다.
Reference
이 문제에 관하여(JS에서 컨텐츠 기반 권장 엔진 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jimatjibba/build-a-content-based-recommendation-engine-in-js-2lpi텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)