使用 Cloud Natural Language API 进行实体、情感和语法分析

Cloud Natural Language API 可用于从文本中提取实体、进行情感分析和语法分析,并将文本进行分类。

在本实验中,我们将了解如何使用 Natural Language API 来分析实体、情感和语法。

学习内容

  • 创建 Natural Language API 请求并使用 curl 调用 API
  • 使用 Natural Language API 从文本中提取实体并进行情感分析
  • 使用 Natural Language API 对文本进行语言分析
  • 创建使用其他语言的 Natural Language API 请求

所需

  • 一个 Google Cloud Platform 项目
  • 一个浏览器,例如 ChromeFirefox

您将如何使用本教程?

仅阅读教程内容 阅读并完成练习

您如何评价自己在使用 Google Cloud Platform 方面的经验水平?

新手 中级 熟练

自定进度的环境设置

如果您还没有 Google 帐号(Gmail 或 Google Apps),则必须创建一个。登录 Google Cloud Platform Console (console.cloud.google.com) 并创建一个新项目:

2016-02-10 12:45:26 的屏幕截图.png

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一名称(很抱歉,上述名称已被占用,您无法使用!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

接下来,您需要在 Cloud Console 中启用结算功能,才能使用 Google Cloud 资源。

在此 Codelab 中运行仅花费几美元,但是如果您决定使用更多资源或继续让它们运行,费用可能更高(请参阅本文档末尾的“清理”部分)。

Google Cloud Platform 的新用户有资格获享 $300 免费试用

点击屏幕左上角的菜单图标。

从下拉菜单中选择 API 和服务,然后点击“信息中心”

点击启用 API 和服务

然后,在搜索框中搜索“语言”。点击 Google Cloud Natural Language API

点击启用以启用 Cloud Natural Language API:

请稍等片刻,以将其启用。启用之后,您将看到以下内容:

Google Cloud Shell 是在云端运行的命令行环境。这是一款基于 Debian 的虚拟机,其中预装了您需要的所有开发工具(gcloudbqgit 等),并提供 5GB 的永久性主目录。我们将使用 Cloud Shell 创建对 Natural Language API 的请求。

如需开始使用 Cloud Shell,请点击标题栏右上角的“激活 Google Cloud Shell”图标 2015 年 6 月 8 日下午 5.30.32 的屏幕截图

一个 Cloud Shell 会话随即会在控制台底部的新框内打开,并显示命令行提示符。等待 user@project:~$ 提示出现

由于我们将使用 curl 向 Natural Language API 发送请求,因此需要生成 API 密钥来传入请求网址。如需创建 API 密钥,请转到 Cloud Console 中“API 和服务”的“凭据”部分:

在下拉菜单中选择 API 密钥

接下来,复制您刚刚生成的密钥。您在实验过程中需要使用此密钥。

现在您已经有了 API 密钥,请将其保存到环境变量,这样就不必在每个请求中插入 API 密钥的值了。您可以在 Cloud Shell 中执行此操作。请务必将 <your_api_key> 替换为您刚刚复制的密钥。

export API_KEY=<YOUR_API_KEY>

我们使用的第一个 Natural Language API 方法是 analyzeEntities。通过这种方法,API 可以从文本中提取实体(例如人物、地点和事件)。为了试用该 API 的实体分析,我们将使用以下语句:

Joanne Rowling,以笔名 J. K. 罗琳和罗伯特·加尔布赖斯是一位英国小说家和编剧,也是《哈利·波特》奇幻系列作品的作者。

我们将在 request.json 文件中构建对 Natural Language API 的请求。在 Cloud Shell 环境中,使用以下代码创建 request.json 文件。您可以使用以下任一首选命令行编辑器(nano、vim、emacs)创建该文件,也可以使用 Cloud Shell 中的内置 Orion 编辑器:

request.json

{
  "document":{
    "type":"PLAIN_TEXT",
    "content":"Joanne Rowling, who writes under the pen names J. K. Rowling and Robert Galbraith, is a British novelist and screenwriter who wrote the Harry Potter fantasy series."
  },
  "encodingType":"UTF8"
}

我们在请求中会将要发送的文本告知 Natural Language API。支持的类型值为 PLAIN_TEXTHTML。在内容中,我们会将文本发送给 Natural Language API 进行分析。Natural Language API 还支持发送存储在 Cloud Storage 中的文件以进行文本处理。如果要从 Cloud Storage 发送文件,需要将 content 替换为 gcsContentUri,并为该文件指定 Cloud Storage 中的文本文件的 uri。encodingType 用于告知 API 在处理我们的文本时应使用何种文本编码。API 将使用此 API 计算特定实体在我们文本中的显示位置。

您现在可以通过以下 curl 命令(通过一个命令行),将请求正文和您之前保存的 API 密钥环境变量传递给 Natural Language API:

curl "https://language.googleapis.com/v1/documents:analyzeEntities?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

响应的开头应如下所示:

{
  "entities": [
     {
      "name": "Robert Galbraith",
      "type": "PERSON",
      "metadata": {
        "mid": "/m/042xh",
        "wikipedia_url": "https://en.wikipedia.org/wiki/J._K._Rowling"
      },
      "salience": 0.7980405,
      "mentions": [
        {
          "text": {
            "content": "Joanne Rowling",
            "beginOffset": 0
          },
          "type": "PROPER"
        },
        {
          "text": {
            "content": "Rowling",
            "beginOffset": 53
          },
          "type": "PROPER"
        },
        {
          "text": {
            "content": "novelist",
            "beginOffset": 96
          },
          "type": "COMMON"
        },
        {
          "text": {
            "content": "Robert Galbraith",
            "beginOffset": 65
          },
          "type": "PROPER"
        }
      ]
    },

    ...
  ]
}

对于响应中的每个实体,我们会获得实体 type、关联的 Wikipedia 网址(如果有)、salience 以及此实体在文本中出现的位置的索引。显著性是 [0,1] 范围内的一个数字,指的是相应实体对整个文本的中心性。Natural Language API 还可通过不同方式识别同一实体。我们看看响应中的 mentions 列表:该 API 能够分辨“Joanne Rowling”、“Rowling”、“quet;novelist”和“Robert Galbriath”都指向同一内容。

除了提取实体之外,Natural Language API 还允许您对文本块执行情感分析。我们的 JSON 请求将包含与上述请求相同的参数,但这一次,我们将更改该文本,以添加具有更强烈情绪的内容。将 request.json 文件替换为以下内容,并将其下方的 content 替换为您自己的文本:

request.json

 {
  "document":{
    "type":"PLAIN_TEXT",
    "content":"Harry Potter is the best book. I think everyone should read it."
  },
  "encodingType": "UTF8"
}

接下来,我们将向 API 的 analyzeSentiment 端点发送请求:

curl "https://language.googleapis.com/v1/documents:analyzeSentiment?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

您的响应应如下所示:

{
  "documentSentiment": {
    "magnitude": 0.8,
    "score": 0.4
  },
  "language": "en",
  "sentences": [
    {
      "text": {
        "content": "Harry Potter is the best book.",
        "beginOffset": 0
      },
      "sentiment": {
        "magnitude": 0.7,
        "score": 0.7
      }
    },
    {
      "text": {
        "content": "I think everyone should read it.",
        "beginOffset": 31
      },
      "sentiment": {
        "magnitude": 0.1,
        "score": 0.1
      }
    }
  ]
}

请注意,我们有两种类型的情感值:整个文档的情感和按句子细分的情感。情感方法会返回两个值:scoremagnitudescore 是一个介于 -1.0 到 1.0 之间的数字,用于表明语句的正面或负面程度。magnitude 是从 0 到无穷大的数字,表示语句中表达的情绪的权重,而不管是正面还是负面。使用较长权重的语句时,较长文本块具有较高的幅度值。第一句的分数是正数 (0.7),第二句的分数是中立的 (0.1)。

除了针对我们发送的 NL API 的整个文本文档提供情感详情之外,它还可以按文本中的实体细分情感。我们以下面这句话为例:

我喜欢吃寿司,但服务非常糟糕

在这种情况下,如前所述,获取整个句子的情感得分可能不是很有用。如果这是一条餐馆评价,并且同一家餐馆有数百条评价,我们想要知道人们在评价中喜欢和不喜欢哪些内容。幸运的是,NL API 有一个方法,可让我们获取文本中每个实体(名为 analyzeEntitySentiment)的情感。用上面的语句更新您的 request.json 以试用:

request.json

 {
  "document":{
    "type":"PLAIN_TEXT",
    "content":"I liked the sushi but the service was terrible."
  },
  "encodingType": "UTF8"
}

然后,使用以下 curl 命令调用 analyzeEntitySentiment 端点:

curl "https://language.googleapis.com/v1/documents:analyzeEntitySentiment?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

我们在响应中返回了两个实体对象:一个用于“寿司”,另一个用于“服务”。以下是完整的 JSON 响应:

{
  "entities": [
    {
      "name": "sushi",
      "type": "CONSUMER_GOOD",
      "metadata": {},
      "salience": 0.52716845,
      "mentions": [
        {
          "text": {
            "content": "sushi",
            "beginOffset": 12
          },
          "type": "COMMON",
          "sentiment": {
            "magnitude": 0.9,
            "score": 0.9
          }
        }
      ],
      "sentiment": {
        "magnitude": 0.9,
        "score": 0.9
      }
    },
    {
      "name": "service",
      "type": "OTHER",
      "metadata": {},
      "salience": 0.47283158,
      "mentions": [
        {
          "text": {
            "content": "service",
            "beginOffset": 26
          },
          "type": "COMMON",
          "sentiment": {
            "magnitude": 0.9,
            "score": -0.9
          }
        }
      ],
      "sentiment": {
        "magnitude": 0.9,
        "score": -0.9
      }
    }
  ],
  "language": "en"
}

我们可以看到,“sushi”的得分为 0.9,而“service”的得分为 -0.9。棒极了!您可能还注意到,每个实体都返回了两个情感对象。如果其中多次提及其中任何一个术语,该 API 会针对每次提及返回不同的情感得分和量值,以及实体的汇总情感。

我们来看一看 Natural Language API 的第三个方法,即语法注释,我们会更深入地了解文本的语言细节。analyzeSyntax 方法可以提供有关文本语义和语法元素的完整详细信息。对于文本中的每个字词,API 都会告知我们这个词的名词(名词、动词、形容词等)及其与句子中其他字词的关系(它是根动词吗?修饰符)。

用简单的一句话试试看吧。我们的 JSON 请求与上述类似,但增加了一个功能键。这将告知 API,我们想要执行语法注解。将您的 request.json 替换为以下内容:

request.json

{
  "document":{
    "type":"PLAIN_TEXT",
    "content": "Hermione often uses her quick wit, deft recall, and encyclopaedic knowledge to help Harry and Ron."
  },
  "encodingType": "UTF8"
}

然后调用 API 的 analyzeSyntax 方法:

curl "https://language.googleapis.com/v1/documents:analyzeSyntax?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

对于句子中的每个令牌,响应应返回一个如下所示的对象。我们来看一下“使用”一词的响应:

{
  "text": {
    "content": "uses",
    "beginOffset": 15
  },
  "partOfSpeech": {
    "tag": "VERB",
    "aspect": "ASPECT_UNKNOWN",
    "case": "CASE_UNKNOWN",
    "form": "FORM_UNKNOWN",
    "gender": "GENDER_UNKNOWN",
    "mood": "INDICATIVE",
    "number": "SINGULAR",
    "person": "THIRD",
    "proper": "PROPER_UNKNOWN",
    "reciprocity": "RECIPROCITY_UNKNOWN",
    "tense": "PRESENT",
    "voice": "VOICE_UNKNOWN"
  },
    "dependencyEdge": {
      "headTokenIndex": 2,
      "label": "ROOT"
    },
    "lemma": "use"
}

我们来细分响应。partOfSpeech 可向我们提供每个字词的语言详情(许多字词都未知,因为它们不适用于英语或这个特定字词)。tag 提供此字词的词性(在此示例中是动词)。我们还可以获取有关时态、模态以及单词是单数还是复数的详细信息。lemma 是字词的规范形式(用于“use" it's "use”)。例如,字词 runrunsranrunning 均具有词元 run。词元值可用于跟踪大段文本中某个字词的出现次数。

dependencyEdge 包含可用于创建文本依赖项解析树的数据。这是一张示意图,说明句子中的字词之间有何关系。上述句子的依赖项解析树如下所示:

上述响应中的 headTokenIndex 是一个标记,其索引指向一个弧形“&uset”。我们可以将句子中的每个词法单元视为一个数组中的单词,而 2 的 headTokenIndex 表示“使用”是指“通常”一词在树中与之相连。

Natural Language API 还支持非英语语言(点击此处查看完整列表)。让我们用日语中的句子尝试以下实体请求:

request.json

{
  "document":{
    "type":"PLAIN_TEXT",
    "content":"日本のグーグルのオフィスは、東京の六本木ヒルズにあります"
  },
  "encodingType": "UTF8"
}

请注意,我们没有告诉 API 我们的文本是什么语言,它可以自动检测。接下来,我们将该消息发送到 analyzeEntities 端点:

curl "https://language.googleapis.com/v1/documents:analyzeEntities?key=${API_KEY}" \
  -s -X POST -H "Content-Type: application/json" --data-binary @request.json

以下是我们的响应中的前两个实体:

{
  "entities": [
    {
      "name": "日本",
      "type": "LOCATION",
      "metadata": {
        "mid": "/m/03_3d",
        "wikipedia_url": "https://en.wikipedia.org/wiki/Japan"
      },
      "salience": 0.23854347,
      "mentions": [
        {
          "text": {
            "content": "日本",
            "beginOffset": 0
          },
          "type": "PROPER"
        }
      ]
    },
    {
      "name": "グーグル",
      "type": "ORGANIZATION",
      "metadata": {
        "mid": "/m/045c7b",
        "wikipedia_url": "https://en.wikipedia.org/wiki/Google"
      },
      "salience": 0.21155767,
      "mentions": [
        {
          "text": {
            "content": "グーグル",
            "beginOffset": 9
          },
          "type": "PROPER"
        }
      ]
    },
    ...
  ]
  "language": "ja"
}

该 API 会提取日本的地理位置,以及 Google 的组织及其各自的维基百科页面。

您已了解如何使用 Cloud Natural Language API 通过提取实体、分析情感和进行语法注释来执行文本分析。

所学内容

  • 创建 Natural Language API 请求并使用 curl 调用 API
  • 使用 Natural Language API 从文本中提取实体并进行情感分析
  • 对文本进行语言分析,以创建依赖项解析树
  • 使用日语创建 Natural Language API 请求

后续步骤