Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ScikitLearn回归:设计矩阵X对于回归来说太大了。我该怎么办?_Python_Numpy_Matrix_Scikit Learn_Regression - Fatal编程技术网

Python ScikitLearn回归:设计矩阵X对于回归来说太大了。我该怎么办?

Python ScikitLearn回归:设计矩阵X对于回归来说太大了。我该怎么办?,python,numpy,matrix,scikit-learn,regression,Python,Numpy,Matrix,Scikit Learn,Regression,我有一个矩阵X,大约有7000列和38000行。因此,它是一个numpy数组,形状(380007000) 我实例化了模型 model = RidgeCV(alphas = (0.001,0.01, 0.1, 1) 然后装上它 model.fit(X, y) 其中,y是响应向量,它是一个形状为(38000,)的numpy数组 通过运行此命令,我得到一个内存错误 我怎样才能解决这个问题 我的想法 我的第一个想法是“水平”分割矩阵X。我的意思是,我把X分成两个矩阵,两个矩阵的列数相同(因此保留了所

我有一个矩阵
X
,大约有7000列和38000行。因此,它是一个
numpy数组
,形状
(380007000)

我实例化了模型

model = RidgeCV(alphas = (0.001,0.01, 0.1, 1)
然后装上它

model.fit(X, y)
其中,
y
是响应向量,它是一个形状为
(38000,)
的numpy数组

通过运行此命令,我得到一个
内存错误

我怎样才能解决这个问题

我的想法

我的第一个想法是“水平”分割矩阵X。我的意思是,我把X分成两个矩阵,两个矩阵的列数相同(因此保留了所有特征),但行数较少。那么我每次都要为每个子矩阵拟合模型?但恐怕这并不等于拟合整个矩阵


有什么想法吗?

这是一个众所周知的问题,可以通过核心外学习来解决。通过谷歌搜索这个词,你会发现解决这个问题的几种方法

对于您的特定问题,首先必须创建一个生成器,生成矩阵的一行(或多行),然后使用算法的
partial\u fit
方法

scikit learn的标准算法实际上使用了解的精确计算,如
sklearn.linear\u model.LinearRegression
sklearn.linear\u model.LinearRegression.RidgeCV
。其他方法基于批量学习,并具有
部分拟合
方法,如
sklearn.linear\u model.SGDRegressor
,只允许拟合小批量。这就是你要找的

过程是:使用生成器生成一个小批量,应用
partial_fit
方法,从内存中删除该小批量并获取一个新的


但是,由于此方法是随机的,并且取决于数据的顺序和权重的初始化,因此与标准回归方法给出的解决方案相反,标准回归方法可以拟合内存中的所有数据。我将不详细介绍,但看看梯度下降优化,了解它是如何工作的()

在我看来,这并不是非常大规模,您可能不需要在这里使用核心外学习(尽管我不知道您有多少内存)

在不需要时使用核心外的方法,您将付出代价(如果不进行大量调优,则不健壮)

了解您的特征是稀疏的还是密集的也很有趣,这会产生巨大的差异(因为大多数解算器都可以利用稀疏数据!)

这里有几句话要说:

  • 使用一些问题调整的交叉验证方法,可能因为这个原因,没有用于控制底层解算器的参数
    • 当有效的热启动有助于过程(性能)时,使用问题调整CV方法并不少见
  • 手动执行CV时,sklearn中提供了所有工具,您可以选择不同的工具
    • 这些在方法和特点上都有很大的不同
解算器:{'auto','svd','cholesky','lsqr','sparse_cg','sag','saga'}

要在计算例程中使用的解算器:

“自动”根据数据类型自动选择解算器

“svd”使用X的奇异值分解来计算脊线系数。奇异矩阵比“cholesky”更稳定

“cholesky”使用标准的scipy.linalg.solve函数来获得封闭形式的解

“sparse_cg”使用scipy.sparse.linalg.cg中的共轭梯度解算器。作为一种迭代算法,该解算器比“cholesky”更适用于大规模数据(可能设置tol和max_iter)

“lsqr”使用专用的正则化最小二乘例程scipy.sparse.linalg.lsqr。它是最快的,但在旧的scipy版本中可能不可用。它还使用一个迭代过程

“sag”使用随机平均梯度下降,“saga”使用其改进的无偏版本saga。这两种方法还使用迭代过程,并且当n_样本和n_特征都较大时,通常比其他解算器更快。请注意,“sag”和“saga”快速收敛仅在具有大致相同比例的特征上得到保证。您可以使用sklearn.preprocessing中的定标器对数据进行预处理

最后五个解算器都支持密集和稀疏数据。但是,只有“sag”和“saga”在fit_intercept为真时支持稀疏输入

因此,我强烈建议尝试:
稀疏cg
或者可能
lsqr
与手动CV一起使用。如果这样做有效(对我来说非常好),我希望,这种方法更加稳定/稳健(与使用SGD的核心外方法相比),并且您不需要对其参数进行太多调整,这是一个巨大的优势

当然,人们总是可以使用
sag
sgd
,但收敛理论是基于一些关于参数调整的强大假设。在非常大规模的环境中,这两个都是可行的候选人(因为其他人不起作用),但在这里我看不到多少merrit(同样:我不确定你有多少内存)。如果上述方法不起作用,请在sgd之前尝试saga,并遵守规则(标准化+参数调整)。(edit:sag对我的测试数据来说非常糟糕!)

例如:

from sklearn.datasets import make_regression
from sklearn.linear_model import Ridge
from time import perf_counter

X, y, = make_regression(n_samples=38000, n_features=7000, n_informative=500,
                        bias=-2.0, noise=0.1, random_state=0)

print(type(X))  # dense!!! if your data is sparse; use that fact!

clf = Ridge(alpha=1.0, solver="lsqr")
start = perf_counter()
clf.fit(X, y)
end = perf_counter()
print('LSQR: used secs: ', end-start)
输出:

LSQR: used secs:  8.489622474064486
LSQR: used secs:  0.08252486090450709
train-score:  0.999999907282
sparse_cg: used secs:  0.13668818702548152
train-score:  0.999999181151
SGD: used secs:  0.04154542095705427
train-score:  0.743448766459
SGD: used secs:  0.05300238587407993
train-score:  0.774611911034
SGD: used secs:  0.038653031605587
train-score:  0.733585661919
SGD: used secs:  0.46313909066321507
train-score:  0.776444474871
因此,即使在高密度的情况下,优化也不难(并且使用了约6-8GB的内存)

虽然我会小心地暗示Ridge模型和以下基于SGD的Ridge模型之间的等价性(小心哪个变量是正则化的一部分;太懒了以至于无法检查),但这里只是一个演示如何调整SGD。把这个和一粒盐一起吃(和
LSQR: used secs:  0.08252486090450709
train-score:  0.999999907282
sparse_cg: used secs:  0.13668818702548152
train-score:  0.999999181151
SGD: used secs:  0.04154542095705427
train-score:  0.743448766459
SGD: used secs:  0.05300238587407993
train-score:  0.774611911034
SGD: used secs:  0.038653031605587
train-score:  0.733585661919
SGD: used secs:  0.46313909066321507
train-score:  0.776444474871