テキスト分析

このドキュメントでは、GoogleSQL for BigQuery のテキスト分析(テキスト マイニング)の概要について説明します。

GoogleSQL はテキスト分析をサポートしています。テキスト分析は、非構造化テキストで用語(トークン)を識別し、それらの用語をインデックスや検索などの実用的な分析情報に使用したり、ML トレーニング パイプラインで利用するベクトル化の入力として使用したりするための手法です。テキスト アナライザを使用して特定の方法で情報を分析し、テキスト分析オプションを使用して独自の分析カスタマイズを適用することができます。

テキスト分析は、GoogleSQL の次の関数とステートメントでサポートされています。

テキスト アナライザ

GoogleSQL for BigQuery は数種類のテキスト アナライザをサポートしています。テキスト アナライザを使用して、非構造化テキストからデータを抽出できます。analyzer 引数を指定して一部の関数とステートメントにアナライザを渡すことができます。各テキスト アナライザは、独自の方法で情報を抽出します。次の設定を選択できます。

  • NO_OP_ANALYZER: 入力を 1 つの用語(トークン)として抽出します。
  • LOG_ANALYZER: 区切り文字が検出されると入力を分割します。
  • PATTERN_ANALYZER: 入力を、正規表現に一致する用語に分割します。

NO_OP_ANALYZER アナライザ

NO_OP_ANALYZER アナライザは、入力テキストを 1 つの用語(トークン)として抽出する、オペレーション不要のアナライザです。結果として得られる単語には、書式設定は適用されません。

このアナライザは、テキスト アナライザのオプションやトークン フィルタをサポートしていません。

次のクエリは、テキスト アナライザとして NO_OP_ANALYZER を使用します。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'NO_OP_ANALYZER'
) AS results

/*-----------------------------------------------*
 | results                                       |
 +-----------------------------------------------+
 | 'I like pie, you like-pie, they like 2 PIEs.' |
 *-----------------------------------------------*/

LOG_ANALYZER アナライザ

LOG_ANALYZER アナライザは、区切り文字が検出されると入力テキストを用語(トークン)として抽出し、区切り文字を破棄し、結果で大文字をすべて小文字に変更します。

詳細:

  • 用語の大文字は小文字に変換されますが、127 より大きい ASCII 値はそのまま保持されます。
  • スペース、ピリオド、その他の文字以外の要素など、以下の区切り文字のいずれかが検出されると、テキストは個々の用語に分割されます。

    [ ] < > ( ) { } | ! ; , ' " * & ? + / : = @ . - $ % \ _ \n \r \s \t %21 %26
    %2526 %3B %3b %7C %7c %20 %2B %2b %3D %3d %2520 %5D %5d %5B %5b %3A %3a %0A
    %0a %2C %2c %28 %29
    

    これらのデフォルトの区切り文字を使用しない場合は、テキスト アナライザのオプションとして使用する特定の区切り文字を指定できます。詳細については、delimiters オプションをご覧ください。

このアナライザはトークン フィルタをサポートしています。詳細については、token_filters オプションをご覧ください。token_filters オプションが指定されていない場合、デフォルトで ASCII 小文字正規化が使用されます。

次のクエリは、テキスト アナライザとして LOG_ANALYZER を使用します。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'LOG_ANALYZER'
) AS results

/*---------------------------------------------------------------------------*
 | results                                                                   |
 +---------------------------------------------------------------------------+
 | [ 'i', 'like', 'pie', 'you', 'like', 'pie', 'they', 'like', '2', 'pies' ] |
 *---------------------------------------------------------------------------*/

LOG_ANALYZER はデフォルトのテキスト アナライザであるため、クエリで指定する必要はありません。たとえば、次のクエリでは上記のクエリと同じ結果が得られます。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.'
) AS results

PATTERN_ANALYZER アナライザ

PATTERN_ANALYZER アナライザは、re2 正規表現を使用して、非構造化テキストから用語(トークン)を抽出します。

このアナライザは、入力テキストの左側から、正規表現に一致する最初の単語を見つけると、その単語を出力に追加します。次に、新たに見つかった単語までの入力テキスト内の接頭辞を削除します。このプロセスは、入力テキストが空になるまで繰り返されます。

