模型评估与选择

模型评估与选择

:由于本人水平有限,难免出现纰漏,敬请诸君不吝赐教。

1.前言

机器学习具体说来,就是从假设空间中找出最优的模型。对于现实问题,应该先对问题进行分析,选择某一个模型算法,比如支持向量机、随机森林等,训练得出模型。但不同模型算法或者同一模型算法不同超参数都可能产生比较大的性能差异,这时,我们需要评估模型好坏,从而确定模型算法以及超参数。

2.评估方法

(1)留出法

留出法直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T。在S上训练出模型后,用T来评估模型误差,作为对泛化误差的估计。训练集S与训练集T按照一定比例划分,通常的做法是训练集占总样本数的2/3~4/5。同时,划分时应该保持数据分布一致性,采用分层抽样的方法,比如说,在二分类问题中,D中样本可分为正反两类,对于不同类别分别按比例划分,从而保证数据分布一致性。此外,数据划分带有一定随机性,一次留出法估计不够可靠,应该多次取平均。

# 分层
def layered(data_set):
    n = len(data_set[0])

    classifications = {}

    # 遍历数据集,获取分布情况
    for data in data_set:
        classification_list = []
        label = data[n-1]
        if classifications.__contains__(label):
            classification_list = classifications[data[n-1]]
        else:
            classifications[label] = classification_list
        classification_list.append(data)

    return classifications



# 留出法
def hold_out(data_set, scale, times=1):

    classifications = layered(data_set)

    train_test_list = []

    for i in range(times):
        s = []
        t = []

        for label in classifications.keys():
            classification_list = classifications.get(label)
            m = len(classification_list)
            for count in range(int(scale*m)):
                random_pos = random.randint(0, m-1)
                data = classification_list[random_pos]
                s.append(data)
                classification_list.remove(data)
            t = t + classification_list
        train_test_list.append((s, t))
    return train_test_list

(2)交叉验证法

交叉验证法通过分层采样将数据集D均分为k个子集合,每次选取其中k-1个集合作为训练集S,剩下的一个作为测试集T,这样得到k组划分结果,分别训练取平均。但由于划分子集合具有一定随机性,于是重复p次,这样的过程被称为p次k折交叉验证法。特别地,当k取D中总样本数时,称为留一法

#交叉验证法
def cross_validation(data_set, k, times=1):
    classifications = layered(data_set)
    test_train_lists = []

    for i in range(times):
        sub_sets = []
        for j in range(k):
            sub_sets.append([])

        for label in classifications.keys():
            classification = classifications[label]
            m = len(classification)
            pos_list = list(range(m))
            sub_pos = 0
            for g in range(m):
                pos = pos_list[random.randint(0, len(pos_list)-1)]
                data = classification[pos]
                sub_sets[sub_pos%k].append(data)
                sub_pos = sub_pos + 1
                pos_list.remove(pos)

        test_train_list = []
        for j in range(k):
            t = sub_sets[j]
            s = []
            for g in range(k):
                if g != j:
                    s = s + sub_sets[g]
            test_train_list.append((t, s))
        test_train_lists.append(test_train_list)
    return test_train_lists

(3)自助法

自助法对给定包含m个样本数据集D进行放回重复采样m次得到集合作为训练集S,剩下的D-S作为测试集T。显然,D中部分样本会多次被选中,估计D中36.8%的样本始终不会被选中。
lim ⁡ m → ∞ ( 1 − 1 m ) m = e lim ⁡ m → ∞ m ln ⁡ ( 1 − 1 m ) = e − 1 ≈ 0.368 \lim_{m\to \infty} (1-\frac{1}{m})^m = e^{\lim_{m \to \infty} m\ln(1-\frac{1}{m})} = e^{-1} \approx 0.368 mlim(1m1)m=elimmmln(1m1)=e10.368

def bootstrapping(data_set):
    s = set()
    m = len(data_set)

    for i in range(m):
        s.add(tuple(data_set[random.randint(0, m-1)]))

    s = [list(data) for data in s]
    t = []
    for data in data_set:
        if not s.__contains__(data):
            t.append(data)

    return (t, s)

3.性能度量

