基于Python的行为决策程序(双效原则)

基于Python的行为决策程序

  • 前言
    • 1、双效原则的简单介绍
    • 2、行为识别的设计
    • 3、行为判断的设计
    • 4、行为决策的设计
    • 5、代码展示与运行说明
  • 后记

前言

笔者在了解到双效原则之后,发现这是一个“强原则”。所谓“强原则”,是因为它不仅要求程序正义、结果正义,甚至还要求目标正义。在这样的要求下,即使把决策交给机器人来做,也有很强的可靠性。以下是这篇文章的链接:

电车难题:为道德直觉提供理论证成
https://www.bilibili.com/read/cv6181552

文中应用双效原则对于著名哲学问题——电车难题的深入分析与讨论启发了我,加之双效原则本身具有很强的程序性,如果用代码实现出来,再配合一些数据统计,就可以实现一个行为决策程序。

在经过一些假设与设计之后,用Python成功模拟了一次行为识别、行为判断以及行为决策的过程。但是此次实验并非技术篇,只是记录一次想法。

1、双效原则的简单介绍

以下摘自文章原句,感兴趣的也可以直接去阅读原文。

双效原则(principle of double effect)是由神学家、自然法思想家托马斯·阿奎纳提出的,他认为,同一个行为提出兼具善的和恶的两种效果。而在某些情况下,一个同时具备善恶两种结果的行为是可以被允许的。
双效原则试图确定的是:在什么情况下,那些既可以产生正面效果又可以导致负面效果的行为在道德上是允许的。这样的被允许的行为需要满足四个要件:
①.这个行为本身的性质是善的,至少是中立的。我称之为客观要件;
②.行为人的目的是为了追求善果,不能主观希望恶果的发生,但是可以对恶果采取容认的态度。如果行为人有途径能避免恶果而造成善果,行为人一定会这样做。我称之为主观要件;
③善的结果是由行为直接造成的,而不是通过恶果间接造成。善果和行为本身之间的直接程度要不低于善果和恶果之间的直接程度。我称之为因果关系;
④.善的结果超过恶的结果。也就是说善果能够弥补恶果造成的损失。我称之为结果要件。
以上四个要件之间没有位阶之分,缺一不可,至于构成了四个要件才会产生“能对行为作出正面的评价”的效果。

2、行为识别的设计

着手开始写程序,首先直面的一个问题就是:怎么在代码里表述一个行为?为了适配双效原则,我们可以把一个行为表示为:一个包含主角,目标,行为,好结果和坏结果的5元数组。

# 5元数组 [role, purpose, action, good result, bad result]
# 例如:张三为了调整心态,于是听起了音乐,这样会使他得到放松,但也会占用他的时间。
info = ['张三', '调整心态', '听音乐', '得到放松', '占用时间']

在以上实例中,张三到底该不该听音乐呢?我们的行为决策也由此展开。

注意:规定这5个元素有严格的顺序,即:

info[0] = role
info[1] = purpose
info[2] = action
info[3] = good result
info[4] = bad result

这样一来,我们对双效原则的四个要件进行判断就有了对象:

1、对info[1] 讨论目标的正当性
2、对info[2] 讨论行为的正当性
3、对info[3],info[4] 讨论好结果和结果的程度
4、只有当行为是直接而非间接造成结果才能放到所定义的数组中,也就是说,四个要件中的行为直接性要先天成立,我们才能继续讨论行为的目标、行为本身以及行为的结果,否则不在讨论的范畴。

3、行为判断的设计

当我们将一组行为输入的时候,程序要展开对此行为的解析或识别,分析是目标是否正当、行为本身是否正当,比较结果好坏程度。为此,我定义了一组数据结构来进行处理。
以一个基本的事件Event作为父类,有两个成员变量为name和isTrue,意为事件的名称和正当性。此外还配有一个成员函数speak,以检验输出。其下有目的和行为两个子类。

# 父类:事件
class Event:def __init__(self,n,tf):self.name = nself.isTrue = tfdef speak(self):print("%s is %s." %(self.name,self.isTrue))

目的Purpose类继承了事件Event类所有的变量和函数,再添加一个change函数,模拟在判断过程中行为目标发生改变的情况。

