L. Li and H.-T. Lin, ‘‘Ordinal regression by extended binary classification,’’ in Proc. Adv. Neural Inf. Process. Syst., 2007, pp. 865–872
基于cvxpy实现了个线性版的
要点:cvxpy中连续多个约束可以使用for循环得到,详细见代码41行。
尝试了非线性的Cvxpy解决方案。仅100条数据,直接内存溢出。
非线性的算法只能用SMO。
补:SMO的坐标下降法确实强大。现在用上了SMO,但依然计算消耗巨大,原因:需要优化的参数太多,大约(N*n_theta)*2 + n_theat+n_w 个参数。
目前是草稿版,只计算出了各个参数:
import numpy as np
from sklearn import datasets
import cvxpy as cp
class eSVM():
def __init__(self,X_train,y_train):
self.X = X_train
self.y = y_train
self.n_features = X_train.shape[1]
self.n_instances = X_train.shape[0]
self.n_class = len(set(self.y))
self.n_theta = self.n_class - 1
self.w = cp.Variable((self.n_features,1))
self.b = cp.Variable()
self.xi = cp.Variable((self.n_instances, self.n_theta))
self.theta = cp.Variable((1,self.n_class-1))
self.C = 1
self.Y = self.rcon_label()
def rcon_label(self):
target = []
for i in range(self.n_instances):
label = []
for j in range(self.n_theta):
if self.y[i] <= j:
a = 1
else:
a = 0
label.append(1 - 2 * a)
target.append(label)
return np.array(target)
def optimal(self):
#TODO:np.tile(self.theta,(self.n_instances,1))写错了
objective = cp.Minimize(0.5 * cp.norm2(self.w) + 0.5 * cp.norm(self.theta) + self.C * cp.sum(self.xi))
constraints = []
for i in range(self.n_instances):
for k in range(self.n_theta):
constraints += [self.Y[i,k] * cp.sum(cp.multiply(self.X[1].reshape(-1,1), self.w)) - self.Y[i, k] * self.theta[0][k] - self.Y[i,k] * self.b >= 1 - self.xi[i,k], self.xi[i,k]>=0]
prob = cp.Problem(objective, constraints)
result = prob.solve()
# print(prob.value)
print("w=",self.w.value)
print("b=",self.b.value)
print("theta=",self.theta.value)
if __name__ == '__main__':
X, y = datasets.make_blobs(n_samples=100, n_features=2, center_box=(-20, 20), centers=4, cluster_std=[4, 4, 4, 4], random_state=3)
print("数据类别信息",np.unique(y))
for i, ele in enumerate(y):
if ele == 3:
y[i] = 0
elif ele == 0:
y[i] = 2
elif ele == 2:
y[i] = 3
model = eSVM(X_train=X,y_train=y)
model.optimal()