デフォルトでは正規表現 \b\w{2,}\b が使用されます。この正規表現は、2 文字以上の Unicode 以外の単語に一致します。別の正規表現を使用する場合は、patterns オプションをご覧ください。

このアナライザはトークン フィルタをサポートしています。詳細については、token_filters オプションをご覧ください。token_filters オプションが指定されていない場合、デフォルトで ASCII 小文字正規化が使用されます。

次のクエリは、テキスト アナライザとして PATTERN_ANALYZER を使用します。デフォルトの正規表現が使用されているため、2 文字以上の単語のみが用語として追加されます。また、結果は小文字になります。i2 は結果に表示されないことに注意してください。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'PATTERN_ANALYZER'
) AS results

/*----------------------------------------------------------------*
 | results                                                        |
 +----------------------------------------------------------------+
 | ['like', 'pie', 'you', 'like', 'pie', 'they', 'like', 'pies' ] |
 *----------------------------------------------------------------*/

テキスト アナライザのオプション

テキスト アナライザは、入力テキストの分析方法を決定するカスタム オプションをサポートしています。analyzer_options 引数を指定して一部の関数とステートメントにアナライザ オプションを渡すことができます。この引数は JSON 形式の STRING 値を取ります。

次の設定を選択できます。

  • delimiters: 区切り文字が検出されると入力が用語に分割されます。
  • patterns: 入力を、正規表現に一致する用語に分割します。
  • token_filters: 入力テキストを用語にトークン化した後、用語にフィルタを適用します。

delimiters アナライザ オプション

'{
  "delimiters": array_of_delimiters
}'

説明

LOG_ANALYZER テキスト アナライザを使用していて、デフォルトの区切り文字を使用しない場合は、入力テキストをフィルタするために使用する特定の区切り文字を指定できます。

定義

  • delimiters: 入力テキストのトークン化に使用する区切り文字を表す文字列を含む JSON 配列。

詳細

同じ接頭辞を持つ区切り文字が 2 つある場合は(%%2 など)、長い区切り文字の方が優先順位が高く、最初に分析されます。

区切り文字として任意の ASCII 文字列を追加できます。区切り文字の長さは 16 文字以下にする必要があります。含めることのできる一般的な区切り文字を以下に示します。

[ ] < > ( ) { } | ! ; , ' " * & ? + / : = @ . - $ % \ _ \n \r \s \t %21 %26
%2526 %3B %3b %7C %7c %20 %2B %2b %3D %3d %2520 %5D %5d %5B %5b %3A %3a %0A
%0a %2C %2c %28 %29

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'{"delimiters": [",", ".", "-"]}'
) AS results

/*-------------------------------------------------------*
 | results                                               |
 +-------------------------------------------------------+
 | ['i like pie', 'you like', 'pie', 'they like 2 pies]' |
 *-------------------------------------------------------*/

patterns アナライザ オプション

'{
  "patterns": array_of_regex_patterns
}'

説明

PATTERN_ANALYZER テキスト アナライザを使用していて、デフォルトの正規表現を使用しない場合は、入力テキストをフィルタするために使用する正規表現を指定できます。

定義

  • patterns: 正規表現を表す 1 つの文字列を含む JSON 配列。

詳細

PATTERN_ANALYZER テキスト アナライザにこのアナライザ オプションが指定されていない場合は、正規表現 \b\w{2,}\b がデフォルトで使用され、非 Unicode の単語(2 文字以上)に一致します。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'PATTERN_ANALYZER',
  analyzer_options=>'{"patterns": ["[a-zA-Z]*"]}'
) AS results

/*----------------------------------------------------------------*
 | results                                                        |
 +----------------------------------------------------------------+
 | ['like', 'pie', 'you', 'like', 'pie', 'they', 'like', 'pies' ] |
 *----------------------------------------------------------------*/

token_filters アナライザ オプション

'{
  "token_filters": array_of_token_filters
}'

説明

LOG_ANALYZER または PATTERN_ANALYZER テキスト アナライザを使用している場合は、入力テキストがトークン化された後、1 つ以上のトークン フィルタを入力テキストに順次適用できます。