# 子类:目的
class Purpose(Event):def change(self,new_tf):self.isTrue = new_tf

行为Action类也继承了事件Event类所有的变量和函数,但这还远远不够,先要添加两个变量:好结果good_result和坏结果bad_result,同时还有一个关键函数compare,其主要是对行为产生的两个结果进行判断:如果好结果超过坏结果,就返回True;否则返回False,同时对speak函数进行改写,输出一些提醒信息。
在这个数据结构中,函数compare调用了另外一个函数GetPriority来进行判断,这是为了保持该类本身的简洁性,Getpriority在下一部分中实现。

# 子类:行为
class Action(Event):def __init__(self, n, tf, gre,bre):Event.__init__(self, n, tf)self.good_result = greself.bad_result = bredef compare(self):priority = GetPriority(self.good_result,self.bad_result)if priority == 1:return Trueelse:return Falsedef speak(self):print("%s is %s. \nGood result is %s, Bad result is %s."%(self.name,self.isTrue,self.good_result,self.bad_result))if self.compare() is True:print("The good result is better than the bad result.")else:print("The bad result may destroy you!")

受此影响,为了方便处理,或以备后续使用,我们也给输入的行为定义一个对应的People类,读入5元组,调用speak函数,会输出一个还原的人物情境。

# 人物情境
class People:def __init__(self, str):self.role = str[0]self.purpose = str[1]self.action = str[2]self.good_result = str[3]self.bad_result = str[4]def speak(self):print("%s想要%s,通过%s的方式,这样可以%s,但是会%s。"%(self.role,self.purpose,self.action,self.good_result,self.bad_result))

例如

    info = ['张三', '调整心态', '听音乐', '得到放松', '占用时间']# 实例化人物情境robot = People(info)robot.speak()# 输出张三想要调整心态,通过听音乐的方式,这样可以得到放松,但是会占用时间。

4、行为决策的设计

所以程序要怎么帮人做决策的呢?换句话说我们要怎么为机器注入思考的能力?在无法开发出学习算法之前,说白了,只能通过数据统计,依靠强大的数据库做出决策。顺便说一句,所有统计来的数据也是不失一般性的人类经验,在这个意义上,说机器人是人类智能的延伸一点没错,这很马克思。

言归正传,也可能被猜到我要怎么做了。要对行为和目标进行情感判断或道德判断,它是好,是坏,或是中立的。就需要一个文本库,它提前记录了所要进行判断的词条,与其对应的性质,就像一本辞典记录了该词是褒义词、贬义词或是中性词。为了测试实验结果,我建立了如下的简易文本库(这里把目标和行为都放到一起了,当然也可以分开存储):

Standard.txt听音乐 neutral
打游戏 neutral
调整心态 good
放松 good
放纵 bad
逃避现实 bad
谈恋爱 good
学会照顾 good
骗吃骗喝 bad
...

以下做一些说明:“听音乐”、“打游戏”这类词汇属于中立的,“放松”属于好的,但“放纵”就属于不好的。
依此进行解读。(再次声明,本人定义的词库不具有一般性,但如果在大量调查统计下得出的词库,就不失一般性。)

定义一个读取词库的函数GetJudge,从该文件中返回一个字典:

# 获取判断标准
def GetJudge(filepath='Standard.txt'):judge = {}fr = open(filepath, "r", encoding='utf-8')lines = fr.readlines()for line in lines:line = line.strip('\n')line = line.split(' ')judge[line[0]]=line[1]return judge
# 输出
{'听音乐': 'neutral', '打游戏': 'neutral', '调整心态': 'good', '放松': 'good', '放纵': 'bad', '逃避现实': 'bad', '谈恋爱': 'good', '学会照顾': 'good', '骗吃骗喝': 'bad'}

以上仅仅解决了对目的和行为的判断,对好结果和坏结果之间还需要有一个比较,同样的思路,我们需要一个对大量事件结果进行对比的文件,其中包含了我们道德判断、情感判断,可以将其定义为这样:

Result占用时间考试挂科身心俱疲
得到放松1-1-1
开小差-1-1-1
得到照顾1-1-1

