【西瓜书】1-绪论习题

文章目录

1.1

表1. 1 中若只包含编号为 1 和 4 的两个样例?试给出相应的版本空间.


表1.1的训练数据集对应的假设空间应该如下:

  • 1 色泽=*,根蒂=*,敲声=*
  • 2 色泽=青绿,根蒂=*,敲声=*
  • 3 色泽=乌黑,根蒂=*,敲声=*
  • 4 色泽=*,根蒂=蜷缩,敲声=*
  • 5 色泽=*,根蒂=硬挺,敲声=*
  • 6 色泽=*,根蒂=稍蜷,敲声=*
  • 7 色泽=*,根蒂=*,敲声=浊响
  • 8 色泽=*,根蒂=*,敲声=清脆
  • 9 色泽=*,根蒂=*,敲声=沉闷
  • 10 色泽=青绿,根蒂=蜷缩,敲声=*
  • 11 色泽=青绿,根蒂=硬挺,敲声=*
  • 12 色泽=青绿,根蒂=稍蜷,敲声=*
  • 13 色泽=乌黑,根蒂=蜷缩,敲声=*
  • 14 色泽=乌黑,根蒂=硬挺,敲声=*
  • 15 色泽=乌黑,根蒂=稍蜷,敲声=*
  • 16 色泽=青绿,根蒂=*,敲声=浊响
  • 17 色泽=青绿,根蒂=*,敲声=清脆
  • 18 色泽=青绿,根蒂=*,敲声=沉闷
  • 19 色泽=乌黑,根蒂=*,敲声=浊响
  • 20 色泽=乌黑,根蒂=*,敲声=清脆
  • 21 色泽=乌黑,根蒂=*,敲声=沉闷
  • 22 色泽=*,根蒂=蜷缩,敲声=浊响
  • 23 色泽=*,根蒂=蜷缩,敲声=清脆
  • 24 色泽=*,根蒂=蜷缩,敲声=沉闷
  • 25 色泽=*,根蒂=硬挺,敲声=浊响
  • 26 色泽=*,根蒂=硬挺,敲声=清脆
  • 27 色泽=*,根蒂=硬挺,敲声=沉闷
  • 28 色泽=*,根蒂=稍蜷,敲声=浊响
  • 29 色泽=*,根蒂=稍蜷,敲声=清脆
  • 30 色泽=*,根蒂=稍蜷,敲声=沉闷
  • 31 色泽=青绿,根蒂=蜷缩,敲声=浊响
  • 32 色泽=青绿,根蒂=蜷缩,敲声=清脆
  • 33 色泽=青绿,根蒂=蜷缩,敲声=沉闷
  • 34 色泽=青绿,根蒂=硬挺,敲声=浊响
  • 35 色泽=青绿,根蒂=硬挺,敲声=清脆
  • 36 色泽=青绿,根蒂=硬挺,敲声=沉闷
  • 37 色泽=青绿,根蒂=稍蜷,敲声=浊响
  • 38 色泽=青绿,根蒂=稍蜷,敲声=清脆
  • 39 色泽=青绿,根蒂=稍蜷,敲声=沉闷
  • 40 色泽=乌黑,根蒂=蜷缩,敲声=浊响
  • 41 色泽=乌黑,根蒂=蜷缩,敲声=清脆
  • 42 色泽=乌黑,根蒂=蜷缩,敲声=沉闷
  • 43 色泽=乌黑,根蒂=硬挺,敲声=浊响
  • 44 色泽=乌黑,根蒂=硬挺,敲声=清脆
  • 45 色泽=乌黑,根蒂=硬挺,敲声=沉闷
  • 46 色泽=乌黑,根蒂=稍蜷,敲声=浊响
  • 47 色泽=乌黑,根蒂=稍蜷,敲声=清脆
  • 48 色泽=乌黑,根蒂=稍蜷,敲声=沉闷
  • 49 Ø

加入 1 号数据,(色泽=青绿、根蒂=蜷缩、敲声=浊响) 好瓜,剩下

  • 1 色泽=*,根蒂=*,敲声=*
  • 2 色泽=青绿,根蒂=*,敲声=*
  • 4 色泽=*,根蒂=蜷缩,敲声=*
  • 7 色泽=*,根蒂=*,敲声=浊响
  • 10 色泽=青绿,根蒂=蜷缩,敲声=*
  • 16 色泽=青绿,根蒂=*,敲声=浊响
  • 22 色泽=*,根蒂=蜷缩,敲声=浊响
  • 31 色泽=青绿,根蒂=蜷缩,敲声=浊响

加入 4 号数据,(色泽=乌黑、根蒂=稍蜷、敲声=沉闷) 坏瓜,剩下

  • 2 色泽=青绿,根蒂=*,敲声=*
  • 4 色泽=*,根蒂=蜷缩,敲声=*
  • 7 色泽=*,根蒂=*,敲声=浊响
  • 10 色泽=青绿,根蒂=蜷缩,敲声=*
  • 16 色泽=青绿,根蒂=*,敲声=浊响
  • 22 色泽=*,根蒂=蜷缩,敲声=浊响
  • 31 色泽=青绿,根蒂=蜷缩,敲声=浊响

