代码之家  ›  专栏  ›  技术社区  ›  Vidya Marathe

利用支持向量机预测概率

  •  10
  • Vidya Marathe  · 技术社区  · 7 年前

    我写了这段代码,想获得分类的概率。

    from sklearn import svm
    X = [[0, 0], [10, 10],[20,30],[30,30],[40, 30], [80,60], [80,50]]
    y = [0, 1, 2, 3, 4, 5, 6]
    clf = svm.SVC() 
    clf.probability=True
    clf.fit(X, y)
    prob = clf.predict_proba([[10, 10]])
    print prob
    

    我获得了以下输出:

    [[0.15376986 0.07691205 0.15388546 0.15389275 0.15386348 0.15383004 0.15384636]]
    

    这很奇怪,因为概率应该是

    [0 1 0 0 0 0 0 0]
    

    (注意,必须预测类别的样本与第二个样本相同)同样,该类别获得的概率最低。

    3 回复  |  直到 7 年前
        1
  •  8
  •   borgr Atterratio    4 年前

    编辑 :正如@TimH所指出的,概率可以通过以下公式得出 clf.decision_function(X) 。下面的代码是固定的。注意低概率的指定问题,使用 predict_proba(X) ,我想答案是根据官方文件 here ,则, 。。。。此外,它将在非常小的数据集上产生无意义的结果。

    理解支持向量机的结果概率时的答案剩余。 简而言之,二维平面中有7个类和7个点。 支持向量机试图做的是在每个类和其他类之间找到一个线性分隔符(一对一方法)。每次只选2个班。 你得到的是 归一化后分类器的投票 。更多关于多类支持向量机的详细说明,请参见 libsvm 在里面 this post或 here (scikit learn使用libsvm)。

    通过稍微修改代码,我们可以看到确实选择了正确的类:

    from sklearn import svm
    import matplotlib.pyplot as plt
    import numpy as np
    
    
    X = [[0, 0], [10, 10],[20,30],[30,30],[40, 30], [80,60], [80,50]]
    y = [0, 1, 2, 3, 3, 4, 4]
    clf = svm.SVC() 
    clf.fit(X, y)
    
    x_pred = [[10,10]]
    p = np.array(clf.decision_function(x_pred)) # decision is a voting function
    prob = np.exp(p)/np.sum(np.exp(p),axis=1, keepdims=True) # softmax after the voting
    classes = clf.predict(x_pred)
    
    _ = [print('Sample={}, Prediction={},\n Votes={} \nP={}, '.format(idx,c,v, s)) for idx, (v,s,c) in enumerate(zip(p,prob,classes))]
    

    相应的输出为

    Sample=0, Prediction=0,
    Votes=[ 6.5         4.91666667  3.91666667  2.91666667  1.91666667  0.91666667 -0.08333333] 
    P=[ 0.75531071  0.15505748  0.05704246  0.02098475  0.00771986  0.00283998  0.00104477], 
    Sample=1, Prediction=1,
    Votes=[ 4.91666667  6.5         3.91666667  2.91666667  1.91666667  0.91666667 -0.08333333] 
    P=[ 0.15505748  0.75531071  0.05704246  0.02098475  0.00771986  0.00283998  0.00104477], 
    Sample=2, Prediction=2,
    Votes=[ 1.91666667  2.91666667  6.5         4.91666667  3.91666667  0.91666667 -0.08333333] 
    P=[ 0.00771986  0.02098475  0.75531071  0.15505748  0.05704246  0.00283998  0.00104477], 
    Sample=3, Prediction=3,
    Votes=[ 1.91666667  2.91666667  4.91666667  6.5         3.91666667  0.91666667 -0.08333333] 
    P=[ 0.00771986  0.02098475  0.15505748  0.75531071  0.05704246  0.00283998  0.00104477], 
    Sample=4, Prediction=4,
    Votes=[ 1.91666667  2.91666667  3.91666667  4.91666667  6.5         0.91666667 -0.08333333] 
    P=[ 0.00771986  0.02098475  0.05704246  0.15505748  0.75531071  0.00283998  0.00104477], 
    Sample=5, Prediction=5,
    Votes=[ 3.91666667  2.91666667  1.91666667  0.91666667 -0.08333333  6.5  4.91666667] 
    P=[ 0.05704246  0.02098475  0.00771986  0.00283998  0.00104477  0.75531071  0.15505748], 
    Sample=6, Prediction=6,
    Votes=[ 3.91666667  2.91666667  1.91666667  0.91666667 -0.08333333  4.91666667  6.5       ] 
    P=[ 0.05704246  0.02098475  0.00771986  0.00283998  0.00104477  0.15505748  0.75531071], 
    

    您还可以看到决策区域:

    X = np.array(X)
    y = np.array(y)
    fig = plt.figure(figsize=(8,8))
    ax = fig.add_subplot(111)
    
    XX, YY = np.mgrid[0:100:200j, 0:100:200j]
    Z = clf.predict(np.c_[XX.ravel(), YY.ravel()])
    
    Z = Z.reshape(XX.shape)
    plt.figure(1, figsize=(4, 3))
    plt.pcolormesh(XX, YY, Z, cmap=plt.cm.Paired)
    
    for idx in range(7):
        ax.scatter(X[idx,0],X[idx,1], color='k')
    

    enter image description here

        2
  •  8
  •   Tim    7 年前

    您应该禁用 probability 和使用 decision_function 相反,因为不能保证 predict_proba predict 返回相同的结果。 您可以在 documentation

    clf.predict([[10, 10]]) // returns 1 as expected 
    
    prop = clf.decision_function([[10, 10]]) // returns [[ 4.91666667  6.5         3.91666667  2.91666667  1.91666667  0.91666667
          -0.08333333]]
    prediction = np.argmax(prop) // returns 1 
    
        3
  •  2
  •   Community CDub    4 年前

    你可以 read in the docs 那个

    SVC method decision\u函数为每个样本提供每类分数(或在二进制情况下为每个样本提供单个分数)。当构造函数选项概率设置为True时,将启用类成员概率估计(来自方法predict\u proba和predict\u log\u proba)。在二进制情况下 使用Platt标度校准概率 :支持向量机得分的逻辑回归,通过对训练数据的额外交叉验证进行拟合。在多类情况下,这是根据Wu等人(2004)进行的扩展。

    不用说, Platt缩放中涉及的交叉验证对于大型数据集来说是一项昂贵的操作 此外,概率估计值可能与分数不一致 ,在某种意义上,分数的argmax可能不是概率的argmax。(例如,在二进制分类中, predict可以将样本标记为属于具有概率的类<根据predict\u proba .) 普氏方法也有理论问题。 如果需要置信度得分,但这些不一定是概率,那么 建议将概率设置为False,并使用decision\u函数代替predict\u proba。

    堆栈溢出用户对该函数也有很多困惑,如中所示 this thread this one