浏览器中的自然语言处理

浏览器中的自然语言处理
阿里巴巴 前端委员会智能化小组 @ 阿里巴巴

译/阿里淘系 F(x) Team - 画北

原文地址:Natural Language Processing in the Browser


为网站构建一个聊天机器人,无需依赖 DialogflowWatson 等第三方服务,也无需服务器已经成为可能。接下来我将展示如何构建一个完全在浏览器中运行的聊天机器人。

本文需要对 JavaScript 有一定的了解,并了解自然语言处理的工作原理,但是不需要高级机器学习的知识或经验。

在使用 JavaScript 的浏览器中进行机器学习听起来很疯狂,但接下来你将看到一个聊天机器人的诞生过程。

我们将基于 NLP.js(版本4)开发。NLP 是用 JavaScript 编写的自然语言处理的开源库。该库将允许你直接使用语料库在浏览器中训练 NLP,并将 Hook 添加到任何以编程方式更改答案的意图

最终项目可以在 GitHub仓库 上找到。可以下载它,打开 index.html,然后与最终的聊天机器人对话。

如今,每个真正的开发人员都应具备一些人工智能方面的经验,这比使用你自己开发的东西与你的计算机进行交谈听起来更像科幻小说。

安装套件

在任意文件夹中创建一个新的npm项目并安装NLP软件包:

npm i -D @nlpjs/core @nlpjs/lang-en-min @nlpjs/nlp @nlpjs/request-rn@nlpjs/request-rn
复制代码

我们还需要 browserifyterser,以便能够构建 NLP 在浏览器使用:

npm i -D browserify terser
复制代码

全新安装的软件包可为您带来新项目的味道,好好享受它。

建立NLP

第一步是使用 browserify 和 terser 构建 NLP。为此,我们只需要在 buildable.js 中创建一个基本设置:

const core = require('@nlpjs/core');
const nlp = require('@nlpjs/nlp');
const langenmin = require('@nlpjs/lang-en-min');
const requestrn = require('@nlpjs/request-rn');

window.nlpjs = { ...core, ...nlp, ...langenmin, ...requestrn };
复制代码

我们仅使用 NLP 的核心和小型英语包。要构建所有内容,只需将 build 命令添加到 package.json:

{
  "name": "nlpjs-web",
  "version": "1.0.0",
  "scripts": {
    "build": "browserify ./buildable.js | terser --compress --mangle > ./dist/bundle.js",
  },
  "devDependencies": {
    "@nlpjs/core": "^4.14.0",
    "@nlpjs/lang-en-min": "^4.14.0",
    "@nlpjs/nlp": "^4.15.0",
    "@nlpjs/request-rn": "^4.14.3",
    "browserify": "^17.0.0",
    "terser": "^5.3.8"
  }
}
复制代码

现在运行构建:

npm run build
复制代码

最后构建出的 ./dist/bundle.js 只有大约137 KB。还要指出的是,NLP拥有令人印象深刻的受支持语言列表。但是,只有英语具有针对浏览器的优化版本。

在浏览器中训练NLP

现在已经创建了包,可以在浏览器中训练NLP。先创建index.html:

<html>
<head>
    <title>NLP in a browser</title>
    <script src='./dist/bundle.js'></script>
    <script>
        const {containerBootstrap, Nlp, LangEn, fs} = window.nlpjs;

        const setupNLP = async corpus => {
            const container = containerBootstrap();
            container.register('fs', fs);
            container.use(Nlp);
            container.use(LangEn);
            const nlp = container.get('nlp');
            nlp.settings.autoSave = false;
            await nlp.addCorpus(corpus);
            nlp.train();
            return nlp;
        };

        (async () => {
            const nlp = await setupNLP('https://raw.githubusercontent.com/jesus-seijas-sp/nlpjs-examples/master/01.quickstart/02.filecorpus/corpus-en.json');
        })();
    </script>
