Monday, November 17, 2014

什么是机器学习? What is machine learning? (Chinese)

机器学习是 AI 最重要部分,但我上次用 Clojure 写 Genifer 的时候没有完成这部分,结果那 prototype 完全没有应用,是一大失误。

「学习」的本质

人脑很多时是通过「一般化 , generalization」来学习的。

例如,广东话俗语说:『有须就认老窦』(有胡子便认做父亲,用来取笑过份的一般而论),但可能婴儿就是这样辨认亲人的。

又例如,小时候爷爷教我写中文的「一二三四五」,学到 3 的时候我便自作聪明地说:「我知道了,四字的写法是 4 划!」  虽然是错误的,但表示小孩子的思想方式。

又例如,有些人被女人骗过一次之后,便永远不信女人。

这些都是 generalization 的例子。

相反的方向叫 specialization (特殊化),或 refinement (精细化)。

例如我们从「所有女人都说谎」修正到「有些女人是诚实的」,或者「那个骗我的女人其实也有诚实的一面。」

一般化 和 特殊化 就是逻辑学习的基本运作,没有别的内容了。

此外还有一种机器学习的範畴,是基於在空间中的点的模式识别


例如我们已经知道有两类东西 (分别标作红色和蓝色),而我们数量化地量度它们的某些特徵,然后在座标空间上点描出来,这时发现红点和蓝点的分布大致可以用一条线分割,於是以后我们只要量度那些特徵,就可以分辨哪些是红组或蓝组的东西,而不需要知道事先知道它们的颜色。

这种「空间中」的统计学习 (statistical learning),其先决条件是知道一些数值上的量度,否则根本没有几何空间可言。  神经网络就是这种 "spatial learning" 的例子。

On the other hand,逻辑学习是不需要几何空间的,它只需要「符号」运作 (symbolic manipulations)。

以下我们专注逻辑学习;  如何统一逻辑学习和空间学习,我觉得是研究的重要课题。


Logic-based learning


例如说,我们观察到「很多读电脑的人都戴眼镜」,但我们是怎样跳到这个「归纳」的结论的?

在逻辑引擎中,已经有的 gound facts (事实资料) 是:
读电脑(小明), 戴眼镜(小明),
读电脑(小娟), 戴眼镜(小娟),
读电脑(小强), 戴眼镜(小强),
读电脑(美玲), 戴眼镜(美玲),
读音乐(小芬),不 戴眼镜(小芬),
男生(小明),男生(小强),
女生(小娟),女生(美玲),女生(小芬),
. . . . . . . 等等。

我们欲求得到的 general rule 是:
读电脑(X) $\rightarrow$ 戴眼镜(X)

其实那算法就是在所有可能的 formula 里面搜寻

换句话说,由最简单的 formula 开始,我们不断 generate 越来越复杂的 formulas,然后我们逐一试验这些 formulas,看看哪一条最能解释事实

最简单的 formula 就是一条「空」的命题 (什么也没有,表示一切都是真的)。

然后我们逐步添加一些逻辑项 (terms)。

例如:
$\rightarrow$ 戴眼镜(X)
表示任何人都戴眼镜,但那和事实不符。

又例如:
女生(X) $\rightarrow$ 戴眼镜(X)
「所有女生都戴眼镜」,那也和事实不符。

最后我们试验:
读电脑(X) $\rightarrow$ 戴眼镜(X)
发现其机率很高 (或许有少数例外),於是接受这一假设。

换句话说,这是在「假设空间,hypothesis space」中的搜寻。

这些 search space (搜寻空间) 的结构,形状像「树」那样不断细分下去:


我们由最「一般」的命题 (什么都是真的) 开始搜寻,到越来越特殊的命题,例如「22 岁、五月生日、体重 70 公斤以上、读大学 4 年级、数学不合格、姓张的人 $\rightarrow$ 都戴眼镜」,这过程中必然会出现我们期待的 formula。  这叫 general-to-specific search。

但由於 假设空间里面 有非常多组合 (combinatorial) 的可能性,所以这种学习是很慢的。

似乎唯一的解决之道,就是把所有概念和法则都分类,例如「这是属於物理学的知识」、「这是关於我女朋友的知识」…… 等,而在搜寻时我们只关注那些最可能有关的集合,例如「买礼物给女友时 考虑 class A 的知识」、「物理学考试时 考虑 class B 的知识」 …… 等等。

