人工智能一种现代化学习方法——学习笔记(13章)

第13章——不确定的量化

人工智能一种现代化的学习方法(第3版)学习笔记。

  • 13.1不确定环境下的行动
  • 13.2基本概率符号
  • 13.3使用完全联合分布进行推理
  • 13.4独立性
  • 13.5贝叶斯规则及其应用
  • 13.6重游Wumpus世界
  • 13.7本章小结
  • 文献与历史注释

13.1不确定环境下的行动

决策理论 = 概率理论 + 效用理论
决策理论基本思想:
一个Agent是理性的,当且仅当它选择能产生最高期望效用的行动,这里的期望效用是行动的所有可能结果的平均。这成为期望效用最大化(Maximum Expected Utility, MEU)。

先验概率(无条件概率)
是指根据以往经验和分析得到的概率,如全概率公式,它往往作为”由因求果”问题中的”因”出现的概率·
后验概率(条件概率)
基于新的信息,修正原来的先验概率后所获得的更接近实际情况的概率估计。
条件概率

13.2.2概率断言中的命题语言

随机变量
变量的名字以大写字母开头,比如投掷两个一样的骰子,他们的点数之和Total就是随机变量。Total的定义域是{2,…,12};一个布尔变量的定义域是{true,false}(变量的值总是小写)。
例:
“如果患者是一个没有牙痛的青少年,那么他有牙洞的概率是0.1” => P(cavity|?toothache^teen)=0.1

13.3使用完全联合分布进行推理

例:
三个布尔变量
- Toothache,牙痛
- Cavity,牙洞
- Catch,牙医的钢探针不洁导致牙龈感染
对应的完全联合分布2x2x2的表格:
这里写图片描述
(1)将使命题为真的概率相加
P(cavity∨toothache)=0.108+0.012+0.072+0.008+0.016+0.064=0.28(∨是逻辑或)
(2)无条件概率(边缘概率)
P(cavity)=0.108+0.012+0.072+0.008=0.2

13.4独立性

计算,P(toothace,catch,cavity,cloudy)=P(cloudy|toothace,catch,cavity)P(toothace,catch,cavity)
因为cloudy与toothace,catch,cavity互相独立,
所以,P(cloudy|toothace,catch,cavity)=P(cloudy)
所以,P(toothace,catch,cavity,cloudy)=P(cloudy) P(toothace,catch,cavity)
这里写图片描述

13.5贝叶斯规则及其应用

常用形式:
这里写图片描述
通用形式:
这里写图片描述
例:
医生知道脑膜炎会引起病人脖子僵硬,比如有70%的机会。医生还了解一些无条件事实:病人患脑膜炎的先验概率是1/50000,而任何一个脖子僵硬的先验概率为1%,令s表示“病人脖子僵硬”的命题,m表示“病人患有脑膜炎”的命题,则有
这里写图片描述
也就是说,我们期望700个有脖子僵硬症状的病人中只有不到1个人患有脑膜炎。注意,尽管脑膜炎相当强烈地预示着会有脖子僵硬的症状(概率为0.7),但脖子僵硬的病人患有脑膜炎的 概率依然很低。这是因为脖子僵硬的先验概率大大高于患脑膜炎的先验概率。
朴素贝叶斯:
参考算法杂货铺——分类算法之朴素贝叶斯分类(Naive Bayesian classification)
这里写图片描述

例:
实验内容
利用贝叶斯算法或者决策树算法进行数据分类操作
数据集:汽车评估数据集(见附录CarDatas.txt)
实验步骤
1.仔细阅读并了解实验数据集;
2.使用任何一种熟悉的计算机语言(比如C,Java或者matlab)实现朴素贝叶斯算法或者决策树算法;
3.利用朴素贝叶斯算法或者决策树算法在训练数据上学习分类器,训练数据的大小分别设置为:前100个数据,前200个数据,前500个数据,前700个数据,前1000个数据,前1350个数据;
4.利用测试数据对学习的分类器进行性能评估;
5.统计分析实验结果并上交实验报告;
实验思路:
这里写图片描述

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<fstream>
#include<stdio.h>
using namespace std;

int countTrain = 0;//训练样本数目
int countTest = 0;//测试样本数目
int countTestSuc = 0;//测试样本正确的数目
int countF=100; //训练和测试的分界 

