最小的语言操作原子

📄 文章 🌐 公开
📋 列表 ✏️ 编辑 🎨 画布版 📋 复制MD 🌐 复制HTML ☆ 收藏

对,我觉得你的思路非常值得做实验。而且你说的“类似基函数”这个比喻很准确:不一定要直接把“句子理解”当成一个巨大任务,而是先寻找一组最小的语言操作原子,再观察复杂语言现象能不能由这些原子组合出来。

如果你的目标是测试一种新的 NLP 方法,我建议不要从“分词、词向量、Transformer”这些现成模块出发,而是从语言到底需要哪些基本操作来拆。

一、先把自然语言处理拆成几个最基本的动作

我会把它分成 7 类。

1. 指称:这个东西是谁?

最基本的问题:

“猫” → 一个对象/概念
“北京” → 一个地点
“他” → 某个已经出现的人

可以叫:

REFER(指称)

例如:

小明喜欢猫。

至少需要建立:

小明 → 人
猫 → 动物

2. 属性:它是什么样?

把一个对象和一个属性连接起来。

猫很大。

变成:

猫 → 大

或者:

小明很聪明。
小明 → 聪明

这是非常基础的操作:

ATTRIBUTE(x, a)


3. 关系:两个东西之间有什么关系?

例如:

小明喜欢小红。

实际上就是:

喜欢(小明, 小红)

再比如:

猫追老鼠。
追(猫, 老鼠)

我认为这是 NLP 中非常重要的一个“基函数”。

因为很多语言最终都可以还原成:

对象 + 对象 + 关系

4. 动作:某个东西发生了什么变化?

例如:

小明打开门。

不是简单的:

小明 → 打开
门 → 被打开

而是一个事件:

事件:
    动作 = 打开
    执行者 = 小明
    对象 = 门

也就是:

EVENT(action, agent, object)

复杂语言里的“事件”“过程”“因果”,可能都是从这个东西组合出来的。


5. 否定:不是

这是一个特别值得测试的基本操作。

小明喜欢猫。
喜欢(小明, 猫)

变成:

小明不喜欢猫。
NOT(喜欢(小明, 猫))

注意:

否定不是一个普通词,而是一种对已有结构进行操作的函数。

这就已经很接近你说的“基函数”了。


6. 组合:把两个东西组成一个更大的东西

例如:

红色的苹果

可以认为:

苹果
↓
ATTRIBUTE(苹果, 红色)

再比如:

小明喜欢红色的苹果。

就是:

喜欢(
    小明,
    ATTRIBUTE(苹果, 红色)
)

于是语言开始出现递归组合

这可能才是你这个研究方向最核心的地方:

复杂语言未必需要新的基本运算,只需要已有运算不断组合。

7. 逻辑操作:如果、因为、所以、但是

再往上一层:

如果下雨,小明就不出去。

可以拆成:

IF(
    下雨,
    NOT(出去(小明))
)

再比如:

因为下雨,所以小明没有出去。
CAUSE(
    下雨,
    NOT(出去(小明))
)

再比如:

小明很聪明,但是他很懒。
AND(
    聪明(小明),
    懒(小明)
)

或者:

CONTRAST(
    聪明(小明),
    懒(小明)
)

于是:

否定、条件、因果、并列、转折,都可以成为更高层的组合操作。


二、这样一来,可以建立一个“语言基函数表”

我甚至建议你先不要追求很多。

可以从下面这套最小集合开始:

基本操作功能例子
REFER指向对象/概念
ATTRIBUTE对象具有属性猫→黑
RELATE建立关系喜欢(小明,猫)
EVENT表示事件打开(小明,门)
NOT否定不喜欢
AND合并A并且B
OR选择A或者B
IF条件如果A,则B
CAUSE因果A导致B
COMPARE比较A比B大
TIME时间关系A之后B
SPACE空间关系A在B里面

然后刻意限制模型只能使用这些操作

这就变成一个非常有意思的实验。


三、例如把一句很复杂的话“编译”一下

比如:

因为昨天晚上下了很大的雨,所以小明没有去公园,但是小红去了。

可以逐层拆:

