为了账号安全,请及时绑定邮箱和手机立即绑定

多次拟合同一个 SVM 模型后得到略有不同的 SVM 模型

多次拟合同一个 SVM 模型后得到略有不同的 SVM 模型

阿晨1998 2021-12-08 10:23:20
我正在做数据挖掘作业,我想通过投票应用一些集成学习。因此,我希望我可以通过一个一个地创建它们来获得多个略有不同的 SVM 模型的副本,因为我可以在 RNN 模型上做同样的事情。 但是,我发现,例如,在拟合 SVM 30 次后,我得到了 30 个相同的模型,而在拟合 RNN 模型后,我可以得到 30 个略有不同的 RNN 模型。你能建议任何方法在 SVM 中做同样的事情吗?非常感谢!
查看完整描述

1 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

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()

//img1.sycdn.imooc.com//61b017480001c68005900388.jpg

上图显示了具有不同种子(初始化)的感知器识别的决策边界。正如您所看到的,所有模型都正确地对数据点进行了分类,但哪个模型最好?当然,这对看不见的数据进行了概括,这将是在决策边界周围具有足够余量以覆盖看不见的数据的数据。这就是 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()

//img1.sycdn.imooc.com//61b01754000108bd05880385.jpg

正如您所看到的,无论随机种子如何,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()

//img1.sycdn.imooc.com//61b017620001784c05880388.jpg

查看完整回答
反对 回复 2021-12-08
  • 1 回答
  • 0 关注
  • 324 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信