成功构建版本空间

1.2

与使用单个合取式来进行假设表示相比,使用"析合范式"将使得假设空间具有更强的表示能力。
例如

好瓜 <-> ((色泽=*(根蒂=蜷缩) ^ (敲声= *)) v ((色泽=乌黑) ^ (根蒂=*) ^ (敲声=沉闷))

会把(色泽=青绿)^(根蒂=蜷缩)^(敲声=清脆)以及(色泽=乌黑) ^ (根蒂=硬挺) ^ (敲声=沉闷)都分类为"好瓜"

若使用最多包含 k k k 个合取式的析合范式来表达。表1. 1 西瓜分类问题的假设空间, 试估算共有多少种可能的假设.


不会

  1. 48

从网上抄到一份代码(不过我觉得可以用动态规划试一试§(* ̄▽ ̄*)§)

机器学习(周志华) 第一章 习题1.2参考答案_是你的小鱼的博客-CSDN博客

import numpy as np
import itertools as it

def get_18_from_trible(trible):  #把三维向量变为代表特征的18维向量
   a = np.zeros([2,3,3])
   a1 = trible[0]
   a2 = trible[1]
   a3 = trible[2]
   if a1 == 3:  #对于第一种属性为"*"的情况
	   a1 = [1,2]
   else:
	   a1 = [a1]    
   if a2 == 4:  #对于第二种属性为"*"的情况
	   a2 = [1,2,3]
   else:
	   a2 = [a2]
	if a3 == 4:  #对于第三种属性为"*"的情况
		a3 = [1,2,3]
	else:
		a3 = [a3]
	#print (a1,a2,a3) 
	#print(a)
	for m1 in a1:
		for m2 in a2:
			for m3 in a3:
				a[m1-1][m2-1][m3-1] = 1
	return a           #得到了一个18维向量(0/1二值),代表18种特征情况

def turn_48_to_trible(num):   
# num in [0,47],把一个小于48的数字对应到一个三维数组中
	for i in range(3): 
		for j in range(4):
			for k in range(4):
				if i*16 + j*4 + k == num:
					return [i+1,j+1,k+1]

def from_48_to_18(num):  #把0-47的某个数唯一对应到某个18维向量
	a = turn_48_to_trible(num)
	b = get_18_from_trible(a)
	return b  

def main(k):
	rset=[]
	for i in it.combinations(range(48),k):   
	#开始对48取k的组合数进行穷举,i是一个k元数组
		subset=[]
		for j in range(k): 
			p = from_48_to_18(i[j])  
			subset.append(p)
		subset = np.array(subset)    
		subset = subset.any(axis=0)  # 这是去除冗余操作!!!
		subset = np.reshape(subset,[18]) 
		subset = subset.tolist()  #从array变为list方便接下来的操作
		count = 0
		for i in range(18):
			count += 2 ** i *subset[i]  
			#这是简单的一一映射,18维二值向量可以一一对应到1~2^18的某个数
		subset = count  
		length = len(rset)
		rset.append(subset)    
		if len(rset) % 100000 == 0 :
			print(len(rset))  #为了证明程序确实在运行hhh,这个可以注释掉
		if len(rset) > 5000000: 
			rset = list(set(rset))  #set是集合,是对rset数组进行去重!
			#设置500W上限为了防止set操作时数组长度太长导致程序崩掉
	rset = list(set(rset)) #最终set操作一下得到最终结果
	#rset = list(set(tuple(t) for t in rset))
	
	print( "%d : %d examples"%(k,len(rset)))    

# main(k) 运行即得k个析取范式的结果。注:当k≥9时花费时间过长!目前没法解决!

这里笔者也给出自己写的题解,和部分网上答案不一致,不保证准确性。
更新:和这篇博客的答案一致

#include <bits/stdc++.h>
using namespace std;

bitset<2 << 18> bset;
vector<int> single; // 单个合取范式匹配的位置
int color = 2, root = 3, sound = 3;

int foo(int i, int j, int k, int val = 0) {
    if (i == 0) {
        for (int x = 1; x <= color; ++x) {
            val |= foo(x, j, k, val);
        }
        return val;
    }
    if (j == 0) {
        for (int x = 1; x <= root; ++x) {
            val |= foo(i, x, k, val);
        }
        return val;
    }
    if (k == 0) {
        for (int x = 1; x <= sound; ++x) {
            val |= foo(i, j, x, val);
        }
        return val;
    }
    int no = (i - 1) * (root * sound) + (j - 1) * sound + k - 1;
    return val | (1 << no);
}

void build_vec() {

    for (int i = 0; i <= color; ++i) {
        for (int j = 0; j <= root; ++j) {
            for (int k = 0; k <= sound; ++k) {
                single.push_back(foo(i, j, k));
            }
        }
    }
}

// 组合型枚举板子
void comb(int k, int depth = 0, int start = 0, int val = 0) {
    if (depth > 0) {
        // for (size_t i = 1; i < depth; i++)
        //     cerr << "\t";
        // cerr << "Choose: " << start - 1 << "\n";
    }
    if (depth >= k) {
        // cerr << "Val: " << val << endl;
        bset.set(val);
    } else {
        for (int i = start; i < single.size(); i++) {
            comb(k, depth + 1, i + 1, val | single[i]); // 选择 i号假设
        }
    }
}

int main(int argc, char const *argv[]) {
    // 首先直接枚举 k=1的情况
    build_vec();
    int k;
    cin >> k;
    for (int i = 1; i <= k; ++i) {
        comb(i);

        cout << "i=" << i << "\tans=" << bset.count() << endl;
    }
    /* code */
    return 0;
}

以上代码在 k ≥ 9 k\geq 9 k9时计算较慢,我使用动态规划改进了一下:

这里使用了假设:

a n s k = a n s k − 1 ∨ a n s k = 1 ans_k = ans_{k-1} \vee ans_{k=1} ansk=ansk1ansk=1
也就是说要求最多使用k个,可以先只使用k-1个,然后将k-1个的结果再加上单个范式组合起来,复杂度不超过2^18 * 48能在1s内计算完成。

#include <bits/stdc++.h>
using namespace std;

bitset<2 << 18> bset;
vector<int> single; // 单个合取范式匹配的位置
int color = 2, root = 3, sound = 3;

int foo(int i, int j, int k, int val = 0) {
    if (i == 0) {
        for (int x = 1; x <= color; ++x) {
            val |= foo(x, j, k, val);
        }
        return val;
    }
    if (j == 0) {
        for (int x = 1; x <= root; ++x) {
            val |= foo(i, x, k, val);
        }
        return val;
    }
    if (k == 0) {
        for (int x = 1; x <= sound; ++x) {
            val |= foo(i, j, x, val);
        }
        return val;
    }
    int no = (i - 1) * (root * sound) + (j - 1) * sound + k - 1;
    return val | (1 << no);
}

void build_vec() {
    for (int i = 0; i <= color; ++i) {
        for (int j = 0; j <= root; ++j) {
            for (int k = 0; k <= sound; ++k) {
                single.push_back(foo(i, j, k));
            }
        }
    }
}

int main(int argc, char const *argv[]) {
    // 首先直接枚举 k=1的情况
    build_vec();

    for (auto fansi : single) {
        bset.set(fansi);
    }

    int k;
    cin >> k;
    for (int i = 1; i < k; ++i) {
        cout << "i=" << i << "\tans=" << bset.count() << endl;
        // 对每个现有范式组合结果 添加 新范式
        auto bs = bset;
        for (int i = 0; i < bs.size(); ++i) {
            if (bs.test(i)) {
                for (int fansi : single) {
                    bset.set(i | fansi); // 原有范式 | 新范式
                }
            }
        }
    }
    cout << "i=" << k << "\tans=" << bset.count() << endl;
    /* code */
    return 0;
}

输出:

$ ./a.out
48
i=1	ans=48
i=2	ans=897
i=3	ans=8385
i=4	ans=41742
i=5	ans=115821
i=6	ans=201303
i=7	ans=248853
i=8	ans=260787
i=9	ans=262143
i=10	ans=262143
i=11	ans=262143
...后面全是262143了

1.3

若数据包含噪声,则假设空间中有可能不存在与所有训练样本都一致的假设。在此情形下,试设计一种归纳偏好用于假设选择.

  • 假设噪声点很少:少数服从多数,如果统计相同标签下分类数,取占比多的
    • 对于感知机算法:使用PosketAlgorithm改善
    • 对于SVM算法:使用软间隔SVM
  • 假设噪声点服从高斯分布:使用最小二乘法
    • 最小二乘法对于离群值敏感,如果存在极端的噪声值,可能需要考虑采用鲁棒回归方法或者其他方法来处理。

1.4


前面忘了,中间忘了,总之成立
在这里插入图片描述

KaTeX parse error: Expected 'EOF', got '&' at position 58: …id X, f\right) &̲=& \sum_{h} \su…

1.5

试述机器学习能在互联网搜索的哪曲环节起什么作用.


  1. NLP,关键词检索
  2. 图像识别:以图搜图
  3. 爬虫后数据分析,pagerank网页排序算法
  4. 文字搜图
  5. 带歧义的搜索?

参考

  1. 《机器学习》周志华 习题1.2的解答_机器学习导论试题讲解-CSDN博客
  2. 《机器学习》习题解答(第一章:绪论) - 知乎
  3. ChatGPT
  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值