虽然很难,但必须把这个算法写出来,否则 Genifer 便无望了!

PS:  我在 Genifer 网页里有更详细解释 inductive learning (PDF, in English)

Sunday, November 16, 2014

如何写一个逻辑引擎?How to write a logic engine? (Chinese)

现试用最简单的方法,介绍如何写一个逻辑引擎。

即使是现时最尖端的人工智能,例如 OpenCog,它的内部仍然是很简单的。

逻辑推理 (deduction) 只需要两个算法:

  1. 命题推理
  2. 配对法 (unification) 
这两个算法只需要数行程式就能表达 !


逻辑是什么?


逻辑可以分解为两部分:
  1. 命题逻辑 (propositional logic)
  2. 命题内部的结构

命题逻辑

命题逻辑的意思是:  我们只关心命题的真假,而不看命题内部的结构。  所以「小明爱小娟」和「北京昨天下雨」都是同一类句子,只要我们知道它们的真值 (truth value)。

命题之间的关系用箭頭表示,例如:
  1. 吃了不洁食物 $\rightarrow$ 肚痛
  2. 下大雨,没带雨伞 $\rightarrow$ 变落汤鸡
但命题不一定非黑即白,关系也会有不确定因素,所以最严格是要用 fuzzy probability (模糊 机率) 来描述。

推理的算法,原理很简单:

所有命题的关系构成一个 graph,例如下图:


有些 nodes 的真值我们知道,有些不知道; 我们将真值由已知的 nodes「传播」到未知的 nodes 去。 这传播有其法则,例如 机率 要用机率论的法则计算,你甚至可以自创,甚至可以用机器学习那些法则,而不需我们伤脑筋去设计!

所以,你只要懂得怎样在电脑建立和处理 graph 结构,第一个问题便解决了。

谓词逻辑

现在来看看句子内部的结构。

最经典的做法是用谓词逻辑 (predicate logic),那是 Gottlob Frege 在 1879 年发明的。  罗素 (Bertrand Russell) 用它改写所有数学,使之发扬光大,然后 AI 之父 John McCarthy 把它应用在 AI 上,变成 classical AI。  但现在我们搞 strong AI 的人似乎都不太喜欢它,使用一些变奏,但基调一样。

谓词逻辑的做法就是将句子拆成 predicate 和 predicate 里面的 objects。
例如:
「小明爱小娟」 -->  爱(小明,小娟)
「北京下雨」-->  下雨(北京)
但对於较为复杂的句子结构例如「小明执迷不悟地爱着小娟」则视乎个别研究者的做法,没有统一的准则。  我们暂时不深究。

其实只要用某个方法把句子内部拆开就行,命题的推理方法完全没有变。

但句子拆开之后,我们可以在里面使用 variables (变量),那是很有用的。

例如,我们可以构造:
爱(小明,X)
那变量 X 可以是 小娟、美玲、等。

於是现在我们需要另一个算法,叫 unification (配对)。

Unification

Unify 的作用是:  给定两个句子 A 和 B,它们内部可以很复杂,也可以有 variables,而我们试图找一些 substitutions (代入),令那两句变成一样

例如:
爱(X,Y)

爱(小强,美玲)
这两句命题,只要代入{X = 小强,Y = 美玲},就可以变成同一句。

当然有些命题是无法 unify 的,例如:
爱(小明,小娟)
恨(小明,X)
那算法便会回覆 "fail"。

变量是很重要的发明,有了变量才可以表达 general rules (一般法则),例如:
「女人都说谎」换成逻辑就是:
女人(X) $\rightarrow$ 说谎(X)

有些人被女人骗过一次之后,便永远不信女人;  所以人脑的思想也是透过 generalization (一般化) 来学习的。  那是机器学习的範围,容后再谈。

Unify 所做的其实是 pattern matching。
例如:
    戴眼镜(X) 或 爱(小明,Y)
是一些模式,可以套到:
    戴眼镜(美玲) 或 爱(小明,小娟)
这些实例上。

人工智能就是一个很大的资料库,里面有很多用模式写成的 general rules,经过配对而产生新的推论。  例如 小娟是女人,所以用上面那条 general rule,得出小娟说谎的结论。