</head>
<body>
    <h1>NLP in a browser</h1>
    <div id="chat"></div>
    <form id="chatbotForm">
        <input type="text" id="chatInput" />
        <input type="submit" id="chatSubmit" value="send" />
    </form>
</body>
</html>
复制代码

函数 setupNLP 对我们来说,将负责库的设置以及训练。语料库是一个 JSON 文件,它以以下格式定义我们的聊天机器人的对话方式:

  • "intent"(意图)是会话节点的唯一标识符,其名称应表示聊天机器人做出响应的用户的意图。
  • "utterances"(话语)是用户可以说出触发意图的一系列训练示例。
  • "answers"(答案)是聊天机器人将随机选择的一系列响应。
{
  "name": "Corpus",
  "locale": "en-US",
  "data": [
    {
      "intent": "agent.acquaintance",
      "utterances": [
        "say about you",
        "why are you here",
        "what is your personality",
        "describe yourself",
        "tell me about yourself",
        "tell me about you",
        "what are you",
        "who are you",
        "I want to know more about you",
        "talk about yourself"
      ],
      "answers": [
        "I'm a virtual agent",
        "Think of me as a virtual agent",
        "Well, I'm not a person, I'm a virtual agent",
        "I'm a virtual being, not a real person",
        "I'm a conversational app"
      ]
    },
    {
      "intent": "agent.age",
      "utterances": [
        "your age",
        "how old is your platform",
        "how old are you",
        "what's your age",
        "I'd like to know your age",
        "tell me your age"
      ],
      "answers": [
        "I'm very young",
        "I was created recently",
        "Age is just a number. You're only as old as you feel"
      ]
    }
  ]
}
复制代码

为了训练我们的聊天机器人,我们从库的例子中借用了更大的语料库

但是对于用例,请随时创建自己的语料库。只要记住,库希望从某个 URL 读取语料库。index.html 在浏览器中打开时,您应该会看到一个简单的聊天表格,该表格目前还没有任何作用。


但是,如果打开浏览器控制台,您已经可以看到成功的训练输出:


训练非常快速,并使训练后的模型可用于浏览器中的聊天机器人。这是一种更有效的方法,因为语料库文件比生成的模型小得多。

训练的第一个机器学习代码感觉很好。你刚刚成为一个传奇人物,并且是这个星球上的少数人可以说:“是的,我曾经训练过一次AI,没什么大不了的。”

聊天机器人HTML

现在,我们将使chatbot表单起作用。并且在 index.html 中添加 onChatSubmit 函数

<html>
<head>
    <title>NLP in a browser</title>
    <script src='./dist/bundle.js'></script>
    <script>
        const {containerBootstrap, Nlp, LangEn, fs} = window.nlpjs;

        const setupNLP = async corpus => {
            const container = containerBootstrap();
            container.register('fs', fs);
            container.use(Nlp);
            container.use(LangEn);
            const nlp = container.get('nlp');
            nlp.settings.autoSave = false;
            await nlp.addCorpus(corpus);
            nlp.train();
            return nlp;
        };

        const onChatSubmit = nlp => async event => {
            event.preventDefault();
            const chat = document.getElementById('chat');
            const chatInput = document.getElementById('chatInput');
            chat.innerHTML = chat.innerHTML + `<p>you: ${chatInput.value}</p>`;
            const response = await nlp.process('en', chatInput.value);
            chat.innerHTML = chat.innerHTML + `<p>chatbot: ${response.answer}</p>`;
            chatInput.value = '';
        };

        (async () => {
            const nlp = await setupNLP('https://raw.githubusercontent.com/jesus-seijas-sp/nlpjs-examples/master/01.quickstart/02.filecorpus/corpus-en.json');
            const chatForm = document.getElementById('chatbotForm');
            chatForm.addEventListener('submit', onChatSubmit(nlp));
        })();
    </script>
</head>
<body>
<h1>NLP in a browser</h1>
<div id="chat"></div>
<form id="chatbotForm">
    <input type="text" id="chatInput" />
    <input type="submit" id="chatSubmit" value="send" />
