多次拟合同一个SVM模型得到略有不同的SVM模型
Get slightly different SVM models after fitting the same SVM model multiple times
我正在做数据挖掘作业,我想应用一些集成学习和投票。因此,我希望我可以通过一个一个地创建它们来获得多个略有不同的 SVM 模型副本,因为我可以在 RNN 模型上做同样的事情。
但是,我发现,例如,在我的 SVM 拟合 30 次后,我得到了 30 个相同的模型,而在我拟合 RNN 模型后,我得到了 30 个略有不同的 RNN 模型。
你能推荐任何方法在 SVM 中做同样的事情吗?非常感谢!
SVM:最大间隔 classifier
您每次获得相同 SVM 模型的原因是因为 SVM 是最大边距 class 化器,或者换句话说,它们最大化分隔 +ve 和 -ve classes 的边距。所以你 运行 它不管你开始的随机状态如何,它总是最终找到与 +ve class 和 -ve class 的边距最大的超平面。
其他非最大边距 class 器,例如一个简单的感知器,试图将损失最小化,您可以将简单损失视为错误 class 化的数据点的数量。我们通常使用其他类型的(可微分的)损失函数,这些损失函数对应于模型预测的置信度。
例子
感知器
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()
上图显示了感知器在不同种子(initilizations)下识别出的决策边界。如您所见,所有模型都正确 class 验证了数据点,但哪个模型是最好的?当然,这对看不见的数据进行了概括,这将是在决策边界周围有足够余量以覆盖看不见的数据的数据。这就是支持向量机过度救援的地方。
支持向量机
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()
如您所见,无论随机种子如何,SVM 总是 return 相同的决策边界,即最大化边际的决策边界。
使用 RNN,您每次都会得到不同的模型,因为 RNN 不是最大边距 class生成器。此外,RNN 收敛标准是手动的,即我们决定何时停止训练过程,如果我们决定 运行 它用于固定数量的 epoch,那么根据权重初始化,模型的最终权重会有所不同。
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()
我正在做数据挖掘作业,我想应用一些集成学习和投票。因此,我希望我可以通过一个一个地创建它们来获得多个略有不同的 SVM 模型副本,因为我可以在 RNN 模型上做同样的事情。
但是,我发现,例如,在我的 SVM 拟合 30 次后,我得到了 30 个相同的模型,而在我拟合 RNN 模型后,我得到了 30 个略有不同的 RNN 模型。
你能推荐任何方法在 SVM 中做同样的事情吗?非常感谢!
SVM:最大间隔 classifier
您每次获得相同 SVM 模型的原因是因为 SVM 是最大边距 class 化器,或者换句话说,它们最大化分隔 +ve 和 -ve classes 的边距。所以你 运行 它不管你开始的随机状态如何,它总是最终找到与 +ve class 和 -ve class 的边距最大的超平面。
其他非最大边距 class 器,例如一个简单的感知器,试图将损失最小化,您可以将简单损失视为错误 class 化的数据点的数量。我们通常使用其他类型的(可微分的)损失函数,这些损失函数对应于模型预测的置信度。
例子
感知器
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()
上图显示了感知器在不同种子(initilizations)下识别出的决策边界。如您所见,所有模型都正确 class 验证了数据点,但哪个模型是最好的?当然,这对看不见的数据进行了概括,这将是在决策边界周围有足够余量以覆盖看不见的数据的数据。这就是支持向量机过度救援的地方。
支持向量机
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()
如您所见,无论随机种子如何,SVM 总是 return 相同的决策边界,即最大化边际的决策边界。
使用 RNN,您每次都会得到不同的模型,因为 RNN 不是最大边距 class生成器。此外,RNN 收敛标准是手动的,即我们决定何时停止训练过程,如果我们决定 运行 它用于固定数量的 epoch,那么根据权重初始化,模型的最终权重会有所不同。
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()