说明:竖列表示好结果good result,横行表示坏结果bad result。如果good result的程度超过bad result,就填1,否则就是-1。例如:

得到放松,占用时间 ——> 1,说明花一点时间休息是值得的,可能尽管学习很紧张。
得到放松,考试挂科 ——> -1,说明考试实在太紧迫,已经容不得休息。
开小差,占用时间 ——> -1,说明花时间去开小差很不值得。

(依旧声明:该判断只是我的个人判断,不具有一般性。比如谈恋爱会得到照顾,但是可能会考试挂科或者谈得身心俱疲,如果你认为这是值得的,也可以把这一整列全改为1,表示爱情大于天。)

定义一个函数GetPriority把对应的结果读到程序中:

# 获取比较
def GetPriority(gre,bre,filepath='judge.xlsx'):record_i = 0record_j = 0data = xlrd.open_workbook(filepath)table = data.sheet_by_index(0)for i in range(3):if fuzz.ratio(gre,table.cell_value(i, 0)) > 50:record_i = ifor j in range(3):if fuzz.ratio(bre,table.cell_value(0, j)) > 50:record_j = jreturn table.cell_value(record_i, record_j)

这里我采用了一个模糊匹配的方法,意在说明我们从语境中获取的关键词汇,并不是每次都能严丝合缝地与我们定义的文本库中(无论是有关目的、行为的文本库还是有关结果比较的文本库)的词汇相匹配。因此,我们采取一个中文模糊匹配的方法:当两个词汇的相同部分超过50%的时候,即认为这两个词汇描述的是同一个目的、同一个行为、同一个结果。

5、代码展示与运行说明

以上,我们可以对程序的结果进行检测:

if __name__ == '__main__':# info = [role, purpose, action, good result, bad result]info = ['张三', '调整心态', '听音乐', '得到放松', '占用时间']# 实例化人物情境robot = People(info)robot.speak()print("*************************************************")# 获取判断标准judge = GetJudge()# 根据标准实例化目的和行为if robot.purpose in judge.keys():# 实例化目的p = Purpose(robot.purpose,judge[robot.purpose])p.speak()if robot.action in judge.keys():# 实例化行为 a = Action(robot.action,judge[robot.action],robot.good_result,robot.bad_result)a.speak()print("*************************************************")# 检验是否满足双效原则:目的是正当的;行为起码是中立的,结果是正当的。if p.isTrue == 'good' and a.isTrue != 'bad' and a.compare() == True:print('Yes!')else:print('No!!!')

调用的函数库:

import xlrd
import fuzzywuzzy.fuzz as fuzz

案例1

# 输入
info1 = ['张三', '调整心态', '听音乐', '得到放松', '占用时间']
# 输出
张三想要调整心态,通过听音乐的方式,这样可以得到放松,但是会占用时间。
*************************************************
调整心态 is good.
听音乐 is neutral. 
Good result is 得到放松, Bad result is 占用时间.
The good result is better than the bad result.
*************************************************
Yes!

案例2

# 输入
info2 = ['张三', '放纵', '听音乐', '得到放松', '占用时间']
# 输出
张三想要放纵,通过听音乐的方式,这样可以得到放松,但是会占用时间。
*************************************************
放纵 is bad.
听音乐 is neutral. 
Good result is 得到放松, Bad result is 占用时间.
The good result is better than the bad result.
*************************************************
No!!!

案例3

# 输入
info3 = ['张三', '调整心态', '听音乐', '得到放松', '考试挂科']
# 输出
张三想要调整心态,通过听音乐的方式,这样可以得到放松,但是会考试挂科。
*************************************************
调整心态 is good.
听音乐 is neutral. 
Good result is 得到放松, Bad result is 考试挂科.
The bad result may destroy you!
*************************************************
No!!!

后记

如果在进行大量的社会研究之后可以将上述我设计的两个文件生成出来,那么以此为基础的决策程序应当就有很强的可使用性。当然,如果要让它自己学习自我纠错,那么如何设计学习算法和纠错算法这又是另外大得多的学问。

另外:本次实验并没有讨论如何通过中文信息处理得到这样的5元组,即[role, purpose, action, good result, bad result],这一部分有待补充。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部