1

バックグラウンド

慣用語は、次のように、少なくとも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です。

ありがとうございました!

4

1 に答える 1

1
CREATE OR REPLACE VIEW ingredient_locutions_vw AS 
SELECT
    t.id,
    format('%s_<%s> %s NN', 
        array_to_string(t.prefix, '_'), 
        t.suffix, 
        array_to_string(t.label, '_')
    ) AS locution_nlp
FROM (
    SELECT
        id,

        -- Ingredient name
        label,

        -- All words except the last word
        label[1:array_length(label, 1) - 1] AS prefix,

        -- Just the last word
        label[array_length(label, 1)] AS suffix
    FROM (
        select id, string_to_array(label, ' ') as label
        from ingredient_name
    ) s
    WHERE
    -- Limit set to ingredient names having at least one space
    array_length(label, 1) > 1
) AS t;

select * from ingredient_locutions_vw ;
 id |                      locution_nlp                      
----+--------------------------------------------------------
  1 | alfalfa_<sprout> alfalfa_sprout NN
  2 | almond_<extract> almond_extract NN
  3 | concentrated_apple_<juice> concentrated_apple_juice NN
  4 | black-eyed_<pea> black-eyed_pea NN
  5 | rose_finn_apple_<potato> rose_finn_apple_potato NN
(5 rows)
于 2012-05-31T18:09:18.960 に答える