文本分析

本文档简要介绍了 GoogleSQL for BigQuery 中的文本分析(也称为文本数据挖掘)。

GoogleSQL 支持文本分析,这种技术可识别非结构化文本中的字词(词元),然后使用这些字词获取富有实用价值的分析洞见,例如编入索引和搜索,或作为矢量化的输入,用于机器学习训练流水线。您可以使用文本分析器以特定方式分析信息,并使用文本分析选项来应用您自己的分析自定义。

文本分析在以下 GoogleSQL 函数和语句中受支持:

文本分析器

GoogleSQL for BigQuery 支持多种类型的文本分析器,可用于从非结构化文本中提取数据。您可以使用 analyzer 参数将分析器传递到某些函数和语句中。每个文本分析器都有独特的提取信息的方法。您可以选择以下选项:

  • NO_OP_ANALYZER:将以单个字词(词元)的形式提取输入。
  • LOG_ANALYZER:遇到分隔符时,将输入拆分为字词。
  • PATTERN_ANALYZER:将输入拆分为与正则表达式匹配的字词。

NO_OP_ANALYZER 分析器

NO_OP_ANALYZER 分析器是一种无操作分析器,将以单个字词(词元)的形式提取输入。系统不会对所生成的字词应用任何格式。

此分析器不支持任何文本分析器选项或词元过滤器。

示例

以下查询使用 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。此正则表达式匹配的是至少包含两个字符的非 Unicode 单词。如果您想使用其他正则表达式,请参阅 patterns 选项

此分析器支持词元过滤器。如需了解详情,请参阅 token_filters 选项。如果未指定 token_filters 选项,则默认使用 ASCII 小写标准化

示例

以下查询使用 PATTERN_ANALYZER 作为文本分析器。由于使用的是默认正则表达式,因此只有包含两个或更多字符的单词才会被作为字词包含进来。此外,结果将以小写形式显示。请注意,结果中不会显示 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)时,较长的分隔符的优先级更高,系统会先对其进行分析。

您可以添加任何 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:一个 JSON 数组,其中包含一个表示正则表达式的字符串。

详细信息

如果没有为 PATTERN_ANALYZER 文本分析器提供此分析器选项,则默认使用正则表达式 \b\w{2,}\b 来匹配至少包含两个字符的非 Unicode 单词。

示例

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_ANALYZERPATTERN_ANALYZER 文本分析器,可在输入文本经过词元化处理后对输入文本依序应用一个或多个词元过滤器。

定义

  • array_of_token_filters:一个 JSON 数组,其中包含表示词元过滤器的对象。

详细信息

如需详细了解您可以添加的特定词元过滤器,请参阅词元过滤器

示例

例如,此查询同时包含 patternstoken_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 语法,其中包含一些 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,且未设置此键值对,则 icu_normalize_mode 默认为 NFKC

      • icu_case_folding:用于确定是否将 ICU 大小写折叠应用于字词的 JSON 布尔值。设置为 true 会对字词进行 ICU 大小写折叠。否则为 false

        如果 modeICU_NORMALIZE,则可以使用此参数。如果 modeICU_NORMALIZE,且此值未被使用,则 icu_case_folding 默认为 true

详细信息

在同一查询中,词元过滤器可与除 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' ] |
 *------------------------------------------*/

下面的查询与上一个查询类似,但词元过滤器的顺序经过了重新排序,而这会影响查询的结果。在结果中,2PIEs 被保留,因为 被标准化为 2,而在“stop_words”词元过滤器被应用后,PIEs 会被标准化为 pies

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 使用了两次:

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"
    }
  ]
}'

说明

通过使用 NFKC 进行 ICU 标准化对文本进行标准化处理,该方法会按兼容性分解字符,然后会按规范等价性重组字符。

示例

在以下查询中,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"
    }
  ]
}'

说明

通过使用 NFD 进行 ICU 标准化对文本进行标准化处理,该方法会按规范等价性分解字符,然后会按特定顺序对多个组合字符进行排列。

示例

在以下查询中,虽然 ñ 的输入和输出看起来相同,但字节不同(输入为 \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"
    }
  ]
}'

说明

通过使用 NFKD 进行 ICU 标准化对文本进行标准化处理,该方法会按兼容性分解字符,然后按特定顺序对多个组合字符进行排列。

示例

在以下查询中,虽然 ñ 的输入和输出看起来相同,但字节不同(输入为 \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 数组。结果中不应包含这些字词。该数组必须至少包含一个元素。空字符串是有效的数组元素。

示例

在以下查询中,结果中不包括 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' ] |
 *---------------------------------------------------*/