《机器学习 - 周志华》第一章绪论 总结 + 习题

习题

习题1.1 表1.1中若只包含编号为1,4的两个样例,试给出相应的版本空间。

如下为西瓜的数据集:

编号色泽根蒂敲声好瓜
1青绿蜷缩浊响
2乌黑稍蜷沉闷

数据集中有三种属性,每种属性有2种可能取值,则一共有3 * 3 * 3 + 1 = 28种假设(考虑到泛化*,空集Ø的情况)。如下给出西瓜的假设空间:

习题1的西瓜假设空间

去掉那些与正例不一致的假设,最终形成的版本空间如下:

习题1的西瓜版本空间

 即版本空间有下面这7种:

  • (色泽=青绿;根蒂=*;敲声=*)
  • (色泽=*;根蒂=蜷缩;敲声=*)
  • (色泽=*;根蒂=*;敲声=浊响)
  • (色泽=青绿;根蒂=蜷缩;敲声=*)
  • (色泽=青绿;根蒂=*;敲声=浊响)
  • (色泽=*;根蒂=蜷缩;敲声=浊响)
  • (色泽=青绿;根蒂=蜷缩;敲声=浊响)

计算西瓜的假设空间和版本空间的程序如下:

package com.zfx.ml.watermelon.example.ch1.exercise1;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 《机器学习 - 周志华》第一章练习1.1中的西瓜假设空间程序和版本空间
 *
 */
public class WatermelonExample {
    
    private List<Watermelon> examples = new ArrayList<>();
    
    private Set<String> warnaSet = new LinkedHashSet<>();
    private Set<String> rootSet = new LinkedHashSet<>();
    private Set<String> knockingSet = new LinkedHashSet<>();
    
    private List<Watermelon> positiveExamples = new ArrayList<>();
    
    private List<Watermelon> hypothesisSpace = new ArrayList<>();
    private List<Watermelon> versionSpace = new ArrayList<>();
    
    public WatermelonExample(List<Watermelon> examples) {
        this.examples = examples;

        initPropertiesAndPositiveExample();
        calculateHypothesisSpace();
        calculateVersionSpace();
    }
    
    /** 初始化属性和正例 */
    private void initPropertiesAndPositiveExample() {
        for (Watermelon example : examples) {
            warnaSet.add(example.warna);
            rootSet.add(example.root);
            knockingSet.add(example.knocking);
            
            if (example.isGood()) {
                positiveExamples.add(example);
            }
        }
        
        warnaSet.add("*");
        rootSet.add("*");
        knockingSet.add("*");
    }
    
    /** 计算西瓜的假设空间 */
    private void calculateHypothesisSpace() {
        hypothesisSpace = new ArrayList<>();
        
        for (String warna : warnaSet) {
            for (String root : rootSet) {
                for (String knocking : knockingSet) {
                    boolean isGoodWatermelon = isGoodWatermelon(warna, root, knocking);
                    hypothesisSpace.add(new Watermelon(warna, root, knocking, isGoodWatermelon));
                }
            }
        }
        
        // 加上空集的情况
        hypothesisSpace.add(Watermelon.EMPTY);
    }
    
    /** 计算西瓜的版本空间 */
    private void calculateVersionSpace() {
        for (Watermelon h : hypothesisSpace) {
            // 所有属性是否都是泛化的
            boolean isAllPropGeneralize = "*".equals(h.warna) && 
                    "*".equals(h.root) && "*".equals(h.knocking);
            if (h.isGood() && !isAllPropGeneralize) { // 去掉所有属性都是泛化的情况
                versionSpace.add(h);
            }
        }
    }
    
    /** 是否为好瓜 */
    private boolean isGoodWatermelon(String warna, String root, String knocking) {
        for (Watermelon positiveExample : positiveExamples) {
            int count = 0;
            if ("*".equals(warna) || positiveExample.warna.equals(warna)) {
                count ++;
            }
            if ("*".equals(root) || positiveExample.root.equals(root)) {
                count ++;
            }
            if ("*".equals(knocking) || positiveExample.knocking.equals(knocking)) {
                count ++;
            }
            
            if (count == 3) {
                return true;
            }
        }
        return false;
    }
    
    public List<Watermelon> getHypothesisSpace() {
        return hypothesisSpace;
    }
    
    public List<Watermelon> getVersionSpace() {
        return versionSpace;
    }
    
    public static class Watermelon {
        
        /** 表示Ø */
        public static final Watermelon EMPTY = new Watermelon(null, null, null, null) {
            
            @Override
            public String toString() {
                return "Ø";
            }
            
        };
        
