def train(self):
if (self.status != 'init'):
print("Please load train data and init W first.")
return self.W
self.status = 'train'
original_X = self.train_X[:, 1:]
K = utility.Kernel.kernel_matrix(self, original_X)
# P = Q, q = p, G = -A, h = -c
P = cvxopt.matrix(np.bmat([[K, -K], [-K, K]]))
q = cvxopt.matrix(np.bmat([self.epsilon - self.train_Y, self.epsilon + self.train_Y]).reshape((-1, 1)))
G = cvxopt.matrix(np.bmat([[-np.eye(2 * self.data_num)], [np.eye(2 * self.data_num)]]))
h = cvxopt.matrix(np.bmat([[np.zeros((2 * self.data_num, 1))], [self.C * np.ones((2 * self.data_num, 1))]]))
# A = cvxopt.matrix(np.append(np.ones(self.data_num), -1 * np.ones(self.data_num)), (1, 2*self.data_num))
# b = cvxopt.matrix(0.0)
cvxopt.solvers.options['show_progress'] = False
solution = cvxopt.solvers.qp(P, q, G, h)
# Lagrange multipliers
alpha = np.array(solution['x']).reshape((2, -1))
self.alpha_upper = alpha[0]
self.alpha_lower = alpha[1]
self.beta = self.alpha_upper - self.alpha_lower
sv = abs(self.beta) > 1e-5
self.sv_index = np.arange(len(self.beta))[sv]
self.sv_beta = self.beta[sv]
self.sv_X = original_X[sv]
self.sv_Y = self.train_Y[sv]
free_sv_upper = np.logical_and(self.alpha_upper > 1e-5, self.alpha_upper < self.C)
self.free_sv_index_upper = np.arange(len(self.alpha_upper))[free_sv_upper]
self.free_sv_alpha_upper = self.alpha_upper[free_sv_upper]
self.free_sv_X_upper = original_X[free_sv_upper]
self.free_sv_Y_upper = self.train_Y[free_sv_upper]
free_sv_lower = np.logical_and(self.alpha_lower > 1e-5, self.alpha_lower < self.C)
self.free_sv_index_lower = np.arange(len(self.alpha_lower))[free_sv_lower]
self.free_sv_alpha_lower = self.alpha_lower[free_sv_lower]
self.free_sv_X_lower = original_X[free_sv_lower]
self.free_sv_Y_lower = self.train_Y[free_sv_lower]
short_b_upper = self.free_sv_Y_upper[0] - np.sum(self.sv_beta * utility.Kernel.kernel_matrix_xX(self, self.free_sv_X_upper[0], self.sv_X)) - self.epsilon
short_b_lower = self.free_sv_Y_lower[0] - np.sum(self.sv_beta * utility.Kernel.kernel_matrix_xX(self, self.free_sv_X_lower[0], self.sv_X)) + self.epsilon
self.sv_avg_b = (short_b_upper + short_b_lower) / 2
return self.W
评论列表
文章目录