定義

  • array_of_token_filters: トークン フィルタを表すオブジェクトを含む JSON 配列。

詳細

追加できる特定のトークン フィルタの詳細については、トークン フィルタをご覧ください。

たとえば、次のクエリには patterns オプションと token_filters オプションの両方が含まれています。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'PATTERN_ANALYZER',
  analyzer_options=>'''
  {
    "patterns": ["[a-zA-Z]*"],
    "token_filters": [
      {
        "normalizer": {
          "mode": "LOWER"
        }
      },
      {
        "stop_words": ["they", "pie"]
      }
    ]
  }
  '''
) AS results

/*----------------------------------------------*
 | results                                      |
 +----------------------------------------------+
 | ['i', 'like', 'you', 'like', 'like, 'PIEs' ] |
 *----------------------------------------------*/

トークン フィルタ

'{
  "token_filters": [
    {
      "normalizer": {
        "mode": json_string,
        "icu_normalize_mode": json_string,
        "icu_case_folding": json_boolean
      }
    },
    {
      "stop_words": json_string_array
    }
  ]
}'

トークン フィルタは、入力テキストから抽出された用語(トークン)を変更または削除できます。トークン フィルタをサポートするテキスト アナライザにトークン フィルタが指定されていない場合は、デフォルトで ASCII 小文字正規化トークン フィルタが適用されます。複数のトークン フィルタが追加されると、これらのフィルタは指定された順序で適用されます。同じトークン フィルタを token_filters 配列に複数回追加できます。詳しくは、このセクションの例をご覧ください。

定義

各トークン フィルタには、使用するトークン フィルタのタイプに応じて、次の JSON Key-Value ペアを含む一意の JSON 構文があります。

  • token_filters: トークン フィルタを含むオブジェクトの JSON 配列。この配列には、同じタイプのトークン フィルタを複数回含めることができます。

    • stop_words: 用語のリストから削除する単語を表す文字列の JSON 配列。

    • normalizer: トークン フィルタの正規化設定を含む JSON オブジェクト。設定には次のようなものがあります。

      • mode: 正規化モードを表す JSON 文字列。次の設定を選択できます。

        • NONE: 用語に正規化モードを適用しません。

        • LOWER: ASCII の小文字の用語。トークン フィルタをサポートするテキスト アナライザにトークン フィルタが指定されていない場合は、デフォルトでこれが使用されます。

        • ICU_NORMALIZE: 用語の ICU 正規化。

      • icu_normalize_mode: ICU 正規化モードを表す JSON 文字列。次の設定を選択できます。

        これは、modeICU_NORMALIZE の場合に使用できます。modeICU_NORMALIZE で、この Key-Value ペアが設定されていない場合、icu_normalize_mode はデフォルトで NFKC になります。

      • icu_case_folding: ICU の大文字小文字変換を用語に適用するかどうかを決定する JSON ブール値。ICU の大文字小文字変換を用語に適用する場合は true。それ以外の場合は false

        これは、modeICU_NORMALIZE の場合に使用できます。modeICU_NORMALIZE で、この値が使用されていない場合、icu_case_folding はデフォルトで true になります。

詳細

トークン フィルタは、1 つのクエリ内で NO_OP_ANALYZER テキスト アナライザを除くすべてのテキスト アナライザで使用できます。トークン フィルタは、テキスト アナライザが入力テキストを用語に分割した後に適用されます。

トークン フィルタをサポートするアナライザに token_filters が指定されていない場合、デフォルトで ASCII 小文字正規化が適用されます。

トークン フィルタ配列(token_filters)には、複数のトークン フィルタを追加できます。複数のトークン フィルタが追加されると、指定した順序で用語に適用されます。詳細については、このセクションの例をご覧ください。

同じトークン フィルタをトークン フィルタ配列に複数回追加できます。詳細については、このセクションの例をご覧ください。

トークン フィルタの JSON 構文を使用して用語に適用できるフィルタをいくつか示します。