(1)查全率、查准率、F1

  • 混淆矩阵

    真实值/预测值正例反例
    正例TP(真正例)FN(假反例)
    反例FP(假正例)TN(真反例)

    以上表格是二分类问题混淆矩阵,第一行表示预测值,第一列表示真实值。

  • 查全率

    查全率表示真实值为正例的样本中被预测为正例的比例, R = T P T P + F N R=\frac{TP}{TP+FN} R=TP+FNTP

  • 查准率

    查准率表示预测值为正例的样本中真实值为正例的比例, P = T P T P + F P P=\frac{TP}{TP+FP} P=TP+FPTP

  • P-R曲线

    按照学习器预测结果对样本进行排序,排在前面的是学习器认为最可能是正例的样本,排在最后的则是学习器认为最不可能是正例的样本。按此顺序逐个把样本作为正例预测,则每次可以计算出查全率和查准率,由此以P为纵轴,R为横轴,画出P-R曲线。

    若其中一个学习器曲线完全包住另一个学习器曲线,则认为前者优于后者,如B优于C。但对于有交叉的两个学习器曲线如A与B,我们也希望能够比较,于是引入F1度量。

    在这里插入图片描述

  • F1

    F β F_\beta Fβ度量可综合考虑查全率和查准率
    F β = ( 1 + β 2 ) × P × R ( β 2 × P ) + R F_\beta = \frac{(1+\beta^2) \times P \times R}{(\beta^2 \times P)+R} Fβ=(β2×P)+R(1+β2)×P×R
    β &gt; 1 \beta \gt 1 β>1时,查全率有更大影响。当​ β &lt; 1 \beta \lt 1 β<1时查准率有更大影响。当 β = 1 \beta =1 β=1时,即为F1度量。

    :最常用的度量是F1,如果需要综合考虑多个二分类问题的混淆矩阵,可以用求均值P和R,从而计算宏F1。

(2)ROC与AUC

​ 与P-R曲线类似,唯一区别在于横纵轴不一样,ROC曲线纵轴是真正例率TPR,横轴是假正例率FPR。同样地,当其中学习器曲线完全包住另一个学习器曲线时,则认为前者优于后者。对于交叉曲线,用ROC曲线围成面积AUC来衡量,设ROC曲线横纵轴值为 ( x 1 , y 1 ) , . . . , ( x m , y m ) (x_1,y_1),...,(x_m,y_m) (x1,y1),...,(xm,ym) A U C = 1 2 ∑ i = 1 m − 1 ( x i + 1 − x i ) ( y i + 1 + y i ) AUC=\frac{1}{2}\sum_{i=1}^{m-1}(x_{i+1}-x_i)(y_{i+1}+y_i) AUC=21i=1m1(xi+1xi)(yi+1+yi)
在这里插入图片描述

(3)代价敏感错误率与代价曲线

​ ROC曲线在不同类型错误代价均等的条件下有效,但在现实生活中,不总是这样。比如说去医院检查是否存在肿瘤,此时出现FP错误代价无非是复查,但是出现FN错误将有可能导致性命危险。因此,对于非均等错误代价,引入代价矩阵,以正例概率代价 P ( + ) c o s t P(+)cost P(+)cost为横轴,归一化代价​ c o s t n o r m cost_{norm} costnorm得出代价曲线。
P ( + ) c o s t = p × c o s t 01 p × c o s t 01 + ( 1 − p ) × c o s t 10 P(+)cost = \frac{p \times cost_{01}}{p \times cost_{01}+(1-p) \times cost_{10}} P(+)cost=p×cost01+(1p)×cost10p×cost01

c o s t n o r m = F N R × p × c o s t 01 + F P R × ( 1 − p ) × c o s t 10 p × c o s t 01 + ( 1 − p ) × c o s t 10 cost_{norm}=\frac{FNR \times p \times cost_{01} + FPR \times (1-p) \times cost_{10}}{p \times cost_{01}+(1-p) \times cost_{10}} costnorm=p×cost01+(1p)×cost10FNR×p×cost01+FPR×(1p)×cost10

​ 其中p为样本为正例的概率。

​ 以二分类问题为例,代价曲线与横轴所围成面积即为期望总体代价。代价曲线的绘制很简单:对于ROC曲线上每一点(FPR,TPR),在代价平面上绘制一条从(0,FPR)到(1,TPR)的直线,所有直线下界构成代价曲线。

在这里插入图片描述

4.比较检验

​ 学习器的比较不能够简单地比较性能度量大小,因为性能度量是基于有限个测试样本得出的,而学习器的好坏应该比较两者泛化性能。以下讨论均使用错误率 ε \varepsilon ε来作为性能度量,记 ε \varepsilon ε为泛化错误率, ε ^ \hat{\varepsilon} ε^为测试错误率。