string CVname[4]={"unacc","acc","good","vgood"};
int ClassValues[4];  //unacc, acc, good, vgood 
int buying[4][4];       //vhigh, high, med, low.
int maint[4][4];        // vhigh, high, med, low. 
int doors[4][4];        //2, 3, 4, 5more. 
int persons[4][4];      //2, 4, more. 
int lug_boot[4][4];     //small, med, big.
int safety[4][4];       //low, med, high. 

float ClassValuesL[4];  //unacc, acc, good, vgood 
float buyingL[4][4];       //vhigh, high, med, low.
float maintL[4][4];        // vhigh, high, med, low. 
float doorsL[4][4];        //2, 3, 4, 5more. 
float personsL[4][4];      //2, 4, more. 
float lug_bootL[4][4];     //small, med, big.
float safetyL[4][4];       //low, med, high. 

//统计个数 
void Tonji(string a,string b,string c,string d,string e,string f,string g){
//cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<" "<<f<<" "<<g<<endl;
for(int i=0;i<4;i++)
    if(g==CVname[i]){
        ClassValues[i]++;
            //buying: vhigh, high, med, low.
            if(a=="vhigh") buying[0][i]++;
            else if(a=="high") buying[1][i]++;
            else if(a=="med") buying[2][i]++;
            else if(a=="low") buying[3][i]++;
            //maint: vhigh, high, med, low. 
            if(b=="vhigh") maint[0][i]++;
            else if(b=="high") maint[1][i]++;
            else if(b=="med") maint[2][i]++;
            else if(b=="low") maint[3][i]++;
            //doors: 2, 3, 4, 5more.
            if(c=="2") doors[0][i]++;
            else if(c=="3") doors[1][i]++;
            else if(c=="4") doors[2][i]++;
            else  doors[3][i]++;
            //persons: 2, 4, more. 
            if(d=="2") persons[0][i]++;
            else if(d=="4") persons[1][i]++;
            else persons[2][i]++;
            //lug_boot: small, med, big.
            if(e=="small") lug_boot[0][i]++;
            else if(e=="med") lug_boot[1][i]++;
            else if(e=="big") lug_boot[2][i]++;
            //safety: low, med, high. 
            if(f=="low") safety[0][i]++;
            else if(f=="med") safety[1][i]++;
            else if(f=="high") safety[2][i]++;
            break;
    }
}
//读取文件 
void ReadFileTrain(){
    ifstream fin("CarDatas.txt");
    string a,b,c,d,e,f,g;
    int i = countF;
    while((i--)>0 && fin>>a && fin>>b&& fin>>c && fin>>d && fin>>e && fin>>f && fin>>g){
        countTrain++;
        Tonji(a,b,c,d,e,f,g); 
    }
    fin.close();
    cout<<"训练样本countTrain="<<countTrain<<endl;
}
//统计得到在各类别下各个特征属性的条件概率估计
void CalAP(){ //概率P(yi)
    for(int i=0;i<4;i++){
        ClassValuesL[i] = (float) ClassValues[i]/countTrain;
    }
    //特别注意的是P(ai|yi)=ai/0的情况!!!,会使 P(ai|yi)等于nan; 
    for(int i=0;i<4;i++){ //概率P(ai|yi)  
        for(int j=0;j<4;j++){
            buyingL[i][j] = (float) buying[i][j]/ClassValues[j]; if(buyingL[i][j]<0 || buyingL[i][j]>1) buyingL[i][j]=0;
            maintL[i][j] = (float) maint[i][j]/ClassValues[j];   if(maintL[i][j]<0 || maintL[i][j]>1) maintL[i][j]=0;
            doorsL[i][j] = (float) doors[i][j]/ClassValues[j];   if(doorsL[i][j]<0 || doorsL[i][j]>1) doorsL[i][j]=0;
        }
    }
    for(int i=0;i<3;i++){ //概率P(ai|yi)
        for(int j=0;j<4;j++){
            personsL[i][j] = (float) persons[i][j]/ClassValues[j];    if(personsL[i][j]<0 || personsL[i][j]>1) personsL[i][j]=0;
            lug_bootL[i][j] = (float) lug_boot[i][j]/ClassValues[j];  if(lug_bootL[i][j]<0 || lug_bootL[i][j]>1) lug_bootL[i][j]=0;
            safetyL[i][j] = (float) safety[i][j]/ClassValues[j];      if(safetyL[i][j]<0 || safetyL[i][j]>1) safetyL[i][j]=0;
        }
    }
}
//一行数据的准确与否,P(Bi|A)=P(A|Bi)P(Bi)/P(A),其中P(A)相同,只需比较分子的大小即可 
bool TestLine(string ai,string bi,string ci,string di,string ei,string fi,string gi){
        int b, m, d, p, l, s;
        //buying:
        if(ai=="vhigh") b=0;
        else if(ai=="high") b=1;
        else if(ai=="med") b=2;
        else if(ai=="low") b=3;
        //maint:
        if(bi=="vhigh") m=0;
        else if(bi=="high") m=1;
        else if(bi=="med") m=2;
        else if(bi=="low") m=3;
        //doors:
        if(ci=="2") d=0;
        else if(ci=="3") d=1;
        else if(ci=="4") d=2;
        else  d=3;
        //persons:
        if(di=="2") p=0;
        else if(di=="4") p=1;
        else p=2;
        //lug_boot:
        if(ei=="small") l=0;
        else if(ei=="med") l=1;
        else if(ei=="big") l=2;
        //safety: 
        if(fi=="low") s=0;
        else if(fi=="med") s=1;
        else if(fi=="high") s=2;

        float Bi; 
        float MaxB=0;
        int t=0;
        //计算四个P(Bi|A)的概率取最大的 
        for(int i=0;i<4;i++){
            Bi=buyingL[b][i] * maintL[m][i] * doorsL[d][i] * personsL[p][i] * lug_bootL[l][i] * safetyL[s][i] * ClassValuesL[i];

            if(MaxB < Bi && Bi<=1){
                MaxB = Bi;
                t = i;
            }
        }
        //判断预测和事实是否相等 
        if(CVname[t]==gi) return true;
        else return false;
} 
//读取并测试文件 
void ReadFileTest(){
    ifstream fin("CarDatas.txt");
    string a,b,c,d,e,f,g;
    bool t=false;
    int i=0;
    while(++i && fin>>a && fin>>b&& fin>>c && fin>>d && fin>>e && fin>>f && fin>>g){
        if(i>countF){ 
            countTest++;
            t=TestLine(a,b,c,d,e,f,g); 
            if(t) countTestSuc++; 
        }
    }
    fin.close();
}
void setZero();
int main(){
    int a[5]={100,200,500,700,1350};
    for(int i=0;i<5;i++){
        setZero();
        countF=a[i];       //训练和测试的分界 
        ReadFileTrain();  //读取文件并且统计个数
        CalAP();          //计算条件概率 
        ReadFileTest();   //测试样本 
        cout<<"预测正确countTestSuc="<<countTestSuc<<endl;
        cout<<"测试样本countTest="<<countTest<<endl;
        cout<<"准确率为:"<<100.0*((float)countTestSuc/(float)countTest)<<"%"<<endl<<endl;
    }
    return 0;
} 
//重新赋值为零
void setZero(){
    countTrain = 0;//训练样本数目
    countTest = 0;//测试样本数目
    countTestSuc = 0;//测试样本正确的数目
    for(int i=0;i<4;i++)
    for(int j=0;j<4;j++){
        ClassValues[i]=0;  //unacc, acc, good, vgood 
        buying[i][j]=0;       //vhigh, high, med, low.
        maint[i][j]=0;        // vhigh, high, med, low. 
        doors[i][j]=0;        //2, 3, 4, 5more. 
        persons[i][j]=0;      //2, 4, more. 
        lug_boot[i][j]=0;     //small, med, big.
        safety[i][j]=0;       //low, med, high. 

        ClassValuesL[i]=0;  //unacc, acc, good, vgood 
        buyingL[i][j]=0;       //vhigh, high, med, low.
        maintL[i][j]=0;        // vhigh, high, med, low. 
        doorsL[i][j]=0;        //2, 3, 4, 5more. 
        personsL[i][j]=0;      //2, 4, more. 
        lug_bootL[i][j]=0;     //small, med, big.
         safetyL[i][j]=0;       //low, med, high. 
    }
}

实验结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值