UNPKG

ts-content-based-recommender

Version:

A TypeScript-based content-based recommender with multilingual support (Japanese & English). Forked from content-based-recommender.

127 lines 4.85 kB
import * as sw from 'stopword'; /** * 英語専用トークンフィルタークラス * ストップワード除去、重複除去、長さフィルタリング、N-gram対応等を行います */ export class EnglishTokenFilter { /** * コンストラクタ * @param options フィルターオプション */ constructor(options = {}) { this.options = { removeDuplicates: options.removeDuplicates ?? true, removeStopwords: options.removeStopwords ?? true, customStopWords: options.customStopWords ?? [], minTokenLength: options.minTokenLength ?? 1, allowedPos: options.allowedPos ?? ['名詞', '動詞', '形容詞'] // 日本語用なので英語では使用しない }; } /** * トークン配列をフィルタリングする * @param tokens フィルタリング対象のトークン配列 * @returns フィルタリング済みトークン配列 */ filter(tokens) { let filteredTokens = tokens; // 長さフィルタリング if (this.options.minTokenLength > 1) { filteredTokens = this._filterByLength(filteredTokens); } // ストップワード除去 if (this.options.removeStopwords) { filteredTokens = this._removeStopwords(filteredTokens); } // 重複除去 if (this.options.removeDuplicates) { filteredTokens = this._removeDuplicates(filteredTokens); } return filteredTokens; } /** * N-gram対応フィルタリング(英語用) * ストップワードを含むN-gramを除去します * @param tokens トークン配列 * @returns フィルタリング済みトークン配列 */ filterWithNgrams(tokens) { let filteredTokens = tokens; // 長さフィルタリング if (this.options.minTokenLength > 1) { filteredTokens = this._filterByLength(filteredTokens); } // N-gramのストップワードフィルタリング if (this.options.removeStopwords) { filteredTokens = this._filterNgramsWithStopwords(filteredTokens); } // 重複除去 if (this.options.removeDuplicates) { filteredTokens = this._removeDuplicates(filteredTokens); } return filteredTokens; } /** * 長さによるフィルタリング * @param tokens トークン配列 * @returns フィルタリング済みトークン配列 */ _filterByLength(tokens) { return tokens.filter(token => token.length >= this.options.minTokenLength); } /** * ストップワード除去(英語用) * @param tokens トークン配列 * @returns ストップワード除去済みトークン配列 */ _removeStopwords(tokens) { // stopwordライブラリを使用した後、カスタムストップワードも除去 let filteredTokens = sw.removeStopwords(tokens); if (this.options.customStopWords.length > 0) { const customStopWords = new Set([ ...EnglishTokenFilter.DEFAULT_STOPWORDS, ...this.options.customStopWords ]); filteredTokens = filteredTokens.filter(token => !customStopWords.has(token)); } return filteredTokens; } /** * N-gramのストップワードフィルタリング(英語用) * @param tokens トークン配列 * @returns フィルタリング済みトークン配列 */ _filterNgramsWithStopwords(tokens) { const filteredTokens = []; for (const token of tokens) { if (token.includes('_')) { // N-gramの場合、ストップワードを含むかチェック const tokenParts = token.split('_'); if (tokenParts.length === sw.removeStopwords(tokenParts).length) { filteredTokens.push(token); } } else { // ユニグラムの場合、通常のストップワード除去 const removed = sw.removeStopwords([token]); if (removed.length > 0) { filteredTokens.push(token); } } } return filteredTokens; } /** * 重複除去 * @param tokens トークン配列 * @returns 重複除去済みトークン配列 */ _removeDuplicates(tokens) { return Array.from(new Set(tokens)); } } /** 英語デフォルトストップワード */ EnglishTokenFilter.DEFAULT_STOPWORDS = [ 'the', 'is', 'at', 'which', 'on', 'a', 'an', 'and', 'or', 'but', 'in', 'with', 'to', 'for', 'of', 'as', 'by' ]; //# sourceMappingURL=EnglishTokenFilter.js.map