(1)单学习器检验

  • 二项检验

    ​ 对于给定样本数为m的数据集D有,每个样本被预测错误的概率为 ε \varepsilon ε,服从0-1分布,则被预测错误的样本数目服从m重二项分布。于是,测试错误率 ε ^ \hat{\varepsilon} ε^可看做是泛化错误率的采样,其出现的概率为
    P ( ε ^ ∣ ε ) = C m ε ^ × m × ε ε ^ × m × ( 1 − ε ) m × ( 1 − ε ^ ) P(\hat{\varepsilon}|\varepsilon)=C_m^{\hat{\varepsilon} \times m} \times \varepsilon ^ {\hat{\varepsilon} \times m} \times (1-\varepsilon)^{m \times (1-\hat{\varepsilon})} P(ε^ε)=Cmε^×m×εε^×m×(1ε)m×(1ε^)

    那么,对于假设 ε ≤ ε 0 \varepsilon \le \varepsilon_0 εε0,二项检验先求得最大的 ε \varepsilon ε使 P ( ε &lt; ε 0 ) &gt; 1 − α P(\varepsilon &lt; \varepsilon_0) \gt 1-\alpha P(ε<ε0)>1α,并记作 ε ‾ \overline{\varepsilon} ε。若测试错误率 ε ^ ∈ ( 0 , ε ‾ ) \hat{\varepsilon} \in (0,\overline{\varepsilon}) ε^(0,ε),则接受该假设,否则拒绝该假设。

  • t检验

    ​ 对于给定样本数为m的数据集D,k次留出法划分所得测试错误率为 ε ^ i , i = 1 , 2 , . . . , k \hat{\varepsilon}_i,i=1,2,...,k ε^i,i=1,2,...,k,可看做是泛化错误率的独立采样。

    假设测试错误率服从正态分布,令 ε ^ ‾ = 1 k ∑ i = 1 k ε ^ i \overline{\hat{\varepsilon}} = \frac{1}{k}\sum_{i=1}^k \hat{\varepsilon}_i ε^=k1i=1kε^i S 2 = 1 k − 1 ∑ i = 1 k ( ε ^ i − ϵ ^ ‾ ) 2 S^2 = \frac{1}{k-1}\sum_{i=1}^k(\hat{\varepsilon}_i-\overline{\hat{\epsilon}})^2 S2=k11i=1k(ε^iϵ^)2
    T t = k ( ϵ ^ ‾ − μ ) S ∼ t ( k − 1 ) T_t=\frac{\sqrt{k}(\overline{\hat{\epsilon}}-\mu)}{S} \sim t(k-1) Tt=Sk (ϵ^μ)t(k1)

    那么
    P { ∣ ε ^ ‾ − μ ∣ ≤ Δ } = 1 − α ⇔ P { ∣ T t ∣ ≤ k Δ S } = 1 − α ⇔ k Δ S = t α 2 ( k − 1 ) ⇔ Δ = S × t α 2 ( k − 1 ) k P\{|\overline{\hat{\varepsilon}}-\mu| \le \Delta\} = 1-\alpha \\ \Leftrightarrow P\{|T_t| \le \frac{\sqrt{k}\Delta}{S}\} = 1-\alpha \\ \Leftrightarrow \frac{\sqrt{k}\Delta}{S} = t_{\frac{\alpha}{2}}(k-1)\\ \Leftrightarrow \Delta = \frac{S \times t_{\frac{\alpha}{2}}(k-1)} {\sqrt{k}} P{ε^μΔ}=1αP{TtSk Δ}=1αSk Δ=t2α(k1)Δ=k S×t2α(k1)
    于是,对于假设 μ = ε 0 \mu = \varepsilon_0 μ=ε0, 当 ∣ ε ^ ‾ − ε ∣ ≤ Δ |\overline{\hat{\varepsilon}}-\varepsilon| \le \Delta ε^εΔ时,接受该假设,否则拒绝该假设。

(2)两学习器检验

  • 交叉验证t检验

    对学习器A和B,我们使用k折交叉验证法所得测试错误率分别为 ε i A \varepsilon_i^A εiA ε i B \varepsilon_i^B εiB i = 1 , 2 , . . . , k i=1,2,...,k i=1,2,...,k,并且两者对应在相同的第i折数据集上所得结果。令 Δ i = ε i A − ε i B \Delta_i=\varepsilon_i^A-\varepsilon_i^B Δi=εiAεiB,对 Δ i \Delta_i Δi进行t校验,其原理同上述t校验。但是由于交叉验证法在不同轮次的训练集有所重叠,其测试错误率实际上并不独立,这会导致过高估计假设成立的概率。为了缓解这一问题,可采用“5次2折交叉验证法”。

  • McNemar检验(卡方校验): T χ 2 = ( ∣ e 01 − e 10 ∣ − 1 ) 2 e 01 + e 10 ∼ χ 2 ( 1 ) T_{\chi^2} = \frac{(|e_{01}-e_{10}|-1)^2}{e_{01}+e_{10}} \sim \chi^2(1) Tχ2=e01+e10(e01e101)2χ2(1)

(3)多学习器检验

  • Friedman检验
  • Nemenyi后续检验

5.偏差与方差

​ ”偏差-方差分解“是解释学习算法泛化性能的一种重要工具。

参考资料

  • 《机器学习》 - 周志华
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值