多次拟合相同的SVM模型后,获得略有不同的SVM模型

时间:2019-03-17 09:08:44

标签: python scikit-learn deep-learning svm

我正在从事数据挖掘作业,我想通过投票进行一些综合学习。因此,我希望可以通过逐个创建一个SVM模型来获得多个拷贝,因为它们可以在RNN模型上做同样的事情。 enter image description here

但是,我发现在对SVM进行30次拟合后,我得到了30个相同的模型,而对RNN模型进行拟合后,我可以得到30个略有不同的RNN模型。

enter image description here

您可以建议使用任何方法在SVM中执行相同的操作吗?非常感谢你!

1 个答案:

答案 0 :(得分:2)

SVM:最大边距分类器

每次获得相同SVM模型的原因是因为SVM是最大余量分类器,或者换句话说,它们将+ ve和-ve类分开的余量最大化。因此,无论您以何种方式运行,无论您运行的是哪种随机状态,它总是最终会找到其+ ve类和-ve类边距最大的超素。

其他非最大余量分类器(例如简单的感知器)会尝试将损失最小化,您可以将简单损失视为错误分类的数据点数。我们通常使用与模型预测的置信度相对应的其他种类(可微分)损失函数。

示例

感知器

X = np.r_[np.random.randn(10, 2) - [2, 2], np.random.randn(10, 2) + [2, 2]]
y = [0] * 10 + [1] * 10

def plot_it(clf, X):     
    x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
                         np.arange(y_min, y_max, 0.1))

    Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])

    Z = Z.reshape(xx.shape)
    plt.contourf(xx, yy, Z, cmap=plt.cm.RdBu, alpha=.8)    
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
    plt.xticks([])
    plt.yticks([])


plt.close('all')
plt.figure()
seeds = [0,10,20,30,40,50]
for i in range(1,7):
    plt.subplot(2,3,i)    
    clf = Perceptron(random_state=seeds[i-1])
    clf.fit(X,y)    
    plot_it(clf, X)    
plt.tight_layout()
plt.show()

enter image description here

上图显示了具有不同种子(初始化)的感知器所确定的决策边界。如您所见,所有模型都正确地对数据点进行了分类,但是哪种模型最好?当然,这将泛化未见数据,这将是在决策边界周围具有足够余量以覆盖未见数据的数据。这就是SVM进行救援的地方。

SVM

plt.close('all')
plt.figure()
seeds = [0,10,20,30,40,50]
for i in range(1,7):
    plt.subplot(2,3,i)    
    clf = LinearSVC(random_state=seeds[i-1])
    clf.fit(X,y)    
    plot_it(clf, X)    
plt.tight_layout()  
plt.show()

enter image description here

如您所见,不管随机种子是什么,SVM总是返回相同的决策边界,即最大保证金的边界。

由于RNN并不是最大余量分类器,因此每次使用RNN都会得到不同的模型。此外,RNN收敛标准是手动的,即我们决定何时停止训练过程,如果决定以固定次数的时间段运行训练过程,则取决于权重初始化,模型的最终权重将有所不同。

LSTM

import torch
from torch import nn
from torch import optim

def plot_rnn(lstm, X):     
    x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
                         np.arange(y_min, y_max, 0.1))

    p = np.c_[xx.ravel(), yy.ravel()]
    xt = torch.FloatTensor(p.reshape(-1,1,2).transpose(1, 0, 2))

    s = nn.Sigmoid()
    Z,_ = lstm(xt)
    Z = s(Z.view(len(p)))

    Z = Z.detach().numpy().reshape(xx.shape)
    plt.contourf(xx, yy, Z, cmap=plt.cm.RdBu, alpha=.8)    
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
    plt.xticks([])
    plt.yticks([])

def train(X, y):
    batch_size = 20
    input_size = 2
    time_steps = 1
    output_size = 1

    xt = torch.FloatTensor(X.reshape(batch_size,time_steps,input_size).transpose(1, 0, 2))
    yt = torch.FloatTensor(y)

    lstm = nn.LSTM(input_size, output_size, 1)
    s = nn.Sigmoid()
    loss_function = nn.BCELoss()
    optimizer = optim.SGD(lstm.parameters(), lr=0.05)

    for i in range(1000):
        lstm.zero_grad()
        y_hat,_ = lstm(xt)
        y_hat = y_hat.view(20)
        y_hat = s(y_hat)
        loss = loss_function(y_hat, yt)
        loss.backward()
        optimizer.step()
        #print (loss.data)
    return lstm

plt.close('all')
plt.figure()
for i in range(1,7):
    plt.subplot(2,3,i)    
    clf = train(X,y)    
    plot_rnn(clf, X)    

plt.tight_layout()
plt.show()

enter image description here