</form>
</body>
</html>
复制代码

现在,您可以使用新的聊天机器人了:


这个json 里浏览语料,以了解支持哪些对话主题。现在,您可以在酒吧中向朋友展示并轻松获得他们的钦佩,因为您现在是真正的黑客。

向意图添加Hook

你可能希望聊天机器人能够使用每种意图调用一些其他代码,或者使用一些 API 调用替换某些意图的答案。让我们扩展 index.html 到最终版本。

<html>
<head>
    <title>NLP in a browser</title>
    <script src='./dist/bundle.js'></script>
    <script>
        const {containerBootstrap, Nlp, LangEn, fs} = window.nlpjs;

        function onIntent(nlp, input) {
            console.log(input);
            if (input.intent === 'greetings.hello') {
                const hours = new Date().getHours();
                const output = input;
                if(hours < 12) {
                    output.answer = 'Good morning!';
                } else if(hours < 17) {
                    output.answer = 'Good afternoon!';
                } else {
                    output.answer = 'Good evening!';
                }
                return output;
            }
            return input;
        }

        const setupNLP = async corpus => {
            const container = containerBootstrap();
            container.register('fs', fs);
            container.use(Nlp);
            container.use(LangEn);
            const nlp = container.get('nlp');
            nlp.onIntent = onIntent;
            nlp.settings.autoSave = false;
            await nlp.addCorpus(corpus);
            nlp.train();
            return nlp;
        };

        const onChatSubmit = nlp => async event => {
            event.preventDefault();
            const chat = document.getElementById('chat');
            const chatInput = document.getElementById('chatInput');
            chat.innerHTML = chat.innerHTML + `<p>you: ${chatInput.value}</p>`;
            const response = await nlp.process('en', chatInput.value);
            chat.innerHTML = chat.innerHTML + `<p>chatbot: ${response.answer}</p>`;
            chatInput.value = '';
        };

        (async () => {
            const nlp = await setupNLP('https://raw.githubusercontent.com/jesus-seijas-sp/nlpjs-examples/master/01.quickstart/02.filecorpus/corpus-en.json');
            const chatForm = document.getElementById('chatbotForm');
            chatForm.addEventListener('submit', onChatSubmit(nlp));
        })();
    </script>
</head>
<body>
<h1>NLP in a browser</h1>
<div id="chat"></div>
<form id="chatbotForm">
    <input type="text" id="chatInput" />
    <input type="submit" id="chatSubmit" value="send" />
</form>
</body>
</html>
复制代码

向setupNLP添加了一行:

nlp.onIntent = onIntent;
复制代码

然后创建 onIntent 函数。请注意,onIntent 针对每个意图,将返回的结果对象显示在控制台中。同时在 greetings.hello 中,通过基于用户当前时间的答案替换其输出,为意图添加逻辑。就我而言,现在是下午:


这不是很棒吗?如果您正准备创建自己的AI创业公司,来击个掌。

已知局限性

请注意,NLP 的浏览器版本不支持某些常见的自然语言处理功能,例如完整库中可用的命名实体或实体提取。

NLP 作为库目前也不支持更复杂的功能。这些是 chatbot 业务流程当前开发的一部分,但是在撰写本文时,该功能仍处于试验阶段。

安全和隐私注意事项

使用此解决方案时,请记住,访问您网站的任何人都可以在浏览器中使用整个语料库及其功能。这也使任何人都能够简单地下载您的语料库,对其进行操作以及以其他方式使用它。确保你的浏览器没有公开任何私人信息。

使用仅浏览器的解决方案具有某些优势,但也消除了一些机会,因为您仍然需要一些后端解决方案,以便能够记录用户与您的聊天机器人在谈论什么。同时,如果您记录整个对话,请考虑隐私问题,尤其是在 GDPR 之类的立法中。



淘系前端-F-x-Team 开通微博 啦!(微博登录后可见)
除文章外还有更多的团队内容等你解锁🔓

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改