バックグラウンド
慣用語は、次のように、少なくとも2つの単語で構成される名詞句です。
- ブラックオリーブ
- ホットペッパーソース
- ローズフィンアップルポテト
黒とオリーブという別々の単語は、形容詞(黒-JJ)と名詞(オリーブ-NN)です。ただし、人間はブラックオリーブが名詞であることを知っています(これは、たとえばグリーンオリーブとは異なります)。
ここでの問題は、正規化された成分名のリスト(上記のリストなど)を自然言語プロセッサ(NLP)の特定の形式に最も効率的に変換する方法です。
サンプルデータ
テーブルは次のように作成できます。
CREATE TABLE ingredient_name (
id bigserial NOT NULL, -- Uniquely identifies the ingredient.
label character varying(30) NOT NULL
);
次のSQLステートメントは、実際のデータベースレコードを示しています。
insert into ingredient_name (label) values ('alfalfa sprout');
insert into ingredient_name (label) values ('almond extract');
insert into ingredient_name (label) values ('concentrated apple juice');
insert into ingredient_name (label) values ('black-eyed pea');
insert into ingredient_name (label) values ('rose finn apple potato');
データ形式
一般的な形式は次のとおりです。
lexeme1_lexeme2_<lexemeN> lexeme1_lexeme2_lexemeN NN
上記の単語のリストを考えると、NLPは次のことを期待しています。
black_<olive> black_olive NN
hot_pepper_<sauce> hot_pepper_sauce NN
rose_finn_apple_<potato> rose_finn_apple_potato NN
データベースには、テーブル(recipe.ingredient_name
)と列(label
)があります。ラベルは正規化されています(たとえば、単一スペース、小文字)。
SQLステートメント
期待される結果を生成するコード:
CREATE OR REPLACE VIEW ingredient_locutions_vw AS
SELECT
t.id,
-- Replace spaces with underscores
translate( t.prefix, ' ', '_' )
|| '<' || t.suffix || '>' || ' ' ||
translate( t.label, ' ', '_' )
|| ' NN' AS locution_nlp
FROM (
SELECT
id,
-- Ingredient name
label,
-- All words except the last word
left( label, abs( strpos( reverse( label ), ' ' ) - length( label ) ) + 1 ) AS prefix,
-- Just the last word
substr( label,
length( label ) - strpos( reverse( label ), ' ' ) + 2
) AS suffix
FROM
ingredient_name
WHERE
-- Limit set to ingredient names having at least one space
strpos( label, ' ' ) > 0
) AS t;
質問
prefix
上記のコードの(最初の単語を除くすべての単語)とsuffix
(最後の単語だけ)を分割するためのより効率的な(またはエレガントな)方法は何ですか?
システムはPostgreSQL9.1です。
ありがとうございました!