1 最优分割法简介

最有分割法是对有序样品的一种聚类方法。当样品是按顺序排列,在分类中不允许打破样品的顺序。即

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式

,对python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_02 个有序样品进行分割,就可能有

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_03

种划分方法,这每一种分法称为一种分割。在所有的这些分割中,找到一种分割法,这种分割法使得各段内样品之间的差异最小,而各段之间的差异最大。这种对python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_04 个样品分段并使组内离差平方和最小的分割方法,称为最优分割法。段内数值变化可用变差或者极差来表示,比如样品段

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_05

变差: 

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_06


python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_07

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_08 表示样品段内样本间的差异情况,python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_08越小表示段内各样品之间差异性越小;因此,把python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_10 称为段直径。

2 Fisher最优分割法简介

Fisher最优分割法是用离差平方和来表示同类样本之间的差异程度,通过简便的计算步骤和作图,确定最优分类数,使同类样本间的差异最小,各类别样本间的差异最大,并用F检验法检验最优分类数的合理性。

设某一类python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_11 包含的样品有

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_12

,记为

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_13

,该类的均值向量python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_14  

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_15

, ,

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_16

表示这一类的直径,常用的直径有

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_17

,当是单变量时,也可定义直径为­

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_18

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_19 是中位数。

3 Fisher最优分割递推公式


python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_20

表示将n 个有序样品分为python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_21 类的一种分法,定义损失函数为

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_22

,当python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_04python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_24 固定时,

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_25

越小表示各类的离差平方和越小,因此要寻找一种分法

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_26

,使分类损失函数

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_25

达到最小,记为

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_28

。递推公式:

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_29

             

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_30

公式含义:如果要找到n 个样品分为python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_31 个类的最优分割,应建立在将

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_32

个样品分为k-1 类的最优分割的基础上。

4 Fisher最优分割计算流程

若分类数python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_24 已知,求分类法

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_28

使它在损失函数意义下达最小,其求法如下:首先找分点python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_递推公式_35 使递推公式达极小,即

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_36

。于是得第k

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_37

。然后找python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优分割_38 ,使它满足

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_39

得到第

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_40

类。类似的方法一次可以得到所有类

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_41

,这就是所求的最优解,即:

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_42

。总之,为了求最优解,主要是计算

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_43


python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_44

}

5 Fisher最优分割-Python完整代码

import numpy as np
def G(X, i, j):
    #tex:
    #$$ \overline{x_G}=\frac{1}{j-i+1}\sum^{j}_{t=i}X_t $$
    xg = 0
    for t in range(i-1, j):
        xg += X[t]
    xg /= (j - i + 1)
    return xg
def D(X, i, j):
    #tex:
    #$$ D(i,j)=\sum^{j}_{t=i}(X_t-\overline{x_G})'(X_t-\overline{x_G}) $$
    d = 0
    xg = G(X, i, j)
    for t in range(i-1, j):
        d += (X[t] - xg) ** 2
    return d
def Lq(X, N, K):
    #tex:
    #$$ L(b(n,k))=\sum^k_{i=1}D(i_t,i_{t+1}-1) $$
    #$$ \begin{equation} \left\{ \begin{array}{lr} L(p(n,2))=1 \\ L(p(n,k))=\underset{k \le j \le n}{min} D(1,j-1)+D(n,j) \end{array} \right. \end{equation} $$
    l = np.zeros((N+1, K+1))
    for n in range(1, N+1):
        l[n, 1] = D(X, 1, n)
    for k in range(2, K+1):
        for n in range(k, N+1):
            l[n, k] = min([l[j-1, k-1] + D(X, j, n) for j in range(k, n+1)])
    return l
def B(Lp):
    N = Lp.shape[0] - 1
    K = Lp.shape[1] - 1
    Bl = np.zeros(K+1)
    for k in range(1, K):
        Bl[k] = Lp[N, k] / Lp[N, k+1]
    return Bl
def split_class(X, K, l=None):
    if l is None:
        l = Lq(X, len(X), K * 2 + 1)
        Bl = B(l)
        for i in range(1, K):
            if Bl[i]-1 <= 0.05:
                K = i+1
                l = Lq(X, len(X), K * 2 + 1)
                break
    N = len(X)
    if K == 1:
        return []
    else:
        dist = np.array([abs(l[t-1, K-1] + D(X, t, N) - l[N, K]) for t in range(K, N+1)])
        t = list(range(K, N+1))[int(np.argmin(dist))]
        r = split_class(X[:t-1], K-1, l)
        r.append(t - 1)
        return r

直接调用split_class函数即可

6 Fisher最优分割-确定分类数K

分类个数的确定如果能从实际问题中首先确定当然最好,如果不能则可以从

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_损失函数_45

随k的变化趋势图中找到拐点处,作为确定k的依据。当曲线拐点很平缓时,可选择的k较多,这时需要用其他方法来确定,如均方比法和特征根法。稳定分类数可以这样定义: 当分类数小于此值时, 

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_Fisher_46

较大, 类内样本间的差别仍然显著, 需要继续再细分, 否则分类选取时, 代表性和信息量不能保证; 当分类数大于此值时, 类内样本间的差别已经不显著, 再细分的意义不大。稳定分类数代表了

python 检测曲线拐点 的算法 对噪声不敏感 python求曲线拐点_最优解_47

值由较大值向较小值变化的转折点。按分类选取的原则在每一类中选取一个代表点, 则在优化布点时, 分类数应不小于稳定分类数, 才能保证优选点的代表性。