GPT 是一种强大的自然语言处理技术,能够对文本进行深入分析,实现多种任务,如提取标签、识别实体、理解情感等。

在传统的机器学习工作流程中,若要分析一段文本的情感,首先需要收集带有标签的数据集,然后训练模型,接着探索如何在云端部署模型并进行推断。虽然这种方法可能取得不错的效果,但其工作流程较为繁琐。此外,对于每个任务(如情感分析和实体识别等),都需要训练和部署独立的模型。

GPT 的一大优势在于,对于许多此类任务,只需编写一个简单的提示,即可立即生成结果。这在应用程序开发方面具有显著的速度优势。此外,通过使用单一模型和 API,可以同时完成多种不同任务,无需研究如何训练和部署多个不同的模型。这大大简化了开发过程,提高了开发效率。

识别情感

我们以识别情感为列,写一个提示词来分析这段文本表达的情感。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本表达的情感是什么?\n"
            + "```%s```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

可以看到 GPT 已经帮我们分析出来了悲伤和思念的情绪。如果你想要一个更简洁的回答,以便于后续处理,我们可以添加另一个指令,用一个词回答。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本表达的情感是什么?\n"
            + "用一个词来回答”开心“或者“悲伤”\n"
            + "```%s```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

可以看到输出结果只有一个词,如果是应用程序可以把这个词做为输再做其他的一些事情。

识别情绪列表

GPT 在从一段文本中提取特定的东西方面非常擅长。我们还可以列出这段文本表达的情感列表,在这个列表中不要超过五个词。

public static void main3(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本表达的情绪列表。\n"
            + "在列表中不超过五项,并且格式化为由逗号分隔。\n"
            + "```\n"
            + "%s\n"
            + "```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

识别愤怒

如果我们只关注一种情绪,比如:愤怒。因为如果有人真的很愤怒,可能需要额外的关注,弄清楚发生了什么,并解决问题。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本表达的情感是愤怒吗?\n"
            + "请回答“是”或者”否“。\n"
            + "```\n"
            + "%s\n"
            + "```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

可以看到在这段文本里没有“愤怒”的情绪,我们不要过多的关注。

提取关键信息

假如我们需要从大量文本中提取关键信息,例如时间、地点和人物,并利用 GPT 将这些信息格式化为 JSON 格式,以便于应用程序的后续处理。具体来说,我们希望 GPT 能够生成一个包含 “time”、“place” 和 “person” 键的 JSON 对象,从而使得我们可以轻松地访问和操作这些数据。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本确定以下内容:\n"
            + "- 时间(time)\n"
            + "- 地点(place)\n"
            + "- 人物(person)\n"
            + "\n"
            + "以time、place、person为键的Json格式回答。\n"
            + "如果信息不存在,则使用“未知”作为值。\n"
            + "你的回答尽可能简短。\n"
            + "```\n"
            + "%s\n"
            + "```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

{
  "time": "未知",
  "place": "火车站月台",
  "person": "父亲"
}

可以看到,GPT 为我分析到了地点是火车站月台,人物有父亲,没有找到时间。

更全面的分析

接下来,我将向您展示如何利用该系统从文本中提取更丰富的信息。信息提取是自然语言处理领域的一个重要分支,它关注于从文本中挖掘出有价值的数据和知识。我们将深入探讨这一领域的核心技术和应用场景,帮助您更好地理解和运用信息提取技术。

在前面例子中,我们探讨了如何编写提示词来识别文本中的情感,判断是否存在愤怒情绪,从文本中提取时间、地点和人物关键信息。如果想要提取所有这些信息的一种方法是使用三个或四个独立的提示词,然后分别调用getCompletion方法三次或四次,以便逐一提取这些不同类型的信息。然而,在实际应用中,我们可以通过精心设计一个综合性的提示词,从而实现一次性提取所有相关信息的目的。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本确定以下内容:\n"
            + "- 情绪(sentiment)\n"
            + "- 是否表达了愤怒?(anger)\n"
            + "- 时间(time)\n"
            + "- 地点(place)\n"
            + "- 人物(person)\n"
            + "\n"
            + "以sentiment、anger、time、place、person为键的Json格式回答。\n"
            + "如果信息不存在,则使用“未知”作为值。\n"
            + "将anger的值格式化为布尔值。\n"
            + "你的回答尽可能简短。\n"
            + "```\n"
            + "%s\n"
            + "```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

{
  "sentiment": "悲伤",
  "anger": false,
  "time": "未知",
  "place": "火车站",
  "person": ["我", "父亲"]
}

输出一个JSON,其中情感是悲伤,愤怒的值是false,然后没有引号,因为我们要求将其输出为布尔值。

推理主题

接下来,我们将探讨 GPT 的一个引人注目的应用场景:主题推断。当面对一篇较长的文章时,我们可能会好奇这篇文章主要讨论了哪些核心内容?涉及了哪些关键主题?借助 GPT,我们可以轻松地解答这些问题,从而更好地理解和分析文本。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    String prompt = "分析三个反引号之间的文本的五个主题。\n"
            + "每个主题不超过5个字。主题之间使用逗号分隔。\n"
            + "```\n"
            + "%s\n"
            + "```";
    String response = getCompletion(String.format(prompt, text));
    System.out.println(response);
}

运行一下看看结果:

我们还可以确定最终主题列表中的每个项是否是下面的文本中的主题,如果发现了就提醒我们。

public static void main(String[] args) {
    String text = "我说道:“爸爸,你走吧。”\n"
            + "他望车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”\n"
            + "我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。\n"
            + "我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。"
            + "他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪。怕他看见,也怕别人看见。\n"
            + "我再向外看时,他已抱了朱红的橘子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。"
            + "他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的。过一会儿说:“我走了,到那边来信!”我望着他走出去。"
            + "他走了几步,回过头看见我,说:“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。\n";

    List<String> topicList = Arrays.asList("父爱", "母爱", "万猫学社");

    String prompt = "分析三个反引号之间的文本,确定下面的主题列表中每一项是否为文本中的主题。\n"
            + "每个主题用0或1给出你的答案。"
            + "主题列表:%s\n"
            + "```\n"
            + "%s\n"
            + "```";
    String response = getCompletion(
            String.format(prompt, topicList.stream().collect(Collectors.joining(", ")), text));

    System.out.println(response);
    System.out.println("=========================");

    Arrays.stream(response.split("\n")).forEach(str -> {
        if (str.endsWith("1")) {
            System.out.printf("发现以[%s]为主题的文本", str.split(":")[0]);
        }
    });
}

运行一下看看结果:

我们已经发现以父爱为主题的文本了。

当前示例中所使用的提示词可能并不具备足够的健壮性。在实际生产环境中,我们可能需要考虑将答案输出为 JSON 格式,而非简单的列表形式。这是因为 GPT 的输出结果可能存在一定程度的不一致性。因此,我们需要认识到,这段代码在实际应用中可能表现出较高的脆弱性。 你可以尝试修改这个提示词,以使其输出JSON而不是像这样的列表,然后拥有更健壮的方法来确定特定文章是否是关于父爱的文本。

尾声

在短短几分钟之内,GPT 能够让我们轻松构建多个系统,实现对文本的推断,而这在过去往往需要经验丰富的机器学习开发人员花费数天甚至数周的时间才能完成。

在接下来的文章中,我们将继续探讨 GPT 的另一个令人激动的功能:文本转换。我们将讨论如何将一段文本转换成另一段文本,例如将其翻译成另一种语言。敬请关注后续文章。

09-23 01:49