次の例では、用語が NFKC で正規化されます。次に、ICU の大文字小文字変換が true であるため、用語は小文字に変換されます。最後に、小文字の単語 pies2 がクエリから削除されます。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFKC",
          "icu_case_folding": true
        }
      },
      {
        "stop_words": ["pies", "2"]
      }
    ]
  }
  '''
) AS results

/*------------------------------------------*
 | results                                  |
 +------------------------------------------+
 | ['i', 'like', '❶', 'you', 'like', 'ño' ] |
 *------------------------------------------*/

次のクエリは前のクエリと似ていますが、トークン フィルタの順序が並べ替えられており、クエリの結果に影響します。ストップワード トークン フィルタが適用された後に 2 に正規化され、PIEspies に正規化されるため、結果では 2PIEs が保持されます。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "stop_words": ["pies", "2"]
      },
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFKC",
          "icu_case_folding": true
        }
      }
    ]
  }
  '''
) AS results

/*-------------------------------------------------------*
 | results                                               |
 +-------------------------------------------------------+
 | ['i', 'like', '❶', '2', 'you', 'like', 'ño', 'pies' ] |
 *-------------------------------------------------------*/

クエリでは同じトークン フィルタを何回でも使用できます。次のクエリでは stop_words が 2 回使用されています。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "stop_words": ["like", "you"]
      },
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFKC",
          "icu_case_folding": true
        }
      },
      {
        "stop_words": ["ño"]
      }
    ]
  }
  '''
) AS results

/*----------------------------------*
 | results                          |
 +----------------------------------+
 | ['i', '❶', '2', 'pies', 'pies' ] |
 *----------------------------------*/

正規化なし

'{
  "token_filters": [
    "normalizer": {
      "mode": "NONE"
    }
  ]
}'

説明

正規化は用語に適用されません。

次のクエリでは、正規化は結果に適用されません。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "NONE"
        }
      }
    ]
  }
  '''
) AS results

/*----------------------------------------------------------------*
 | results                                                        |
 +----------------------------------------------------------------+
 | ['I', 'like', '❶', '②', 'pies', 'you', 'like', 'Ño', 'PIEs' ] |
 *----------------------------------------------------------------*/

小文字(ASCII)に変換

'{
  "token_filters": [
    "normalizer": {
      "mode": "LOWER"
    }
  ]
}'

説明

結果の用語に対して ASCII の小文字変換を実施します。

次のクエリでは、結果に ASCII の小文字変換が適用されます。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "LOWER"
        }
      }
    ]
  }
  '''
) AS results

/*----------------------------------------------------------------*
 | results                                                        |
 +----------------------------------------------------------------+
 | ['i', 'like', '❶', '②', 'pies', 'you', 'like', 'Ño', 'pies' ] |
 *----------------------------------------------------------------*/

小文字に変換(ICU の大文字小文字変換)

'{
  "token_filters": [
    "normalizer": {
      "mode": "ICU_NORMALIZE",
      "icu_case_folding": true
    }
  ]
}'

説明

ICU の大文字小文字変換を実施します。これにより、結果の用語が小文字に変換されます。

次のクエリでは、結果に ICU の大文字小文字変換が適用されます。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_case_folding": true
        }
      }
    ]
  }
  '''
) AS results

/*--------------------------------------------------------------*
 | results                                                      |
 +--------------------------------------------------------------+
 | ['i', 'like', '❶', '2' 'pies', 'you', 'like', 'ño', 'pies' ] |
 *--------------------------------------------------------------*/

大文字を維持

'{
  "token_filters": [
    "normalizer": {
      "mode": "ICU_NORMALIZE",
      "icu_case_folding": false
    }
  ]
}'

説明

結果の用語で大文字が小文字に変換されません。

次のクエリでは、結果に ICU の大文字小文字変換が適用されません。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_case_folding": false
        }
      }
    ]
  }
  '''
) AS results

/*---------------------------------------------------------------*
 | results                                                       |
 +---------------------------------------------------------------+
 | ['I', 'like', '❶', '2' 'pies', 'you', 'like',  'Ño', 'PIEs' ] |
 *---------------------------------------------------------------*/

NFC での ICU 正規化

'{
  "token_filters": [
    "normalizer": {
      "mode": "ICU_NORMALIZE",
      "icu_normalize_mode": "NFC"
    }
  ]
}'

説明

標準的な同値によって文字を分解して再構成する ICU NFC 正規化で、テキストを正規化します。

次のクエリでは、結果に NFC 正規化が適用されます。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFC"
        }
      }
    ]
  }
  '''
) AS results