        final Boolean isGood; // 是否为好瓜
        final String warna; // 色泽
        final String root; // 根蒂
        final String knocking; // 敲声
        
        public Watermelon(String warna, String root, String knocking, Boolean isGood) {
            this.warna = warna;
            this.root = root;
            this.knocking = knocking;
            this.isGood = isGood;
        }
        
        /** 是否为好瓜 */
        public boolean isGood() {
            return isGood != null && isGood;
        }
        
        @Override
        public String toString() {
            return "(色泽=" + warna + ";根蒂=" + 
                    root + ";敲声=" + knocking + ")";
        }
        
    }
    
    public static void main(String[] args) {
        List<Watermelon> examples = new ArrayList<>();
        examples.add(new Watermelon("青绿", "蜷缩", "浊响", true));
        examples.add(new Watermelon("乌黑", "稍蜷", "沉闷", false));
        WatermelonExample whs = new WatermelonExample(examples);
        
        List<Watermelon> ws = whs.getHypothesisSpace();
        System.out.println("西瓜的假设空间如下:");
        for (int i = 0; i < ws.size(); i++) {
            System.out.println((i + 1) + ":" + ws.get(i));
        }
        
        List<Watermelon> vs = whs.getVersionSpace();
        System.out.println();
        System.out.println("西瓜的版本空间如下:");
        for (int i = 0; i < vs.size(); i++) {
            System.out.println((i + 1) + ":" + vs.get(i));
        }
    }

}
西瓜假设空间和版本空间计算代码

 习题1.2 与使用单个合取式来进行假设表示相比,使用“析合范式”将使得假设空间具有更强的表示能力。若使用最多包含k个合取式的析合范式来表达1.1的西瓜分类问题的假设空间,试估算有多少种可能的假设。

 先解释下相关概念:

  • 合取式( conJunction):用合取真值联结词“∧”将两个或两个以上的命题联结起来而形成的命题形式。合取联结词“并且”用符号“∧”来表示(“∧"读为合取),构成合取式的支命题,称做合取项。合取式一般表示为“p∧q”,只要其中一项为假,则整个命题为假。
  • 析取式(disjunction):用析取真值联结词“∨”将两个或两个以上的命题联结起来而形成的命题形式。析取联结词“并且”用符号“∨”来表示(“∨"读为析取),构成析取式的支命题,称做析取项。析取式一般表示为“p∨q”,只要其中一项为真,则整个命题为真。
  • 析合范式:即多个合取式的析取,例如:(p1∧q1)∨(p2∧q2)

 表1.1中有4个样例,共有3个属性,则共有3 * 4 * 4 + 1 = 49种假设,若使用k个合取式的析合范式来表示1.1西瓜分类的假设空间,很显然k的取值范围为[1, 49],在不考虑空集的情况下,k的取值范围为[1, 48]。很显然,

  •  具体假设(没有泛化的属性)的假设有:2 * 3 * 3 = 18(种)
  • 1个属性泛化的假设有:1 * 3 * 3 + 2 * 1 * 3 + 2 * 3 * 1 = 21(种)
  • 2个属性泛化的假设有:2 * 1 * 1 + 1 * 3 *1 + 1 * 1 * 3 = 8(种)
  • 3个属性泛化的假设有: 1 * 1 * 1 = 1(种)

很显然有:

  • 当 k = 1时,任选一种假设都可以作为没有冗余的假设,共有48种

转载于:https://www.cnblogs.com/zhangfengxian/p/9575132.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本章主要介绍了概率图模型的基本概念和常见类型,以及如何利用Python实现这些模型。下面是一些笔记和代码示例。 ## 概率图模型的基本概念 概率图模型是一种用于表示和处理不确定性的图形化模型,它能够将一个复杂的联合概率分布表示为多个简单的条件概率分布的乘积形式,从而简化概率推理和模型学习的过程。概率图模型主要包括两种类型:有向图模型和无向图模型。 有向图模型(Directed Acyclic Graph, DAG)又称为贝叶斯网络(Bayesian Network, BN),它用有向边表示变量之间的因果关系,每个节点表示一个随机变量,给定父节点的条件下,每个节点的取值都可以用一个条件概率分布来描述。有向图模型可以用贝叶斯公式进行概率推理和参数学习。 无向图模型(Undirected Graphical Model, UGM)又称为马尔可夫随机场(Markov Random Field, MRF),它用无向边表示变量之间的相互作用关系,每个节点表示一个随机变量,给定邻居节点的取值,每个节点的取值都可以用一个势函数(Potential Function)来描述。无向图模型可以用和有向图模型类似的方法进行概率推理和参数学习。 ## 概率图模型的Python实现 在Python中,我们可以使用`pgmpy`库来实现概率图模型。该库提供了一个简单而强大的接口来定义和操作概率图模型,支持有向图模型和无向图模型的构建、概率推理、参数学习等功能。 ### 有向图模型 以下是一个简单的有向图模型的示例: ```python from pgmpy.models import BayesianModel model = BayesianModel([('A', 'B'), ('C', 'B'), ('B', 'D')]) ``` 其中,`BayesianModel`是有向图模型的类,`('A', 'B')`表示A节点指向B节点,即B节点是A节点的子节点,依此类推。我们可以使用以下代码查看模型的结构: ```python print(model.edges()) # 输出:[('A', 'B'), ('B', 'D'), ('C', 'B')] ``` 接下来,我们可以为每个节点定义条件概率分布。以下是一个简单的例子: ```python from pgmpy.factors.discrete import TabularCPD cpd_a = TabularCPD(variable='A', variable_card=2, values=[[0.2, 0.8]]) cpd_c = TabularCPD(variable='C', variable_card=2, values=[[0.4, 0.6]]) cpd_b = TabularCPD(variable='B', variable_card=2, values=[[0.1, 0.9, 0.3, 0.7], [0.9, 0.1, 0.7, 0.3]], evidence=['A', 'C'], evidence_card=[2, 2]) cpd_d = TabularCPD(variable='D', variable_card=2, values=[[0.9, 0.1], [0.1, 0.9]], evidence=['B'], evidence_card=[2]) model.add_cpds(cpd_a, cpd_c, cpd_b, cpd_d) ``` 其中,`TabularCPD`是条件概率分布的类,`variable`表示当前节点的变量名,`variable_card`表示当前节点的取值个数,`values`表示条件概率分布的值。对于有父节点的节点,需要指定`evidence`和`evidence_card`参数,表示当前节点的父节点和父节点的取值个数。 接下来,我们可以使用以下代码进行概率推理: ```python from pgmpy.inference import VariableElimination infer = VariableElimination(model) print(infer.query(['D'], evidence={'A': 1})) # 输出:+-----+----------+ # | D | phi(D) | # +=====+==========+ # | D_0 | 0.6000 | # +-----+----------+ # | D_1 | 0.4000 | # +-----+----------+ ``` 其中,`VariableElimination`是概率推理的类,`query`方法用于查询给定变量的概率分布,`evidence`参数用于指定给定变量的取值。 ### 无向图模型 以下是一个简单的无向图模型的示例: ```python from pgmpy.models import MarkovModel model = MarkovModel([('A', 'B'), ('C', 'B'), ('B', 'D')]) ``` 其中,`MarkovModel`是无向图模型的类,与有向图模型类似,`('A', 'B')`表示A节点和B节点之间有相互作用关系。 接下来,我们可以为每个节点定义势函数。以下是一个简单的例子: ```python from pgmpy.factors.discrete import DiscreteFactor phi_a = DiscreteFactor(['A'], [2], [0.2, 0.8]) phi_c = DiscreteFactor(['C'], [2], [0.4, 0.6]) phi_b = DiscreteFactor(['A', 'C', 'B'], [2, 2, 2], [0.1, 0.9, 0.3, 0.7, 0.9, 0.1, 0.7, 0.3]) phi_d = DiscreteFactor(['B', 'D'], [2, 2], [0.9, 0.1, 0.1, 0.9]) model.add_factors(phi_a, phi_c, phi_b, phi_d) ``` 其中,`DiscreteFactor`是势函数的类,与条件概率分布类似,需要指定变量名、变量取值个数和势函数的值。 接下来,我们可以使用以下代码进行概率推理: ```python from pgmpy.inference import BeliefPropagation infer = BeliefPropagation(model) print(infer.query(['D'], evidence={'A': 1})) # 输出:+-----+----------+ # | D | phi(D) | # +=====+==========+ # | D_0 | 0.6000 | # +-----+----------+ # | D_1 | 0.4000 | # +-----+----------+ ``` 其中,`BeliefPropagation`是概率推理的类,与有向图模型类似,`query`方法用于查询给定变量的概率分布,`evidence`参数用于指定给定变量的取值。 ## 总结 本章介绍了概率图模型的基本概念和Python实现,包括有向图模型和无向图模型的构建、条件概率分布和势函数的定义、概率推理等。使用`pgmpy`库可以方便地实现概率图模型,对于概率模型的学习和应用都有很大的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值