《机器学习

习题

习题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