使用Python和CPLEX进行SVM,加载目标函数的二次部分

”一般来说,批量创建线性约束的性能会比一次创建一个线性约束的性能更好。我只是想知道即使面对巨大的问题,是否也是如此。” – 一位睿智的程序员。

为了说明清楚,我有一个(35k x 40)的数据集,我想要对其进行SVM分析。我需要生成这个数据集的Gramm矩阵,这没问题,但将系数传递给CPLEX却是一团糟,需要几个小时,以下是我的代码:

    nn = 35000    XXt = np.random.rand(nn,nn) # 数据集的Gramm矩阵    yy = np.random.rand(nn)     # 数据集的标签向量    temp = ((yy*XXt).T)*yy    xg, yg = np.meshgrid(range(nn), range(nn))    indici = np.dstack([yg,xg])    quadraric_part = []    for ii in xrange(nn):        for indd in indici[ii][ii:]:            quadraric_part.append([indd[0],indd[1],temp[indd[0],indd[1]]])

‘quadratic_part’ 是一个形如 [i,j,c_ij] 的列表,其中 c_ij 是存储在 temp 中的系数。它将被传递给 CPLEX Python API 的 ‘objective.set_quadratic_coefficients()’ 函数。

有没有更明智的方法来做这件事?

附注:我可能有内存问题,所以最好不要存储整个 ‘quadratic_part’ 列表,而是多次调用 ‘objective.set_quadratic_coefficients()’ 函数……你明白我的意思吧?!


回答:

在幕后,objective.set_quadratic 使用了 C 可调用库中的 CPXXcopyquad 函数。而 objective.set_quadratic_coefficients 使用了 CPXXcopyqpsep

这里有一个例子(请注意,我不是numpy专家;可能有更好的方法来处理这部分):

import numpy as npimport cplexnn = 5  # 这里是一个小样本大小XXt = np.random.rand(nn,nn) # 数据集的Gramm矩阵yy = np.random.rand(nn)     # 数据集的标签向量temp = ((yy*XXt).T)*yy# 创建对称矩阵tempu = np.triu(temp)     # 上三角矩阵iu1 = np.triu_indices(nn, 1)tempu.T[iu1] = tempu[iu1] # 将上三角复制到下三角ind = np.array([[x for x in range(nn)] for x in range(nn)])qmat = []for i in range(nn):    qmat.append([np.arange(nn), tempu[i]])c = cplex.Cplex()c.variables.add(lb=[0]*nn)c.objective.set_quadratic(qmat)c.write("test2.lp")

你的Q矩阵是完全稠密的,因此根据你拥有的内存量,这种技术可能无法扩展。然而,当可能时,你应该通过使用 objective.set_quadratic 来初始化你的Q矩阵以获得更好的性能。或许你需要使用某种混合技术,同时使用 set_quadraticset_quadratic_coefficients

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注