thank you
thank you
thank you
thank you
diff --git a/404.html b/404.html index 9c123dda..253d89b7 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -
thank you
thank you
thank you
thank you
thank you
thank you
thank you
thank you
这里是我的博客,整理收纳了一些笔记、思维导图、资料
您可以叫我 fuuzen 或者「風船」,这是我随便起的一个用的比较久的网名,没有什么特别含义。fuusen 即「ふうせん」,但这个 ID 已经在 github 被注册了,所以只好叫做 fuuzen 了
这个博客网站的名字是 Balloon Party 或者「風船のパーティー」,也是我随便起的一个名字,没有什么特别含义
如果这里所整理收纳的资料对您的学习有帮助的话,欢迎您向您的朋友们推荐本博客!也欢迎您向我指出资料中的任何错误或提出宝贵的意见!
这里是我的博客,整理收纳了一些笔记、思维导图、资料
您可以叫我 fuuzen 或者「風船」,这是我随便起的一个用的比较久的网名,没有什么特别含义。fuusen 即「ふうせん」,但这个 ID 已经在 github 被注册了,所以只好叫做 fuuzen 了
这个博客网站的名字是 Balloon Party 或者「風船のパーティー」,也是我随便起的一个名字,没有什么特别含义
如果这里所整理收纳的资料对您的学习有帮助的话,欢迎您向您的朋友们推荐本博客!也欢迎您向我指出资料中的任何错误或提出宝贵的意见!
* 星号是没完全看完
持续更新中......
* 星号是没完全看完
持续更新中......
今天因为校青马班的活动又跑到南校开会、参观团一大。中涂我也不能用电脑,于是无聊之际,手机打开了一直感兴趣的《饿殍:明末千里行》的游戏录播,看了前面就上头了。于是一直到凌晨 3 点,打完了 2 个 TE ,非常有感触,于是一边听着 ED 写下本篇文章作记录。(即使第二天有早八我也不管了!)
这是我玩的第二篇国产的国产文字冒险游戏。(上一部是《OPUS: 龙脉长歌》,这两部观感都非常好)《饿殍》难怪这么火,是有些原因的:
我尤其比较喜欢的,还得是双线叙事处理穗的回忆了。穗的回忆可以说是最压抑的部分,在回忆的开头,展现了一点穗原本家庭的美好画面,但后面便开始逐渐步入绝望,令人揪心。尤其是《绝望》这一篇,最为压抑,也最为强而有力,直击玩家的心扉!
这部作品的描绘,很有 “中国” 的历史特色,最后也展现了 “反叛” 这样的末代王朝常见的主旋律。与日系作品相比,少了一分细腻,但却传达了与 “物哀” 一样的悲剧的美。
要说从这作品思考到了什么,倒也没有什么。对我来说,我想也是对于大部分和我一样的观众来说,这样的作品给我们的,更多的是摆脱平常朝九晚五、三点一线生活的一点调味。相比平静的青春校园主题作品,这样的乱世、在乱世中旅行、在乱世中寻仇的题材,更给人刺激感、新鲜感。
穗这个角色,塑造的相当好。她给人一种 “小大人” 的感觉,但是这些成熟、懂事、机灵等等不符合其年龄的特点,都反衬着她的艰辛遭遇,都令人心酸。在穗的回忆中,她反而是没有那么 “懂事” 的,还会因为父母煮了小猫而赌气。这样的前后对照,也是对她悲惨遭遇的深层次的刻画,饥荒的灾难不仅摧残她的身体,更塑造了她的性格,催生了她的成长。
而一路上,玩家要想达到好结局,必须要做的只有一件事:尽量在穗面前表现得善良一些,增加所谓的 “好感度”。这也是和传统的文字冒险游戏选项分支不太一样,从这里实际上也看出了游戏的一大主题:原谅。玩家的最终目标,或者说主人公良的终极目标,就是获取穗的原谅。不得不说这还是蛮反差的,因为穗的回忆中,淋漓尽致地描写了良杀害了穗爹爹后,穗家庭的更加惨不忍睹的悲剧,而玩家在见识到这一切之后,还要去替这个 “罪魁祸首” 寻求原谅。
确实,这也是很多人会排斥、难以接受的地方。把穗一家害得如此惨的弑父仇敌,凭什么要原谅?
当然,游戏制作者还是 “上价值”,提醒了玩家们,罪魁祸首不是良,不是男主,而是荒淫无道的王爷、朝廷官府,这也是为什么这个游戏这么有 “中国” 的历史特色,原来一切都是人压迫人导致的悲剧。
整个作品描绘的是一个悲剧、一幅惨状、一对命运不幸的主人公。
穗的人生,自从家里只剩她自己之后,就总是在围绕着 “为了复仇而活着” 了。
良的人生,自从父亲去世只剩他一个人之后,直到遇到穗之前,总是围绕着 “为自己而活着”。
两个角色也就是这样,有一种恰到好处的 “距离感”,看似合作伙伴,实则杀父仇人,在相互帮助、依赖的过程中,产生了一点点的、非常少的 “为对方而活着” 的感觉。而尤其是到了 TE “同生” ,“为对方而活着” 的感觉就更强烈了。
贯穿整个故事的,一直都是两人这样的 “距离感”。在 TE 之前的 3 个结局,突出表现了距离感与陌生感:
那张惊艳无比的烟花的 CG ,竟是良和穗的最后一面。而后,穗谎称解手,便一去不返,突然没了音讯。两人再次拉开了距离,突然一股陌生感、寂寞感向玩家袭来。
至此,穗这个角色的塑造堪称饱满,她不再是弱小无力的” 小羊 “,而是和良站在平等的位置上的,甚至站在审判良的位置上的,一个饱满的角色。并且,一直保持了一份 “距离感”,即穗与良的 “距离感”,也是玩家与” 穗 “这个角色的” 距离感 “,是不再相见的 “距离感”、是弑父血仇的 “距离感”、是生与死的” 距离感 “。
直到最后的结局 “同生” 也是,一直保留了这份若即若离的距离感,两人还是以仇人相称。这份 “距离感”,比皆大欢喜、甜甜蜜蜜发糖可要好太多了,这也是我非常喜欢的结局。
片段一 (同生) |
---|
良 [喂,我算了一下,如今你大概二十有三了吧。] |
满穗 [嗯。] |
良 [现在嫁人了没?] |
满穗 [没嫁呢。] |
良 [哦。] |
满穗 [良呢?打仗的候娶妻了吗?] |
良 [没娶,兵荒乱的,娶什么妻。] |
满穗 [也是。] |
片段二 (同生) |
---|
满穗 [其实,这么多年来,我跟别人提起我的名字,一直都是 “穗”。] |
满穗 [唯独良爷,我说了全名,是叫满穗。] |
良 [......] |
良 [哦?为何只有我有这个区别?] |
满穗 [呵...... 当初我就是觉得,要仇人知道我的全名,我才没有白复仇。] |
满穗 [如今怎么想的,我也不知道了......] |
良 [......] |
满穗 [......] |
良 [......] |
满穗 [话说回来,良爷觉得怎么样?] |
良 [什么怎么样?] |
满穗 [你喜欢 “满穗”,还是 “穗”?] |
良 [......] |
满穗 [......] |
良 [......] |
良 [“满穗” 吧] |
满穗 [......] |
良 [我喜欢 “满穗”......] |
满穗 [哦......] |
良 [满穗、满穗、满穗......] |
我念了一遍又一遍她的名字。 |
满穗 [......] |
她没有说话,只是装著听不见我在念她的名字 |
她特不时地整笑著,不知在高兴些什么 |
她望著窗外,饮著茶,似乎在想著一些什么...... |
—— 咕 |
我也饮下了一杯茶,望著她所眺望的方向,嘴角不自地勾起了一丝笑意。 |
片段三 (共死) |
---|
满穗 [以前... 我装成哑巴... 现在... 你真成哑巴了... 真好笑...] |
她轻声笑着 |
满穗 [良,抱紧我吧......] |
今天因为校青马班的活动又跑到南校开会、参观团一大。中涂我也不能用电脑,于是无聊之际,手机打开了一直感兴趣的《饿殍:明末千里行》的游戏录播,看了前面就上头了。于是一直到凌晨 3 点,打完了 2 个 TE ,非常有感触,于是一边听着 ED 写下本篇文章作记录。(即使第二天有早八我也不管了!)
这是我玩的第二篇国产的国产文字冒险游戏。(上一部是《OPUS: 龙脉长歌》,这两部观感都非常好)《饿殍》难怪这么火,是有些原因的:
我尤其比较喜欢的,还得是双线叙事处理穗的回忆了。穗的回忆可以说是最压抑的部分,在回忆的开头,展现了一点穗原本家庭的美好画面,但后面便开始逐渐步入绝望,令人揪心。尤其是《绝望》这一篇,最为压抑,也最为强而有力,直击玩家的心扉!
这部作品的描绘,很有 “中国” 的历史特色,最后也展现了 “反叛” 这样的末代王朝常见的主旋律。与日系作品相比,少了一分细腻,但却传达了与 “物哀” 一样的悲剧的美。
要说从这作品思考到了什么,倒也没有什么。对我来说,我想也是对于大部分和我一样的观众来说,这样的作品给我们的,更多的是摆脱平常朝九晚五、三点一线生活的一点调味。相比平静的青春校园主题作品,这样的乱世、在乱世中旅行、在乱世中寻仇的题材,更给人刺激感、新鲜感。
穗这个角色,塑造的相当好。她给人一种 “小大人” 的感觉,但是这些成熟、懂事、机灵等等不符合其年龄的特点,都反衬着她的艰辛遭遇,都令人心酸。在穗的回忆中,她反而是没有那么 “懂事” 的,还会因为父母煮了小猫而赌气。这样的前后对照,也是对她悲惨遭遇的深层次的刻画,饥荒的灾难不仅摧残她的身体,更塑造了她的性格,催生了她的成长。
而一路上,玩家要想达到好结局,必须要做的只有一件事:尽量在穗面前表现得善良一些,增加所谓的 “好感度”。这也是和传统的文字冒险游戏选项分支不太一样,从这里实际上也看出了游戏的一大主题:原谅。玩家的最终目标,或者说主人公良的终极目标,就是获取穗的原谅。不得不说这还是蛮反差的,因为穗的回忆中,淋漓尽致地描写了良杀害了穗爹爹后,穗家庭的更加惨不忍睹的悲剧,而玩家在见识到这一切之后,还要去替这个 “罪魁祸首” 寻求原谅。
确实,这也是很多人会排斥、难以接受的地方。把穗一家害得如此惨的弑父仇敌,凭什么要原谅?
当然,游戏制作者还是 “上价值”,提醒了玩家们,罪魁祸首不是良,不是男主,而是荒淫无道的王爷、朝廷官府,这也是为什么这个游戏这么有 “中国” 的历史特色,原来一切都是人压迫人导致的悲剧。
整个作品描绘的是一个悲剧、一幅惨状、一对命运不幸的主人公。
穗的人生,自从家里只剩她自己之后,就总是在围绕着 “为了复仇而活着” 了。
良的人生,自从父亲去世只剩他一个人之后,直到遇到穗之前,总是围绕着 “为自己而活着”。
两个角色也就是这样,有一种恰到好处的 “距离感”,看似合作伙伴,实则杀父仇人,在相互帮助、依赖的过程中,产生了一点点的、非常少的 “为对方而活着” 的感觉。而尤其是到了 TE “同生” ,“为对方而活着” 的感觉就更强烈了。
贯穿整个故事的,一直都是两人这样的 “距离感”。在 TE 之前的 3 个结局,突出表现了距离感与陌生感:
那张惊艳无比的烟花的 CG ,竟是良和穗的最后一面。而后,穗谎称解手,便一去不返,突然没了音讯。两人再次拉开了距离,突然一股陌生感、寂寞感向玩家袭来。
至此,穗这个角色的塑造堪称饱满,她不再是弱小无力的” 小羊 “,而是和良站在平等的位置上的,甚至站在审判良的位置上的,一个饱满的角色。并且,一直保持了一份 “距离感”,即穗与良的 “距离感”,也是玩家与” 穗 “这个角色的” 距离感 “,是不再相见的 “距离感”、是弑父血仇的 “距离感”、是生与死的” 距离感 “。
直到最后的结局 “同生” 也是,一直保留了这份若即若离的距离感,两人还是以仇人相称。这份 “距离感”,比皆大欢喜、甜甜蜜蜜发糖可要好太多了,这也是我非常喜欢的结局。
片段一 (同生) |
---|
良 [喂,我算了一下,如今你大概二十有三了吧。] |
满穗 [嗯。] |
良 [现在嫁人了没?] |
满穗 [没嫁呢。] |
良 [哦。] |
满穗 [良呢?打仗的候娶妻了吗?] |
良 [没娶,兵荒乱的,娶什么妻。] |
满穗 [也是。] |
片段二 (同生) |
---|
满穗 [其实,这么多年来,我跟别人提起我的名字,一直都是 “穗”。] |
满穗 [唯独良爷,我说了全名,是叫满穗。] |
良 [......] |
良 [哦?为何只有我有这个区别?] |
满穗 [呵...... 当初我就是觉得,要仇人知道我的全名,我才没有白复仇。] |
满穗 [如今怎么想的,我也不知道了......] |
良 [......] |
满穗 [......] |
良 [......] |
满穗 [话说回来,良爷觉得怎么样?] |
良 [什么怎么样?] |
满穗 [你喜欢 “满穗”,还是 “穗”?] |
良 [......] |
满穗 [......] |
良 [......] |
良 [“满穗” 吧] |
满穗 [......] |
良 [我喜欢 “满穗”......] |
满穗 [哦......] |
良 [满穗、满穗、满穗......] |
我念了一遍又一遍她的名字。 |
满穗 [......] |
她没有说话,只是装著听不见我在念她的名字 |
她特不时地整笑著,不知在高兴些什么 |
她望著窗外,饮著茶,似乎在想著一些什么...... |
—— 咕 |
我也饮下了一杯茶,望著她所眺望的方向,嘴角不自地勾起了一丝笑意。 |
片段三 (共死) |
---|
满穗 [以前... 我装成哑巴... 现在... 你真成哑巴了... 真好笑...] |
她轻声笑着 |
满穗 [良,抱紧我吧......] |
取指
取指
Agent 是指驻留在某一环境下能够自主(Autonomous)、灵活(Flexible)地执行动作以满足设计目标的行为实体。
上述定义具有如下二个特点。
智能体能在没有人类或其他智能体的干涉和指导的情况下运行,并能根据其内部状态和感知到的环境信息来决定该实施什么样的动作,进而控制自身的行为
智能体行为的灵活性主要体现为以下三方面:
(Reactive)
反应性是指智能体能够感知所处的环境,并能对环境中发生的相关事件(比如智能体间的交互、用户的指令等)作出适时反应,以满足系统设计目标
(Pro-active)
自发性是指智能体不仅具有目标并根据目标行事,而且能够主动地产生目标,进而实施自发的行为
(Social)
社会性是指智能体所驻留的环境可能存在其他智能体,它拥有这些智能体的有关信息和知识(比如这些智能体的物理位置、所拥有的资源和能力等),并能与它们进行交互和通信,实现灵活多样和复杂的合作、协商和竞争,以满足系统的设计目标
Agent 与分布式人工智能系统一样具有协作性、适应性等特性
Agent 必须利用知识修改其内部状态 (心理状态),以适应环境变化和协作求解的需要。
人类心理状态的要素可分为以下三种
受人类心理启发,传统 Agent 理论模型研究的主要方向为:
的关系及其形式化描述,力图建立 Agent 的 BDI 模型
计算机系统为 Agent 的开发和运行提供软件和硬件环境支持,使各个 Agent 依据全局状态协调地完成各项任务。具体地说:
(1) 在计算机系统中,Agent 相当于一个独立的功能模块、独立的计算机应用系统,它含有独立的外部设备、输入输出驱动装备、操作系统、数据结构和相应的输出。
(2) Agent 程序的核心部分叫做决策生成器或问题求解器,起到主控作用。
(3) Agent 的运行是一个或多个进程,并接受总体调度。
(4) 各个 Agent 在多个计算机 CPU 上并行运行,其运行环境由体系结构支持。
将智能体视为一个定理证明器,智能体的行为决策是一个基于知识库的定理证明过程
智能体的内部状态对应于智能体所拥有的知识
各个知识条目用逻辑语言(比如经典的一阶谓词逻辑或者 Hoare 逻辑)来表示
基于知识型体系结构的智能体开发方法、技术和工具,代表性工作包括:
知识型体系结构的不足:
一个由 Concurrent MetateM 实现的系统包含一组可并发、异步执行的智能体:
对智能体进行编程的本质实际上就是用逻辑符号来定义智能体规约。一个智能体规约对应于一组时序逻辑公式,它描述了智能体行为。
由 Concurrent MetateM 所定义的智能体实际上是一个迭代地建立关于智能体规约逻辑模型的过程。因此,Concurrent MetateM 中的智能体类似于一个定理证明器
Concurrent MetateM 中的每一个智能体包含以下二个主要的部件:
智能体对环境事件的响应是通过一组简单的反应式规则来实现的,这些规则描述了智能体的感知输入与响应动作之间的映射关系。
基于这些反应式规则,智能体无需通过复杂的推理和证明就可针对环境事件作出简单、快速地响应。
多智能体系统是指由多个相对独立同时又相互作用的智能体所构成的系统
每个智能体都是自主的行为实体,封装了行为以及行为控制机制,可以在无需外部指导的情况下实施行为;
这些智能体并不是孤立的,它们之间存在各种关系,需要相互交互和协同进而达成问题的求解
对于绝大多数多智能体系统而言,系统中的智能体要获得关于系统以及环境的完整、准确和及时的信息是非常困难的。这是由于智能体所驻留的环境可能会比较复杂,具有以下特点:
在多智能体系统中,由于智能体行为的自主性、智能体行为对环境影响的有限性、系统中无全局控制智能体、智能体间交互行为的动态性,多智能体系统的运行具有不可预测性和不确定性的特点。
核心假设:人工智能可以通过符号推理形式化刻画。
研究目的:将知识表达为计算机可处理(computer-tractable)的形式,以供智能体使用。
Non-cooperative Game Theory
四种类型拍卖:
四种拍卖形式奠定了拍卖的基本类型,其他无论什么形式的拍卖都只是这四种形式的变型与组合:
在一些合理的约束条件保证下,四种拍卖形式最终的收益是相等的。
给定买方人数,假定所有买方都是风险中性的,各买方的价值独立且具有相同的连续分布,而且分布函数严格递增。
那么,任何满足下列两个条件的拍卖机制对于卖方都会产生相同的期望收益(对于买方则产生相同的期望支出):
“收益等价定理” 是整个拍卖理论研究的起点。它表明:对于委托人来说,只要拍卖品不变,购买对象不变,无论采用什么拍卖方式,最终收益都是一样的。
当然 “收益等价定理” 说的是理想状态,这里我们千万不要忘记约束条件。在现实中,虽然拍卖品是共同的,但由于参与竞标的人不同、不同的拍卖流程和规则,结果产生拍卖结果的巨大差异。甚至同样一种拍卖办法,放到不同的国家,结果也会有天壤之别,原因在于现实的约束条件不同。
Cooperative / Colitional Game Theory
合作博弈是一种侧重于玩家群体行为的模型。与非合作博弈不同,合作博弈中的战略互动没有被明确建模。
仅仅拥有自主性(Autonomy)的 Agent 并不足以作为人 - Agent 交互的研究对象
当人们塑造他们与物体或技术的互动,好像它们有目的、动机或意图时,我们就有了人 - Agent 交互
通常,技术被设计成鼓励人们赋予它们 Agent 的性质,尽管这并非 Agent 的必要条件。人们会将 Agent 的性质赋予许多日常生活中的事物和技术,这是一个常见的研究领域
人机互补 —— 人类和 agent 各自互补缺点,利用优点
Agent 是指驻留在某一环境下能够自主(Autonomous)、灵活(Flexible)地执行动作以满足设计目标的行为实体。
上述定义具有如下二个特点。
智能体能在没有人类或其他智能体的干涉和指导的情况下运行,并能根据其内部状态和感知到的环境信息来决定该实施什么样的动作,进而控制自身的行为
智能体行为的灵活性主要体现为以下三方面:
(Reactive)
反应性是指智能体能够感知所处的环境,并能对环境中发生的相关事件(比如智能体间的交互、用户的指令等)作出适时反应,以满足系统设计目标
(Pro-active)
自发性是指智能体不仅具有目标并根据目标行事,而且能够主动地产生目标,进而实施自发的行为
(Social)
社会性是指智能体所驻留的环境可能存在其他智能体,它拥有这些智能体的有关信息和知识(比如这些智能体的物理位置、所拥有的资源和能力等),并能与它们进行交互和通信,实现灵活多样和复杂的合作、协商和竞争,以满足系统的设计目标
Agent 与分布式人工智能系统一样具有协作性、适应性等特性
Agent 必须利用知识修改其内部状态 (心理状态),以适应环境变化和协作求解的需要。
人类心理状态的要素可分为以下三种
受人类心理启发,传统 Agent 理论模型研究的主要方向为:
的关系及其形式化描述,力图建立 Agent 的 BDI 模型
计算机系统为 Agent 的开发和运行提供软件和硬件环境支持,使各个 Agent 依据全局状态协调地完成各项任务。具体地说:
(1) 在计算机系统中,Agent 相当于一个独立的功能模块、独立的计算机应用系统,它含有独立的外部设备、输入输出驱动装备、操作系统、数据结构和相应的输出。
(2) Agent 程序的核心部分叫做决策生成器或问题求解器,起到主控作用。
(3) Agent 的运行是一个或多个进程,并接受总体调度。
(4) 各个 Agent 在多个计算机 CPU 上并行运行,其运行环境由体系结构支持。
将智能体视为一个定理证明器,智能体的行为决策是一个基于知识库的定理证明过程
智能体的内部状态对应于智能体所拥有的知识
各个知识条目用逻辑语言(比如经典的一阶谓词逻辑或者 Hoare 逻辑)来表示
基于知识型体系结构的智能体开发方法、技术和工具,代表性工作包括:
知识型体系结构的不足:
一个由 Concurrent MetateM 实现的系统包含一组可并发、异步执行的智能体:
对智能体进行编程的本质实际上就是用逻辑符号来定义智能体规约。一个智能体规约对应于一组时序逻辑公式,它描述了智能体行为。
由 Concurrent MetateM 所定义的智能体实际上是一个迭代地建立关于智能体规约逻辑模型的过程。因此,Concurrent MetateM 中的智能体类似于一个定理证明器
Concurrent MetateM 中的每一个智能体包含以下二个主要的部件:
智能体对环境事件的响应是通过一组简单的反应式规则来实现的,这些规则描述了智能体的感知输入与响应动作之间的映射关系。
基于这些反应式规则,智能体无需通过复杂的推理和证明就可针对环境事件作出简单、快速地响应。
多智能体系统是指由多个相对独立同时又相互作用的智能体所构成的系统
每个智能体都是自主的行为实体,封装了行为以及行为控制机制,可以在无需外部指导的情况下实施行为;
这些智能体并不是孤立的,它们之间存在各种关系,需要相互交互和协同进而达成问题的求解
对于绝大多数多智能体系统而言,系统中的智能体要获得关于系统以及环境的完整、准确和及时的信息是非常困难的。这是由于智能体所驻留的环境可能会比较复杂,具有以下特点:
在多智能体系统中,由于智能体行为的自主性、智能体行为对环境影响的有限性、系统中无全局控制智能体、智能体间交互行为的动态性,多智能体系统的运行具有不可预测性和不确定性的特点。
核心假设:人工智能可以通过符号推理形式化刻画。
研究目的:将知识表达为计算机可处理(computer-tractable)的形式,以供智能体使用。
Non-cooperative Game Theory
四种类型拍卖:
四种拍卖形式奠定了拍卖的基本类型,其他无论什么形式的拍卖都只是这四种形式的变型与组合:
在一些合理的约束条件保证下,四种拍卖形式最终的收益是相等的。
给定买方人数,假定所有买方都是风险中性的,各买方的价值独立且具有相同的连续分布,而且分布函数严格递增。
那么,任何满足下列两个条件的拍卖机制对于卖方都会产生相同的期望收益(对于买方则产生相同的期望支出):
“收益等价定理” 是整个拍卖理论研究的起点。它表明:对于委托人来说,只要拍卖品不变,购买对象不变,无论采用什么拍卖方式,最终收益都是一样的。
当然 “收益等价定理” 说的是理想状态,这里我们千万不要忘记约束条件。在现实中,虽然拍卖品是共同的,但由于参与竞标的人不同、不同的拍卖流程和规则,结果产生拍卖结果的巨大差异。甚至同样一种拍卖办法,放到不同的国家,结果也会有天壤之别,原因在于现实的约束条件不同。
Cooperative / Colitional Game Theory
合作博弈是一种侧重于玩家群体行为的模型。与非合作博弈不同,合作博弈中的战略互动没有被明确建模。
仅仅拥有自主性(Autonomy)的 Agent 并不足以作为人 - Agent 交互的研究对象
当人们塑造他们与物体或技术的互动,好像它们有目的、动机或意图时,我们就有了人 - Agent 交互
通常,技术被设计成鼓励人们赋予它们 Agent 的性质,尽管这并非 Agent 的必要条件。人们会将 Agent 的性质赋予许多日常生活中的事物和技术,这是一个常见的研究领域
人机互补 —— 人类和 agent 各自互补缺点,利用优点
人工智能(Artificial Intelligence - AI):研究如何通过计算机技术实现一个智能体,让智能体完成类似于人类智能的行为。
完成智能行为的主体,是物理或抽象实体,可以感知世界并对世界施加作用。
大模型智能体 LLM Agent
在近几年随 ChatGPT 兴起的新概念
首先,需要测量人如何思考的方法:内省、心理实验、 脑成像。
交叉学科,融合人工智能的计算机模型和心理学实验技术,试图构建一种精确可测试的人类思维理论。
交叉学科,以认知科学的理论以及神经心理学、神经科学及计算机模型的实验证据为基础。
1950 年,英国数学家图灵 (Alan Turing) 提出了一个测试方法来确定一个机器是否具有人类智能。
符号主义 / 功能主义方法,模拟大脑逻辑思维功能
原理主要为物理符号系统 (即符号操作系统) 假设和有限合理性原理。
联结主义 / 结构主义方法,模拟大脑结构
原理主要为神经网络及神经网络间的连接机制与学习算法
行为主义 / 进化主义方法,模拟智能系统行为
原理为控制论及感知 — 动作型控制系统
一个完善的符号系统应具有下列 6 种功能
任何一个系统,如果它能够表现出智能,那么它就必定能够执行上述 6 种功能。反之,任何系统如果具有这 6 种功能,那么它就能够表现出智能;这种智能指的是人类所具有的那种智能。
物理符号系统的假设伴随 3 个推论,或称为附带条件
一个机器和人的思考行为都完全一样
只能表面上执行看上去的智能行为
智能体拥有在任何问题上应用智能的能力
只能完成一项具体任务的人工智能
早期爆发阶段,巨大期望
知识就是力量,知识工程
机器学习兴起,人工智能的春天
深度学习获得工业投资和应用
人工智能(Artificial Intelligence - AI):研究如何通过计算机技术实现一个智能体,让智能体完成类似于人类智能的行为。
完成智能行为的主体,是物理或抽象实体,可以感知世界并对世界施加作用。
大模型智能体 LLM Agent
在近几年随 ChatGPT 兴起的新概念
首先,需要测量人如何思考的方法:内省、心理实验、 脑成像。
交叉学科,融合人工智能的计算机模型和心理学实验技术,试图构建一种精确可测试的人类思维理论。
交叉学科,以认知科学的理论以及神经心理学、神经科学及计算机模型的实验证据为基础。
1950 年,英国数学家图灵 (Alan Turing) 提出了一个测试方法来确定一个机器是否具有人类智能。
符号主义 / 功能主义方法,模拟大脑逻辑思维功能
原理主要为物理符号系统 (即符号操作系统) 假设和有限合理性原理。
联结主义 / 结构主义方法,模拟大脑结构
原理主要为神经网络及神经网络间的连接机制与学习算法
行为主义 / 进化主义方法,模拟智能系统行为
原理为控制论及感知 — 动作型控制系统
一个完善的符号系统应具有下列 6 种功能
任何一个系统,如果它能够表现出智能,那么它就必定能够执行上述 6 种功能。反之,任何系统如果具有这 6 种功能,那么它就能够表现出智能;这种智能指的是人类所具有的那种智能。
物理符号系统的假设伴随 3 个推论,或称为附带条件
一个机器和人的思考行为都完全一样
只能表面上执行看上去的智能行为
智能体拥有在任何问题上应用智能的能力
只能完成一项具体任务的人工智能
早期爆发阶段,巨大期望
知识就是力量,知识工程
机器学习兴起,人工智能的春天
深度学习获得工业投资和应用
知识是经过加工的信息,它包括:
策略 —— 关于如何解决问题的政策方略,包括在什么时间、什么地点、由什么主体采取什么行动、达到什么目标、注意什么事项等等一整套完整而具体的行动计划规划、行动步骤、工作方式和工作方法
在给定的 问题 - 问题环境 - 主体目的 的条件下,智能就是有针对性地获取 问题 - 环境 的信息,恰当地对这些信息进行处理以提炼知识达到认知,在此基础上,把已有的知识与主体的目的信息相结合,合理地产生解决问题的策略信息,并利用所得到的策略信息在给定的环境下成功地解决问题达到主体的目的 (行为)。
省流:信息经加工提炼而成知识,知识被目的激活而成智能。
智能具有 4 个能力:
从语法和语义,可以给出使用该语言的 Agent 的必要的推理机制。
基于该推理机制,Agent 可以从已知的语句推导出结论,或判断某条信息是不是已蕴涵在现有的知识当中。
知识表示语言需要:
知识表示语言应该支持知识不完全的情况。不能表达这种不完全性的语言是表达能力不够的语言
程序设计语言比较善于描述算法和具体的数据结构
逻辑学 (logic) 是研究人类思维规律的科学,而现代逻辑学则是用数学 (符号化、公理化、形式化) 的方法来研究这些规律。
所谓符号化即是用 “一种只作整体认读的记号 (signs)”—— 符号 (symbols) 表示量、数及数量关系。也有用字母、符号表示思维的物理对象、概念对象、判断对象等。
语言化是符号化的初级阶段。
现代逻辑学对思维的研究,需要更加彻底的符号化过程。
欧氏几何公理系统中的所有概念都有鲜明的直观背景,其公理、定理也都有强烈的客观意义。像欧氏几何这样的公理系统,常被称为具体公理系统。
始于 Aristotle 的逻辑学被符号化、公理化,逐步演化为现代逻辑学。
所谓形式化,就是彻头彻尾的 “符号化 + 抽象公理化”
现代逻辑学形式系统组成:
以下讨论实际上均为二值逻辑
命题是具有真假意义的陈述句。
在特殊的情况下都具有 “真 (True)” 和 “假(False)” 的意义句子,都是命题。真值 —— 用 T 和 F 表示。
命题有两种类型:
命题逻辑就是研究命题和命题之间关系的符号逻辑系统。
命题逻辑的符号:
用 P、Q、R、S 等来表示命题。可分为:
因为命题变元可以表示任意命题,所以它不能确定真值,故命题变元不是命题。
复合命题的意义是命题组成成份的函数。
联结词的语义可以定义如下:
当命题变元 P 用一个特定的命题取代时,P 才能确定真值,这时也称为对命题变元 P 进行指派
设 G 是公式,A1, ... , An, 为 G 中出现的所有原子命题。公式 G 的一种指派是对 A1, ... , An 赋予的一组真值,其中每个 Ai (i=1 , ... , n) 或者为 T 或者为 F。
公式 G 称为在一种指派下为真,当且仅当 G 按该指派算出的真值为 T,否则称为在该指派下为假。
若在公式中有 n 个不同的原子 A1 , ... , An,那么该公式就有 个不同的指派。
公式 称为永真式或重言式 (tautology),如果对任意指派 α,α 均弄真 A,即 α(A)=T 。
公式 称为可满足的 (satisfiable), 如果存在指派 α 使 α(A)=T,否则称 为不可满足的 (unsatisfiable),或永假式。
永真式是可满足的
当 为永真式 (永假式) 时, 为永假式 (永真式)
称公式 逻辑蕴涵公式 B,记为 ,如果所有弄真 的指派亦必弄真公式 B
称公式集 逻辑蕴涵公式 B,记为 ,如果弄真 中所有公式的指派亦必弄真公式 B
称公式 逻辑等价公式 B,记为 ,如果 且
设 A 为含有命题变元 p 的永真式,那么将 A 中 p 的所有出现均代换为命题公式 B,所得公式 (称为 A 的代入实例) 仍为永真式。
设命题公式 含有子公式 C (C 为 A 中的符号串,且 C 为命题公式),如果 ,那么将 中子公式 C 的某些出现 (未必全部) 用 D 替换后所得公式 B 满足 。
命题公式 B 称为命题公式 的合取(或析取)范式,如果 ,且 B 呈如下形式:
其中 形如:
其中 为原子公式或原子公式的否定,并称 为文字。
【定理】
任一命题公式 φ 有其对应的合取 (析取) 范式。
命题公式 B 称为公式 A 的主合取 (或主析取) 范式,如果:
n 元命题公式的全体可以划分为 个等价类,每一类中的公式彼此逻辑等价,并等价于它们共同的主合取范式 (或主析取范式)。
为命题逻辑的合式公式
如果 A,B 是公式,那么这些也是命题逻辑的合式公式:
命题逻辑的形式系统 PC 包括 3 条公理模式 和 1 条推理规则(即分离规则):
称下列公式序列为公式 在 PC 中的一个证明 (proof):
其中
称 为 PC 中的定理,记为 ,如果公式 在 PC 中有一个证明。
( \vdash
) 断定符,表示可被推导出,可被证明
( \vDash
) 表示 永真
设 为一公式集,称以下公式序列为公式 的,以 为前提的演绎:
其中 满足:
称 为前提 的演绎结果,如果公式 有以 为前提的演绎。记为:
若 , 可以表示为:
若 , 则记为:
对应离散数学课程中的 “附加前提证明法”
对 PC 中任意公式集 和公式 :
PC 是可靠的,即对任意公式集 及公式 :
特别地,若 为 PC 的定理 ,则 永真 :
PC 是一致的 (consistent),即不存在公式 A,使得 与 均为 PC 之定理。
PC 是完全的,即对任意公式集 和公式 :
特别地,若 永真 ,A 必为 PC 的定理 :
谓词逻辑的语法元素表示如下。
一般一元谓词表达了个体的性质,而多元谓词表达了个体之间的关系
如果谓词 P 中的所有个体都是:
则该谓词为一阶谓词,如果某个个体本身又是一个一阶谓词,则称 为二阶谓词,以此类推递归定义 阶谓词
项可递归定义如下:
若 为 元谓词符号, 都是项,则称 为原子公式。在原子公式中,若 都不含变量,则 是命题。
给定公式集 进行合一,就是对 进行合一。
DEMO::
求证一个目标 时,利用归结反演:若子句集 是不可满足的,则可以使用归结规则由 产生空子句 NIL ,具体解题步骤:
谓词公式表示问题
(optional,定义常量)
定义谓词
将前提表示成谓词公式
规则:
......
事实
将要求证的问题表示成谓词公式
问题化为子句集
,
,
......
事实:
目标:(⚠️注意是 ⚠️)
得到 。
利用归结原理进行归结
对子句集进行归结时,一个关键问题是决定选取哪两个子句作归结,为此需要研究有效的归结控制策略。
假设原始子句 (包括待证明合式公式的否定的子句) 称为 层归结式。 层的归结式是一个 层归结式和一个 层归结式进行归结所得到的归结式。
宽度优先就是先生成第 层所有的归结式,然后是第 层所有的归结式,以此类推,直到产生空子句结束,或不能再进行归结为止。
深度优先是产生一个第 层的归结式,然后用第 层的归结式和第 层的归结式进行归结,得到第 层的归结式,直到产生空子句结束,否则,用第 层及其以下各层进行归结,产生第 层,以此类推。
单元优先 (unit preference) 策略,即在归结过程中优先考虑仅由一个文字构成的子句,这样的子句称为单元子句。
精确策略不涉及被归结子句的排序,它们只允许某些归结发生。
支持集 (set of support) 策略,实际是一种目标制导的反向推理
每次归结时,参与归结的子句中至少应有一个是:
所谓后裔是说,如果 是 与另外某子句的归结式,或者 是 的后裔与其他子句的归结式,则称 是 的后裔, 是 的祖先。
支持集策略是完备的,即假如对一个不可满足的子句集合运用支持集策略进行归结,那么最终会导出空子句。
线性输人 (linear input) 策略中参与归结的两个子句中至少有一个是原始子句集中的子句 (包括那些待证明的合式公式的否定)。
线性输人策略是高效的,但是不完备的,如子句集合 不可满足,但是无法用线性输入归结推出。
在归结过程中,除第一次归结都用给定的子句集中的子句外,其后每次归结则至少要有一个亲本子句是上次归结的结果。线性归结策略是完备的,高效的
由于线性输入策略是不完备的,改进该策略得到祖先过滤 (ancestry filtering) 策略,该策略是完备的而且是高效的。参与归结的两个子句中:
不完备但是高效,与单元优先的区别在于每次只考虑单元子句进行归结。
实际上是我的作业
已知:
用归结推理方法证明 Mary 不是 Tom 的兄弟
定义谓词:
问题用谓词公式表示:
再将问题化为子句集:
归结过程:
程序验证:
用谓词逻辑的子句集表示下述刑侦知识,并用反演归结的支持集策略证明结论。
(1) 用子句集表示下述知识。
(2) 求:John 可能会偷窃什么?
定义常量:
定义谓词:
用谓词逻辑的子句集表示:
这个 是我按照网上答案做的,实际上我觉得不需要这么麻烦,用 就可以了...
定义谓词 : 是所求问题的一个答案;
则问题 "John 可能会偷窃什么?" 可以表示为 也就是析取式:
所有可能的答案包括:
证明 问题,化为子句集:
支持集策略归结过程:
可证得:John 可能会偷酒(wine)和奶酪(cheese)
程序验证:
任何通过了历史考试并中了彩票的人都是快乐的。任何肯学习或幸运的人都可以通过所有考试,小张不学习,但很幸运,任何人只要是幸运的,就能中彩。
求证:小张是快乐的。
定义常量;
定义谓词:
用谓词公式表示问题:
求证目标为:
反演归结,将问题表示为子句集:
归结推理过程;
由此证得了:小张是快乐的。
程序验证:
实际上是我的作业
import queue | |
def parse(KB: str): | |
KB = KB.replace("{(", "").replace(")}", "") | |
items = KB.split("),(") | |
resolution_steps = map(lambda x: f'{items.index(x) + 1} ({x})', items) | |
clauses = [] | |
for item in items: | |
if item.endswith(')'): | |
item = item[:-1] | |
clause = [] | |
elements = item.split("),") | |
if elements[-1] == '': | |
elements.pop() | |
for i in range(len(elements)): | |
key, value = elements[i].split("(") | |
clause.append([key, value.split(',')]) | |
clauses.append(clause) | |
return clauses, list(resolution_steps) | |
def MGU(l1, l2): | |
variants = ('x', 'y', 'z', 'u', 'v', 'w', 'xx', 'yy', 'zz', 'uu', 'vv', 'ww') | |
dimension = len(l1) | |
mapdict = {} | |
for i in range(dimension): | |
if l1[i] in variants and l2[i] not in variants: | |
if mapdict.get(l1[i]) is None or mapdict[l1[i]] == l2[i]: | |
mapdict[l1[i]] = l2[i] | |
else: | |
return None | |
elif l1[i] not in variants and l2[i] in variants: | |
if mapdict.get(l2[i]) is None or mapdict[l2[i]] == l1[i]: | |
mapdict[l2[i]] = l1[i] | |
else: | |
return None | |
elif l1[i] not in variants and l2[i] not in variants and l1[i] != l2[i]: | |
return None | |
else: | |
if l1[i] != l2[i]: | |
mapdict[l1[i]] = l2[i] | |
return mapdict | |
# 以下是广度优先搜索策略 | |
def resolve(c1, c2): | |
list_c1keys = [sublist[0] for sublist in c1] | |
list_c2keys = [sublist[0] for sublist in c2] | |
for i in range(len(list_c1keys)): | |
c1key: str = list_c1keys[i] | |
idx_c1key = i | |
flag = c1key.startswith('~') | |
if flag: | |
complement = c1key[1:] | |
else: | |
complement = '~' + c1key | |
if complement in list_c2keys: | |
idx_complement = list_c2keys.index(complement) | |
mapdict = None | |
if c1[idx_c1key][1] != c2[idx_complement][1]: | |
result = MGU(c1[idx_c1key][1], c2[idx_complement][1]) | |
if result is None: | |
return None | |
else: | |
mapdict = result | |
if len(c1) > 1: | |
char1 = chr(ord('a') + idx_c1key) | |
else: | |
char1 = '0' | |
if len(c2) > 1: | |
char2 = chr(ord('a') + idx_complement) | |
else: | |
char2 = '0' | |
c1_to_del = list(c1) | |
c2_to_del = list(c2) | |
del c1_to_del[idx_c1key] | |
del c2_to_del[idx_complement] | |
c1_to_del.extend(c2_to_del) | |
return c1_to_del, char1, char2, mapdict | |
return None | |
def resolution(KB: str): | |
clauses, resolution_steps = parse(KB) | |
steps_idx = list(range(1, len(clauses) + 1)) | |
min_len = len(clauses) | |
while True: | |
l = len(clauses) | |
for i in range(len(clauses)): | |
for j in range(i + 1, len(clauses)): | |
if i == j: | |
continue | |
result = resolve(clauses[i], clauses[j]) | |
if result is None: | |
continue | |
resolvent = result[0] | |
if resolvent is None or resolvent in clauses: | |
continue | |
clauses.append(resolvent) | |
steps_idx.append([i, j]) | |
char1 = result[1] | |
char2 = result[2] | |
mapdict = result[3] | |
if char1 == '0' and char2 == '0': | |
pre_string = f"R[{i + 1},{j + 1}]" | |
elif char1 != '0' and char2 == '0': | |
pre_string = f"R[{i + 1}{char1},{j + 1}]" | |
elif char1 == '0' and char2 != '0': | |
pre_string = f"R[{i + 1},{j + 1}{char2}]" | |
else: | |
pre_string = f"R[{i + 1}{char1},{j + 1}{char2}]" | |
map_string = '' | |
if mapdict is not None: | |
pairs = [] | |
for key, value in mapdict.items(): | |
pairs.append(f"{key}={value}") | |
map_string = "{" + ",".join(pairs) + "}" | |
result_string = '' | |
for [key, value] in resolvent: | |
result_string += f'{key}({",".join(value)}),' | |
if len(resolvent) > 1: | |
result_string = result_string[:-1] | |
result_string = f'({result_string})' | |
resolution_steps.append(f"{len(resolution_steps) + 1} {pre_string}{map_string} = {result_string}") | |
if len(resolvent) == 0: | |
return resolution_steps, steps_idx, min_len | |
if l == len(clauses): | |
return None | |
def simplify_steps(steps, steps_idx, min_len): | |
q = queue.Queue() | |
not_del = [len(steps) - 1] | |
q.put(steps_idx[len(steps) - 1][0]) | |
q.put(steps_idx[len(steps) - 1][1]) | |
while not q.empty(): | |
i = q.get() | |
if i < min_len: | |
continue | |
not_del.append(i) | |
q.put(steps_idx[i][0]) | |
q.put(steps_idx[i][1]) | |
for i in range(len(steps) - 1, min_len - 1, -1): | |
if i not in not_del: | |
del steps[i] | |
num_map = dict() | |
for i in range(len(steps)): | |
num = (steps[i].split(' '))[0] | |
num_map[num] = f'{i+1}' | |
for t in list(num_map.keys()): | |
steps[i] = steps[i].replace(t, num_map[t]) | |
return steps | |
def ResolutionFOL(KB): | |
result = resolution(KB) | |
if result is None: | |
print("Can't be resolved!") | |
else: | |
(steps, steps_idx, min_len) = result | |
steps = simplify_steps(steps, steps_idx, min_len) | |
for step in steps: | |
print(step) | |
if __name__ == '__main__': | |
KB0 = "{(GradStudent(sue),),(~GradStudent(x),Student(x)),(~Student(x),HardWorker(x)),(~HardWorker(sue),)}" | |
KB1 = "{(A(tony),),(A(mike),),(A(john),),(L(tony,rain),),(L(tony,snow),),(~A(x),S(x),C(x)),(~C(y),~L(y,rain)),(L(z,snow),~S(z)),(~L(tony,u),~L(mike,u)),(L(tony,v),L(mike,v)),(~A(w),~C(w),S(w))}" | |
KB2 = "{(On(tony,mike),),(On(mike,john),),(Green(tony),),(~Green(john),),(~On(xx,yy),~Green(xx),Green(yy))}" | |
KB3 = "{(~B(x,y),~F(x)),(~S(x,y),F(x)),(S(Marry,Bill)),(B(Marry,Tom))}" | |
KB4 = "{(T(John),),(L(Paul,wine),),(L(Paul,cheese),),(~L(Paul,x),L(John,x)),(~T(x),~L(x,y),S(x,y)),(~S(John,z),ANSWER(z)),(~ANSWER(wine),~ANSWER(cheese))}" | |
KB5 = "{(~P(x,h),~L(x),H(x)),(~S(x),P(x,y)),(~F(x),P(x,y)),(~F(x),L(x)),(~S(a)),(F(a)),(~H(a))}" | |
ResolutionFOL(KB0) | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB1) | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB2) | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB3) # 不是兄弟 | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB4) # John 偷东西 | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB5) # 小张是快乐的 | |
# 以下为单元归结策略 | |
def resolve_2(c1, c2): | |
list_c1keys = [sublist[0] for sublist in c1] | |
list_c2keys = [sublist[0] for sublist in c2] | |
c1key: str = list_c1keys[0] | |
idx_c1key = list_c1keys.index(c1key) | |
flag = c1key.startswith('~') | |
if flag: | |
complement = c1key[1:] | |
else: | |
complement = '~' + c1key | |
if complement in list_c2keys: | |
idx_complement = list_c2keys.index(complement) | |
mapdict = None | |
if c1[idx_c1key][1] != c2[idx_complement][1]: | |
result = MGU(c1[idx_c1key][1], c2[idx_complement][1]) | |
if result is None: | |
return None | |
else: | |
mapdict = result | |
if len(c1) > 1: | |
char1 = chr(ord('a') + idx_c1key) | |
else: | |
char1 = '0' | |
if len(c2) > 1: | |
char2 = chr(ord('a') + idx_complement) | |
else: | |
char2 = '0' | |
c2_to_del = list(c2) | |
del c2_to_del[idx_complement] | |
return c2_to_del, char1, char2, mapdict | |
return None | |
def resolution_2(KB: str): | |
clauses, resolution_steps = parse(KB) | |
singles = set() | |
for i in range(len(clauses)): | |
if len(clauses[i]) == 1: | |
singles.add(i) | |
while True: | |
l = len(clauses) | |
for i in range(len(clauses)): | |
if i not in singles: | |
continue | |
for j in range(len(clauses)): | |
if i == j: | |
continue | |
result = resolve_2(clauses[i], clauses[j]) | |
if result is None: | |
continue | |
resolvent = result[0] | |
if resolvent is None or resolvent in clauses: | |
continue | |
clauses.append(resolvent) | |
char1 = result[1] | |
char2 = result[2] | |
mapdict = result[3] | |
if char1 == '0' and char2 == '0': | |
pre_string = f"R[{i + 1},{j + 1}]" | |
elif char1 != '0' and char2 == '0': | |
pre_string = f"R[{i + 1}{char1},{j + 1}]" | |
elif char1 == '0' and char2 != '0': | |
pre_string = f"R[{i + 1},{j + 1}{char2}]" | |
else: | |
pre_string = f"R[{i + 1}{char1},{j + 1}{char2}]" | |
map_string = '' | |
if mapdict is not None: | |
pairs = [] | |
for key, value in mapdict.items(): | |
pairs.append(f"{key}={value}") | |
map_string = "{" + ",".join(pairs) + "}" | |
result_string = '' | |
for [key, value] in resolvent: | |
result_string += f'{key}({",".join(value)}),' | |
if len(resolvent) > 1: | |
result_string = result_string[:-1] | |
result_string = f'({result_string})' | |
resolution_steps.append(f"{len(resolution_steps) + 1} {pre_string}{map_string} = {result_string}") | |
if len(resolvent) == 0: | |
return resolution_steps | |
elif len(resolvent) == 1: | |
singles.add(len(clauses) - 1) | |
if l == len(clauses): | |
return None | |
def ResolutionFOL_2(KB): | |
result = resolution_2(KB) | |
if result is None: | |
print("Can't be resolved!") | |
else: | |
for step in result: | |
print(step) |
知识是经过加工的信息,它包括:
策略 —— 关于如何解决问题的政策方略,包括在什么时间、什么地点、由什么主体采取什么行动、达到什么目标、注意什么事项等等一整套完整而具体的行动计划规划、行动步骤、工作方式和工作方法
在给定的 问题 - 问题环境 - 主体目的 的条件下,智能就是有针对性地获取 问题 - 环境 的信息,恰当地对这些信息进行处理以提炼知识达到认知,在此基础上,把已有的知识与主体的目的信息相结合,合理地产生解决问题的策略信息,并利用所得到的策略信息在给定的环境下成功地解决问题达到主体的目的 (行为)。
省流:信息经加工提炼而成知识,知识被目的激活而成智能。
智能具有 4 个能力:
从语法和语义,可以给出使用该语言的 Agent 的必要的推理机制。
基于该推理机制,Agent 可以从已知的语句推导出结论,或判断某条信息是不是已蕴涵在现有的知识当中。
知识表示语言需要:
知识表示语言应该支持知识不完全的情况。不能表达这种不完全性的语言是表达能力不够的语言
程序设计语言比较善于描述算法和具体的数据结构
逻辑学 (logic) 是研究人类思维规律的科学,而现代逻辑学则是用数学 (符号化、公理化、形式化) 的方法来研究这些规律。
所谓符号化即是用 “一种只作整体认读的记号 (signs)”—— 符号 (symbols) 表示量、数及数量关系。也有用字母、符号表示思维的物理对象、概念对象、判断对象等。
语言化是符号化的初级阶段。
现代逻辑学对思维的研究,需要更加彻底的符号化过程。
欧氏几何公理系统中的所有概念都有鲜明的直观背景,其公理、定理也都有强烈的客观意义。像欧氏几何这样的公理系统,常被称为具体公理系统。
始于 Aristotle 的逻辑学被符号化、公理化,逐步演化为现代逻辑学。
所谓形式化,就是彻头彻尾的 “符号化 + 抽象公理化”
现代逻辑学形式系统组成:
以下讨论实际上均为二值逻辑
命题是具有真假意义的陈述句。
在特殊的情况下都具有 “真 (True)” 和 “假(False)” 的意义句子,都是命题。真值 —— 用 T 和 F 表示。
命题有两种类型:
命题逻辑就是研究命题和命题之间关系的符号逻辑系统。
命题逻辑的符号:
用 P、Q、R、S 等来表示命题。可分为:
因为命题变元可以表示任意命题,所以它不能确定真值,故命题变元不是命题。
复合命题的意义是命题组成成份的函数。
联结词的语义可以定义如下:
当命题变元 P 用一个特定的命题取代时,P 才能确定真值,这时也称为对命题变元 P 进行指派
设 G 是公式,A1, ... , An, 为 G 中出现的所有原子命题。公式 G 的一种指派是对 A1, ... , An 赋予的一组真值,其中每个 Ai (i=1 , ... , n) 或者为 T 或者为 F。
公式 G 称为在一种指派下为真,当且仅当 G 按该指派算出的真值为 T,否则称为在该指派下为假。
若在公式中有 n 个不同的原子 A1 , ... , An,那么该公式就有 个不同的指派。
公式 称为永真式或重言式 (tautology),如果对任意指派 α,α 均弄真 A,即 α(A)=T 。
公式 称为可满足的 (satisfiable), 如果存在指派 α 使 α(A)=T,否则称 为不可满足的 (unsatisfiable),或永假式。
永真式是可满足的
当 为永真式 (永假式) 时, 为永假式 (永真式)
称公式 逻辑蕴涵公式 B,记为 ,如果所有弄真 的指派亦必弄真公式 B
称公式集 逻辑蕴涵公式 B,记为 ,如果弄真 中所有公式的指派亦必弄真公式 B
称公式 逻辑等价公式 B,记为 ,如果 且
设 A 为含有命题变元 p 的永真式,那么将 A 中 p 的所有出现均代换为命题公式 B,所得公式 (称为 A 的代入实例) 仍为永真式。
设命题公式 含有子公式 C (C 为 A 中的符号串,且 C 为命题公式),如果 ,那么将 中子公式 C 的某些出现 (未必全部) 用 D 替换后所得公式 B 满足 。
命题公式 B 称为命题公式 的合取(或析取)范式,如果 ,且 B 呈如下形式:
其中 形如:
其中 为原子公式或原子公式的否定,并称 为文字。
【定理】
任一命题公式 φ 有其对应的合取 (析取) 范式。
命题公式 B 称为公式 A 的主合取 (或主析取) 范式,如果:
n 元命题公式的全体可以划分为 个等价类,每一类中的公式彼此逻辑等价,并等价于它们共同的主合取范式 (或主析取范式)。
为命题逻辑的合式公式
如果 A,B 是公式,那么这些也是命题逻辑的合式公式:
命题逻辑的形式系统 PC 包括 3 条公理模式 和 1 条推理规则(即分离规则):
称下列公式序列为公式 在 PC 中的一个证明 (proof):
其中
称 为 PC 中的定理,记为 ,如果公式 在 PC 中有一个证明。
( \vdash
) 断定符,表示可被推导出,可被证明
( \vDash
) 表示 永真
设 为一公式集,称以下公式序列为公式 的,以 为前提的演绎:
其中 满足:
称 为前提 的演绎结果,如果公式 有以 为前提的演绎。记为:
若 , 可以表示为:
若 , 则记为:
对应离散数学课程中的 “附加前提证明法”
对 PC 中任意公式集 和公式 :
PC 是可靠的,即对任意公式集 及公式 :
特别地,若 为 PC 的定理 ,则 永真 :
PC 是一致的 (consistent),即不存在公式 A,使得 与 均为 PC 之定理。
PC 是完全的,即对任意公式集 和公式 :
特别地,若 永真 ,A 必为 PC 的定理 :
谓词逻辑的语法元素表示如下。
一般一元谓词表达了个体的性质,而多元谓词表达了个体之间的关系
如果谓词 P 中的所有个体都是:
则该谓词为一阶谓词,如果某个个体本身又是一个一阶谓词,则称 为二阶谓词,以此类推递归定义 阶谓词
项可递归定义如下:
若 为 元谓词符号, 都是项,则称 为原子公式。在原子公式中,若 都不含变量,则 是命题。
给定公式集 进行合一,就是对 进行合一。
DEMO::
求证一个目标 时,利用归结反演:若子句集 是不可满足的,则可以使用归结规则由 产生空子句 NIL ,具体解题步骤:
谓词公式表示问题
(optional,定义常量)
定义谓词
将前提表示成谓词公式
规则:
......
事实
将要求证的问题表示成谓词公式
问题化为子句集
,
,
......
事实:
目标:(⚠️注意是 ⚠️)
得到 。
利用归结原理进行归结
对子句集进行归结时,一个关键问题是决定选取哪两个子句作归结,为此需要研究有效的归结控制策略。
假设原始子句 (包括待证明合式公式的否定的子句) 称为 层归结式。 层的归结式是一个 层归结式和一个 层归结式进行归结所得到的归结式。
宽度优先就是先生成第 层所有的归结式,然后是第 层所有的归结式,以此类推,直到产生空子句结束,或不能再进行归结为止。
深度优先是产生一个第 层的归结式,然后用第 层的归结式和第 层的归结式进行归结,得到第 层的归结式,直到产生空子句结束,否则,用第 层及其以下各层进行归结,产生第 层,以此类推。
单元优先 (unit preference) 策略,即在归结过程中优先考虑仅由一个文字构成的子句,这样的子句称为单元子句。
精确策略不涉及被归结子句的排序,它们只允许某些归结发生。
支持集 (set of support) 策略,实际是一种目标制导的反向推理
每次归结时,参与归结的子句中至少应有一个是:
所谓后裔是说,如果 是 与另外某子句的归结式,或者 是 的后裔与其他子句的归结式,则称 是 的后裔, 是 的祖先。
支持集策略是完备的,即假如对一个不可满足的子句集合运用支持集策略进行归结,那么最终会导出空子句。
线性输人 (linear input) 策略中参与归结的两个子句中至少有一个是原始子句集中的子句 (包括那些待证明的合式公式的否定)。
线性输人策略是高效的,但是不完备的,如子句集合 不可满足,但是无法用线性输入归结推出。
在归结过程中,除第一次归结都用给定的子句集中的子句外,其后每次归结则至少要有一个亲本子句是上次归结的结果。线性归结策略是完备的,高效的
由于线性输入策略是不完备的,改进该策略得到祖先过滤 (ancestry filtering) 策略,该策略是完备的而且是高效的。参与归结的两个子句中:
不完备但是高效,与单元优先的区别在于每次只考虑单元子句进行归结。
实际上是我的作业
已知:
用归结推理方法证明 Mary 不是 Tom 的兄弟
定义谓词:
问题用谓词公式表示:
再将问题化为子句集:
归结过程:
程序验证:
用谓词逻辑的子句集表示下述刑侦知识,并用反演归结的支持集策略证明结论。
(1) 用子句集表示下述知识。
(2) 求:John 可能会偷窃什么?
定义常量:
定义谓词:
用谓词逻辑的子句集表示:
这个 是我按照网上答案做的,实际上我觉得不需要这么麻烦,用 就可以了...
定义谓词 : 是所求问题的一个答案;
则问题 "John 可能会偷窃什么?" 可以表示为 也就是析取式:
所有可能的答案包括:
证明 问题,化为子句集:
支持集策略归结过程:
可证得:John 可能会偷酒(wine)和奶酪(cheese)
程序验证:
任何通过了历史考试并中了彩票的人都是快乐的。任何肯学习或幸运的人都可以通过所有考试,小张不学习,但很幸运,任何人只要是幸运的,就能中彩。
求证:小张是快乐的。
定义常量;
定义谓词:
用谓词公式表示问题:
求证目标为:
反演归结,将问题表示为子句集:
归结推理过程;
由此证得了:小张是快乐的。
程序验证:
实际上是我的作业
import queue | |
def parse(KB: str): | |
KB = KB.replace("{(", "").replace(")}", "") | |
items = KB.split("),(") | |
resolution_steps = map(lambda x: f'{items.index(x) + 1} ({x})', items) | |
clauses = [] | |
for item in items: | |
if item.endswith(')'): | |
item = item[:-1] | |
clause = [] | |
elements = item.split("),") | |
if elements[-1] == '': | |
elements.pop() | |
for i in range(len(elements)): | |
key, value = elements[i].split("(") | |
clause.append([key, value.split(',')]) | |
clauses.append(clause) | |
return clauses, list(resolution_steps) | |
def MGU(l1, l2): | |
variants = ('x', 'y', 'z', 'u', 'v', 'w', 'xx', 'yy', 'zz', 'uu', 'vv', 'ww') | |
dimension = len(l1) | |
mapdict = {} | |
for i in range(dimension): | |
if l1[i] in variants and l2[i] not in variants: | |
if mapdict.get(l1[i]) is None or mapdict[l1[i]] == l2[i]: | |
mapdict[l1[i]] = l2[i] | |
else: | |
return None | |
elif l1[i] not in variants and l2[i] in variants: | |
if mapdict.get(l2[i]) is None or mapdict[l2[i]] == l1[i]: | |
mapdict[l2[i]] = l1[i] | |
else: | |
return None | |
elif l1[i] not in variants and l2[i] not in variants and l1[i] != l2[i]: | |
return None | |
else: | |
if l1[i] != l2[i]: | |
mapdict[l1[i]] = l2[i] | |
return mapdict | |
# 以下是广度优先搜索策略 | |
def resolve(c1, c2): | |
list_c1keys = [sublist[0] for sublist in c1] | |
list_c2keys = [sublist[0] for sublist in c2] | |
for i in range(len(list_c1keys)): | |
c1key: str = list_c1keys[i] | |
idx_c1key = i | |
flag = c1key.startswith('~') | |
if flag: | |
complement = c1key[1:] | |
else: | |
complement = '~' + c1key | |
if complement in list_c2keys: | |
idx_complement = list_c2keys.index(complement) | |
mapdict = None | |
if c1[idx_c1key][1] != c2[idx_complement][1]: | |
result = MGU(c1[idx_c1key][1], c2[idx_complement][1]) | |
if result is None: | |
return None | |
else: | |
mapdict = result | |
if len(c1) > 1: | |
char1 = chr(ord('a') + idx_c1key) | |
else: | |
char1 = '0' | |
if len(c2) > 1: | |
char2 = chr(ord('a') + idx_complement) | |
else: | |
char2 = '0' | |
c1_to_del = list(c1) | |
c2_to_del = list(c2) | |
del c1_to_del[idx_c1key] | |
del c2_to_del[idx_complement] | |
c1_to_del.extend(c2_to_del) | |
return c1_to_del, char1, char2, mapdict | |
return None | |
def resolution(KB: str): | |
clauses, resolution_steps = parse(KB) | |
steps_idx = list(range(1, len(clauses) + 1)) | |
min_len = len(clauses) | |
while True: | |
l = len(clauses) | |
for i in range(len(clauses)): | |
for j in range(i + 1, len(clauses)): | |
if i == j: | |
continue | |
result = resolve(clauses[i], clauses[j]) | |
if result is None: | |
continue | |
resolvent = result[0] | |
if resolvent is None or resolvent in clauses: | |
continue | |
clauses.append(resolvent) | |
steps_idx.append([i, j]) | |
char1 = result[1] | |
char2 = result[2] | |
mapdict = result[3] | |
if char1 == '0' and char2 == '0': | |
pre_string = f"R[{i + 1},{j + 1}]" | |
elif char1 != '0' and char2 == '0': | |
pre_string = f"R[{i + 1}{char1},{j + 1}]" | |
elif char1 == '0' and char2 != '0': | |
pre_string = f"R[{i + 1},{j + 1}{char2}]" | |
else: | |
pre_string = f"R[{i + 1}{char1},{j + 1}{char2}]" | |
map_string = '' | |
if mapdict is not None: | |
pairs = [] | |
for key, value in mapdict.items(): | |
pairs.append(f"{key}={value}") | |
map_string = "{" + ",".join(pairs) + "}" | |
result_string = '' | |
for [key, value] in resolvent: | |
result_string += f'{key}({",".join(value)}),' | |
if len(resolvent) > 1: | |
result_string = result_string[:-1] | |
result_string = f'({result_string})' | |
resolution_steps.append(f"{len(resolution_steps) + 1} {pre_string}{map_string} = {result_string}") | |
if len(resolvent) == 0: | |
return resolution_steps, steps_idx, min_len | |
if l == len(clauses): | |
return None | |
def simplify_steps(steps, steps_idx, min_len): | |
q = queue.Queue() | |
not_del = [len(steps) - 1] | |
q.put(steps_idx[len(steps) - 1][0]) | |
q.put(steps_idx[len(steps) - 1][1]) | |
while not q.empty(): | |
i = q.get() | |
if i < min_len: | |
continue | |
not_del.append(i) | |
q.put(steps_idx[i][0]) | |
q.put(steps_idx[i][1]) | |
for i in range(len(steps) - 1, min_len - 1, -1): | |
if i not in not_del: | |
del steps[i] | |
num_map = dict() | |
for i in range(len(steps)): | |
num = (steps[i].split(' '))[0] | |
num_map[num] = f'{i+1}' | |
for t in list(num_map.keys()): | |
steps[i] = steps[i].replace(t, num_map[t]) | |
return steps | |
def ResolutionFOL(KB): | |
result = resolution(KB) | |
if result is None: | |
print("Can't be resolved!") | |
else: | |
(steps, steps_idx, min_len) = result | |
steps = simplify_steps(steps, steps_idx, min_len) | |
for step in steps: | |
print(step) | |
if __name__ == '__main__': | |
KB0 = "{(GradStudent(sue),),(~GradStudent(x),Student(x)),(~Student(x),HardWorker(x)),(~HardWorker(sue),)}" | |
KB1 = "{(A(tony),),(A(mike),),(A(john),),(L(tony,rain),),(L(tony,snow),),(~A(x),S(x),C(x)),(~C(y),~L(y,rain)),(L(z,snow),~S(z)),(~L(tony,u),~L(mike,u)),(L(tony,v),L(mike,v)),(~A(w),~C(w),S(w))}" | |
KB2 = "{(On(tony,mike),),(On(mike,john),),(Green(tony),),(~Green(john),),(~On(xx,yy),~Green(xx),Green(yy))}" | |
KB3 = "{(~B(x,y),~F(x)),(~S(x,y),F(x)),(S(Marry,Bill)),(B(Marry,Tom))}" | |
KB4 = "{(T(John),),(L(Paul,wine),),(L(Paul,cheese),),(~L(Paul,x),L(John,x)),(~T(x),~L(x,y),S(x,y)),(~S(John,z),ANSWER(z)),(~ANSWER(wine),~ANSWER(cheese))}" | |
KB5 = "{(~P(x,h),~L(x),H(x)),(~S(x),P(x,y)),(~F(x),P(x,y)),(~F(x),L(x)),(~S(a)),(F(a)),(~H(a))}" | |
ResolutionFOL(KB0) | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB1) | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB2) | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB3) # 不是兄弟 | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB4) # John 偷东西 | |
print("\x1B[31m--------------------\x1B[m") | |
ResolutionFOL(KB5) # 小张是快乐的 | |
# 以下为单元归结策略 | |
def resolve_2(c1, c2): | |
list_c1keys = [sublist[0] for sublist in c1] | |
list_c2keys = [sublist[0] for sublist in c2] | |
c1key: str = list_c1keys[0] | |
idx_c1key = list_c1keys.index(c1key) | |
flag = c1key.startswith('~') | |
if flag: | |
complement = c1key[1:] | |
else: | |
complement = '~' + c1key | |
if complement in list_c2keys: | |
idx_complement = list_c2keys.index(complement) | |
mapdict = None | |
if c1[idx_c1key][1] != c2[idx_complement][1]: | |
result = MGU(c1[idx_c1key][1], c2[idx_complement][1]) | |
if result is None: | |
return None | |
else: | |
mapdict = result | |
if len(c1) > 1: | |
char1 = chr(ord('a') + idx_c1key) | |
else: | |
char1 = '0' | |
if len(c2) > 1: | |
char2 = chr(ord('a') + idx_complement) | |
else: | |
char2 = '0' | |
c2_to_del = list(c2) | |
del c2_to_del[idx_complement] | |
return c2_to_del, char1, char2, mapdict | |
return None | |
def resolution_2(KB: str): | |
clauses, resolution_steps = parse(KB) | |
singles = set() | |
for i in range(len(clauses)): | |
if len(clauses[i]) == 1: | |
singles.add(i) | |
while True: | |
l = len(clauses) | |
for i in range(len(clauses)): | |
if i not in singles: | |
continue | |
for j in range(len(clauses)): | |
if i == j: | |
continue | |
result = resolve_2(clauses[i], clauses[j]) | |
if result is None: | |
continue | |
resolvent = result[0] | |
if resolvent is None or resolvent in clauses: | |
continue | |
clauses.append(resolvent) | |
char1 = result[1] | |
char2 = result[2] | |
mapdict = result[3] | |
if char1 == '0' and char2 == '0': | |
pre_string = f"R[{i + 1},{j + 1}]" | |
elif char1 != '0' and char2 == '0': | |
pre_string = f"R[{i + 1}{char1},{j + 1}]" | |
elif char1 == '0' and char2 != '0': | |
pre_string = f"R[{i + 1},{j + 1}{char2}]" | |
else: | |
pre_string = f"R[{i + 1}{char1},{j + 1}{char2}]" | |
map_string = '' | |
if mapdict is not None: | |
pairs = [] | |
for key, value in mapdict.items(): | |
pairs.append(f"{key}={value}") | |
map_string = "{" + ",".join(pairs) + "}" | |
result_string = '' | |
for [key, value] in resolvent: | |
result_string += f'{key}({",".join(value)}),' | |
if len(resolvent) > 1: | |
result_string = result_string[:-1] | |
result_string = f'({result_string})' | |
resolution_steps.append(f"{len(resolution_steps) + 1} {pre_string}{map_string} = {result_string}") | |
if len(resolvent) == 0: | |
return resolution_steps | |
elif len(resolvent) == 1: | |
singles.add(len(clauses) - 1) | |
if l == len(clauses): | |
return None | |
def ResolutionFOL_2(KB): | |
result = resolution_2(KB) | |
if result is None: | |
print("Can't be resolved!") | |
else: | |
for step in result: | |
print(step) |
给定 ,学习一个函数 能够根据输入 预测 ,其中 为数值,即回归。
给定 ,学习一个函数 能够根据输入 预测 ,其中 为类别,即分类。
给定 (无标签), 是多维的,每一维对应一个属性,输出 的隐变量
独立分量分析(ICA):一种用于分离混合信号中不同独立源的方法
e g :
输入一组包括状态、动作、延迟奖励的序列,输出一个策略
策略是一个从状态到行动的映射函数,表明每个状态下所采取的行动或行动的分布
e g :
现如今已有数以万计的机器学习算法,每年仍有数百种新方法。万变不离其宗,每种机器学习都由以下三部分组成:
线性回归
神经网络
支持向量机
决策树
命题逻辑中的规则
一阶谓语逻辑中的规则
最近邻
基于案例求解
朴素贝叶斯
贝叶斯网络
隐性马尔可夫模型(HMMs)
概率上下文自由语法(PCFGs)
马尔可夫网络
感知机
反向传播算法
HMM 学习
PCFG 学习
决策树归纳法
规则学习
遗传算法(GA)
遗传编程(GP)
神经进化算法
准确率
精度和召回率
均方误差
先验概率
后验概率
成本 / 效率
边际效用
熵
KL 散度
......
机器学习可以被看作是利用直接或间接的经验来逼近一个选定的目标函数。
函数近似可以看作是在假定的空间(函数的表征)中寻找最适合一组参数。
不同的学习方法设定不同的假定空间(表征语言)和 / 或 采用不同的搜索技术
机器学习的开发流程:
机器学习首先要考虑使用什么样的模型,直观理解就是使用什么分布函数拟合数据。
模型的类别,大致有两种:
根据上述损失函数模型,我们可知,损失函数值越小,模型性能越好。给定一个数据集,我们将训练数据集的平均损失称为经验风险。
基于经验风险最小化原则,可构建全局损失函数求解最优化问题:
当样本数量足够大时,根据大数定理,经验风险会近似于模型的期望风险。此时,经验风险最小化能确保有好的学习性能。
然而,当样本数量不足时,单单利用经验风险最小化可能会导致 “过拟合” 的问题。为此,我们在原有基础上加上用于控制模型复杂度的正则项 (Regularizer),得到结构最小化准则。
定义了损失函数计算 loss 之后,问题就转化为了求 loss 最小化的问题;如何使得 loss 最小化?就需要使用优化算法。
算法指的是模型学习中的具体计算方法。
一般来说,基于参数模型构建的统计学习问题都为最优化问题,它们都具有显式的解析解。
现有的优化方法主要有:
和 分别表示第 个样本的真实值和预测值, 为样本个数
均方误差 (Mean Square Error, MSE)
均方根误差 (Root Mean Square Error, RMSE)
平均绝对误差 (Mean Absolute Error, MAE)
线性回归(Linear Regression)
是一种通过属性的线性组合来进行预测的线性模型,其目的是找到一条直线或者一个平面或者更高维的超平面,使得预测值与真实值之间的误差最小化。
为随机梯度下降 (SGD, Stochastic Gradient Descent)
为批量梯度下降 (BGD, Batch Gradient Descent)
为小批量梯度下降 (MBGD, Mini-Batch Gradient Descent)
归一化
数据归一化的目的是使得各特征对目标变量的影响一致,会将特征数据进行伸缩变化,所以数据归一化是会改变特征数据分布的
将数据映射到 区间
Z-Score
数据标准化为了不同特征之间具备可比性,经过标准化变换之后的特征数据分布没有发生改变。
就是当数据特征取值范围或单位差异较大时,最好是做一下标准化处理
处理后的数据均值为 0,方差为 1
交叉验证 Cross Validation
最常见的缓解过拟合问题的方法,将数据集分为训练用的和测试用的两份数据集(大多是 训练:测试 = 9:1 )
多重交叉验证 N-fold Cross Validation
迁移学习
使用更多的训练数据是解决过拟合问题最有效的手段,因为更多的样本能够让模型学习到更多更有效的特征,减小噪声的影响
即丢弃一些不能帮助我们正确预测的特征。可以是手工选择保留哪些特征,或者使用一些模型选择的算法来帮忙(例如 PCA)。
正则化 (regularization) 的技术,保留所有的特征,但是减少参数的大小(magnitude),它可以改善或者减少过拟合问题。
集成学习是把多个模型集成在一起,来降低单一模型的过拟合风险。
当特征不足或者现有特征与样本标签的相关性不强时,模型容易出现欠拟合。通过挖掘组合特征等新的特征,往往能够取得更好的效果。
简单模型的学习能力较差,通过增加模型的复杂度可以使模型拥有更强的拟合能力。例如,在线性模型中添加高次项,在神经网络模型中增加网络层数或神经元个数等。
正则化是用来防止过拟合的,但当模型出现欠拟合现象时,则需要有针对性地减小正则化系数。
分类问题和回归问题有一定的相似性,都是通过对数据集的学习来对未知结果进行预测,区别在于输出值不同。
在回归问题的基础上,对预测结果值进行量化,即将连续值量化为离散值,就能解决分类问题。
逻辑回归是线性回归的一种扩展,用来处理分类问题。
常用的逻辑函数 Sigmoid 及其导函数:
损失函数:
梯度为:
梯度下降更新参数 :
支持向量机,Support Vector Machines,SVM
只考 K-means
K-means 算法是一种无监督学习方法,是最普及的聚类算法,算法使用一个没有标签的数据集,然后将数据聚类成不同的组。
初试化簇质心为的任意点( 个)。初试化时,必须注意簇的质心必须小于训练数据点的数目。
遍历所有数据点,计算所有质心与数据点的距离。这些簇将根据质心的最小距离而形成。
移动质心,因为上面步骤中形成的簇没有优化,所以需要形成优化的簇。为此需要迭代地将质心移动到一个新位置。取一个簇的数据点,计算平均值,然后将簇的质心移动到这个新位置。所有簇重复相同的步骤。
重复上述步骤,直至收敛。
优点
原理简单,实现容易,收敛速度快
聚类效果较优
算法的可解释度比较强
主要需要调参的参数仅仅时簇数 K
缺点
需要预先指定簇的数量
如果有两个高度重叠的数据,那么它就无法区分,也不能判断有两个簇
欧几里得距离限制了能处理的数据变量类型
随机选择质心并不能带来理想的结果
无法处理异常值和噪声数据
不适用于非线性数据
对特征尺度敏感
如果遇到非常大的数据集,那么计算机可能回崩溃
决策树基于 “树” 结构进行决策
学习过程:通过对训练样本的分析来确定 “划分属性”(即内部结点所对应的属性 )
预测过程:将测试示例从根结点开始沿着划分属性所构成的 “判定测试序列” 下行,直到叶结点
策略:“分而治之”( divide-and-conquer)
自根至叶的递归过程在每个中间结点寻找一个 “划分”( split or test) 属性。
三种停止条件
输入:
过程:
TreeGenerate(D,A)
输出:
生成结点 node; | |
if D 中样本全属于同一类别 C then: | |
将 node 标记为 C 类叶结点; | |
return; | |
end if; | |
if A is not None or D 中样本在 A 上取值相同 then: | |
将 node 标记为叶结点,其类别标记为 D 中样本数最多的类; # 利用当前结点的后验分布 | |
return; | |
end if; | |
从 A 中选择最优划分属性 a ; | |
for a 的每一个值 a(i) do | |
为 node 生成一个分支; | |
令 D(i) 表示 D 中在 a 上取值为 a(i) 的样本子集; | |
if D(i) is None then: | |
将分支结点标记为叶结点,其类别标记为 D 中样本最多的类; # 将父结点的样本分布作为当前结点的先验分布 | |
return; | |
else: | |
以 TreeGenerate(D(i), A\{a}) 为分支结点 | |
end if; | |
end for; |
(ID3 算法)
一个离散属性 的取值:;
的信息熵定义为
的值越小,则 的纯度越高
以属性 对数据集 进行划分, 为 在 上取值为 的样本集合,获得属性 的信息增益为:
其中:
满足以下性质
(C4.5 算法)
信息增益对可取值数目较多的属性有所偏好,有明显弱点,例如考虑将 “编号” 作为一个属性。所以引入增益率:
其中:
属性 a 的可能取值数目越多 (即 V 越大),则 IV (a) 的值通常就越大
启发式:先从候选划分属性中找出信息增益高于平均水平的,再从中选取增益率最高的。
(CART 算法)
样本集(数据集) 的基尼系数定义如下:
反映了从 D 中随机抽取两个样例,其类别标记不一致的概率。
样本集(数据集) 的属性 的基尼系数定义如下:
建立决策树时,在候选属性集合中,选取那个使划分后基尼指数最小的属性。
为了尽可能正确分类训练样本,有可能造成分支过多,也就是决策树的过拟合问题,可通过主动去掉一些分支来降低过拟合的风险
基本策略 :
预剪枝 (pre-pruning) : 提前终止某些分支的生长
在构造决策树的过程中,先对每个结点在划分前进行估计,如果当前结点的划分不能带来决策树模型泛化性能的提升,则不对当前结点进行划分并且将当前结点标记为叶结点。(泛化性能可根据在测试集上的准确率衡量)
后剪枝 (post-pruning) : 生成一棵完全树,再 “回头” 剪枝
先把整颗决策树构造完毕,然后自底向上的对非叶结点进行考察,若将该结点对应的子树换为叶结点能够带来泛化性能的提升,则把该子树替换为叶结点。
泛化性能:后剪枝通常优于预剪枝
剪枝过程中需评估剪枝前后决策树的优劣
推荐阅读 https://blog.csdn.net/u012328159/article/details/79285214