雨(昨天晚上)

大雨(昨天晚上)

去(小明, 公园)

NOT(去(小明, 公园))

去(小红, 公园)

CAUSE(
    下雨(昨天晚上),
    NOT(去(小明, 公园))
)

CONTRAST(
    NOT(去(小明, 公园)),
    去(小红, 公园)
)

注意这里发生了一件很重要的事情:

句子本身没有消失,只是被转换成了一个结构。

那么你的新 NLP 方法就可以测试:

给定这套基础操作,能不能重新生成原来的语言?

如果可以,就出现了:

自然语言
   ↓
基本操作
   ↓
组合结构
   ↓
复杂语义
   ↓
自然语言

这实际上已经非常接近一个“语言编译器”的思想。


四、我觉得你真正应该测试的不是“理解”,而是“组合能力”

这是我认为你这个想法最有意思的地方。

传统 NLP 很容易测试:

“这句话是什么意思?”

但你可以换一个问题:

一个语言系统能不能只用少量基本操作,组合出越来越复杂的语言结构?

例如规定只有:

A = 指称
B = 属性
C = 关系
D = 否定
E = 因果
F = 条件

然后测试:

一级

猫
红猫
猫吃鱼

二级

红猫吃鱼
小明喜欢红猫
小明不喜欢红猫

三级

因为小明喜欢红猫,所以他买了一只。

四级

如果小明喜欢红猫,那么当他看到红猫的时候,他就会买一只。

五级

如果小明喜欢红猫,那么即使价格上涨,只要他认为这只猫值得,他仍然会购买。

然后观察:

复杂程度增加以后,你的算法需要增加新的基本函数吗?

如果不需要,只需要不断组合已有函数——

那就非常有意思了。


五、甚至可以做一个“语言基函数实验”

我建议你第一版不要碰大型语料库。

自己做一个非常小的测试集。

比如只使用:

20个名词

人、猫、狗、鱼、苹果、汽车、学校……

20个关系

喜欢、吃、看、追、拥有、进入……

10个属性

大、小、红、蓝、聪明、漂亮……

10个逻辑操作

不、并且、或者、如果、因为、所以、但是……

然后随机组合。

例如:

猫 + 吃 + 鱼

小明 + 喜欢 + 猫

小明 + 不喜欢 + 猫

如果 + 小明喜欢猫 + 那么 + 小明买猫

因为 + 猫饿了 + 所以 + 猫吃鱼

然后逐渐增加组合深度:

深度 1
深度 2
深度 3
深度 4
深度 5
……

最后画一条曲线:

语言复杂度 ↑ → 算法性能 ↓

看看你的方法在什么地方开始崩溃。


六、而且这和你之前想到的“语义扩散”其实可以接起来

你之前提出过一个想法:

不一定要计算所有词之间的高维向量相似度,而是把相近的词连接起来,然后通过 2 度、3 度关系进行语义扩散。

这个想法和现在这个“基函数”思路其实可以形成一个更大的架构。

可以变成:

                 自然语言
                    ↓
              语言基本单元
                    ↓
          ┌─────────┴─────────┐
          ↓                   ↓
       词/概念节点          操作节点
          ↓                   ↓
      语义关系网络       基本语言函数
          └─────────┬─────────┘
                    ↓
                 组合
                    ↓
                 语义结构
                    ↓
                复杂理解

也就是说,你研究的可能不再是:

“如何让一个神经网络更聪明?”

而是一个更基础的问题:

“自然语言的复杂性,能否由有限数量的语义原子 + 有限数量的组合操作产生?”

这个问题我觉得非常值得认真做实验

而且如果要验证,我建议下一步直接建立一个 “NLP 基函数最小集合 v0.1”,把每个函数定义成严格的输入、输出和组合规则,然后设计 100~1000 个由简单到复杂的测试句子。这样你的新 NLP 方法就可以和 Transformer/词向量方法做一个非常干净的对照实验。

💬 留言 ⋮⋮

加载中…
💡 不登录也可留言(IP 限制:每文/每天各 1/10 条)

加载中…

纸张白
护眼绿
羊皮卷
夜间黑
100%