/*---------------------------------------------------------------*
 | results                                                       |
 +---------------------------------------------------------------+
 | ['i', 'like', '❶', '②' 'pies', 'you', 'like',  'ño', 'pies' ] |
 *---------------------------------------------------------------*/

NFKC での ICU 正規化

'{
  "token_filters": [
    "normalizer": {
      "mode": "ICU_NORMALIZE",
      "icu_normalize_mode": "NFKC"
    }
  ]
}'

説明

互換性によって文字を分解し、標準的な同値によって文字を再構成する ICU NFKC 正規化で、テキストを正規化します。

次のクエリでは、結果に NFKC 正規化が適用されます。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFKC"
        }
      }
    ]
  }'''
) AS results

/*---------------------------------------------------------------*
 | results                                                       |
 +---------------------------------------------------------------+
 | ['i', 'like', '❶', '2' 'pies', 'you', 'like',  'ño', 'pies' ] |
 *---------------------------------------------------------------*/

NFD での ICU 正規化

'{
  "token_filters": [
    "normalizer": {
      "mode": "ICU_NORMALIZE",
      "icu_normalize_mode": "NFD"
    }
  ]
}'

説明

標準的な同値によって文字を分解し、複数の結合文字を特定の順序で配置する ICU NFD 正規化で、テキストを正規化します。

次のクエリでは、ñ の入力と出力は同じに見えますが、バイトが異なります(入力は \u00f1、出力は \u006e \u0303)。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFD"
        }
      }
    ]
  }
  '''
) AS results

/*---------------------------------------------------------------*
 | results                                                       |
 +---------------------------------------------------------------+
 | ['i', 'like', '❶', '2' 'pies', 'you', 'like',  'ño', 'pies' ] |
 *---------------------------------------------------------------*/

NFKD での ICU 正規化

'{
  "token_filters": [
    "normalizer": {
      "mode": "ICU_NORMALIZE",
      "icu_normalize_mode": "NFKD"
    }
  ]
}'

説明

互換性によって文字を分解し、複数の結合文字を特定の順序で配置する ICU NFKD 正規化で、テキストを正規化します。

次のクエリでは、ñ の入力と出力は同じに見えますが、バイトが異なります(入力は \u00f1、出力は \u006e \u0303)。

SELECT TEXT_ANALYZE(
  'I like ❶ ② pies, you like Ño PIEs',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {"normalizer": {
        "mode": "ICU_NORMALIZE",
        "icu_normalize_mode": "NFKD"
        }
      }
    ]
  }'''
) AS results

/*---------------------------------------------------------------*
 | results                                                       |
 +---------------------------------------------------------------+
 | ['i', 'like', '❶', '2' 'pies', 'you', 'like',  'ño', 'pies' ] |
 *---------------------------------------------------------------*/

単語を削除

'{
  "token_filters": [
    "stop_words": array_of_stop_words
  ]
}'

説明

結果から一連の用語(トークン)を除外します。

定義

  • array_of_stop_words: 用語を表す文字列を含む JSON 配列。これらの用語は結果に含まれません。配列には少なくとも 1 つの要素が必要です。空の文字列は有効な配列要素です。

次のクエリでは、theypie という単語が結果から除外されます。

SELECT TEXT_ANALYZE(
  'I like pie, you like-pie, they like 2 PIEs.',
  analyzer=>'LOG_ANALYZER',
  analyzer_options=>'''
  {
    "token_filters": [
      {
        "stop_words": ["they", "pie"]
      }
    ]
  }
  '''
) AS results

/*---------------------------------------------------*
 | results                                           |
 +---------------------------------------------------+
 | ['I', 'like', 'you', 'like', 'like, '2', 'PIEs' ] |
 *---------------------------------------------------*/