【问题标题】:what can cause sklearn svm to hang, both cpu and mem usage are zero什么会导致 sklearn svm 挂起,cpu 和 mem 使用率都为零
【发布时间】:2017-12-25 10:01:22
【问题描述】:

我注意到使用 scikit learn 在输入维度为 24700 x 11200 的数据集上训练 svm 分类器时出现非常奇怪的行为。一旦拆分为训练/测试集,之后的训练数据部分就有 >18500 个样本。

我的代码如下所示:

def feature_scale(M):
    scaler = MinMaxScaler(feature_range=(0, 1))
    return scaler.fit_transform(M)

M = feature_extraction(....) # method to create the 24700x11200 matrix
X_train_data, X_test_data, y_train, y_test = \
            train_test_split(M, self.raw_data['class'],
                             test_size=0.25,
                             random_state=42)
X_train_data=feature_scale(X_train_data) 
X_test_data =feature_scale(X_test_data) 
y_train = y_train.astype(int)
y_test = y_test.astype(int)

classifier = svm.LinearSVC(class_weight='balanced', C=0.01, penalty='l2', loss='squared_hinge',multi_class='ovr')

print("### test sfm...")
fs=SelectFromModel(LogisticRegression(class_weight='balanced', penalty="l1", C=0.01))       
X_=fs.fit_transform(X_train, y_train)
print(np.count_nonzero(X_)) # LINE C0, prints: 23828534
print(X_.shape)             # LINE C0, prints: (18587, 1282), the product is exactly 23828534
print("### end \n\n\n")

#classifier.fit(X_, y_train_data) #LINE D


print("### test kb...")
fs=SelectKBest(k=1000, score_func=f_classif)
X_=fs.fit_transform(X_train, y_train)
print(np.count_nonzero(X_))  #LINE E0, prints (18587, 1000)
print(X_.shape)              #LINE E1, prints 18587000
print("### end \n\n\n")

M 是一个稀疏特征矩阵。首先,我加载一个 CSV 数据,其中每行是一个句子,有 24700 行(样本)。然后我调用一系列 NLP 过程来处理这些行,以提取 n-gram、pos 标签等特征,并将原始数据转换为 24700 x m 的特征矩阵,在这种情况下 m=11200。矩阵是稀疏的。

意见:(已针对回复进行了更新 - 对此表示感谢)

如您所见,代码测试了两种特征选择,一种使用 SelectFromModel,使用 LogisticRegression 算法;另一个使用 SelectKBest,使用 f_classif 评分功能。我已经测试了两者,以打印转换后的特征矩阵。

这两种方法都会创建一个每个元素都被填充的密集矩阵,唯一的区别是 SelectFromModel 生成一个包含 1282 个特征的矩阵,而 SelectKBest 生成一个包含 1000 个特征的矩阵。

我的第一个问题是:为什么这些特征矩阵是完全填充的?我希望它们很密集,但没有完全填满。

然后继续进一步测试代码,如果我把D行放回去,即在SelectFromModel转换后的特征矩阵上应用svm,问题就挂了,而CPU和内存都是0使用率。产生如下错误:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

但是,如果将 D 行放回,但移到 SelectKBest 之后,即,如果 svm 分类器使用 SelectKBest 创建的特征矩阵,则可以正常工作,没有任何错误。

所以我的第二个问题是两个转换后的特征矩阵之间的差异会导致 SVM 出现该错误,为什么会导致它挂起?我总共有 32G 内存。

更新:我注意到我运行实验的服务器没有交换。我分配了一个8G的swap,重新运行实验,现在注意到swap全部使用了:total=8191,used=8182,free=9。我想知道这是否表明之前没有足够的内存,并且由于某种原因,一段时间后系统只是挂起,甚至系统统计数据显示 CPU 和内存使用率为 0?

谢谢

【问题讨论】:

标签: scikit-learn


【解决方案1】:

您的代码缺少一些细节,尤其是 M 的来源。我也不知道util.feature_scale()是基于,但这里有些猜测:

  • Memory-trashing 是我 99.9% 的案例中使用悬挂系统的原因!
    • 意思:你的可用内存可能已被完全填满,会发生垃圾处理
    • 通过观察系统统计数据很容易(粗略地)分析

那么为什么一种方法是垃圾,而另一种则不是?

  • 我认为您的原始数据集可能是sparse-matrix
    • 该矩阵的密集版本可能大得吓人
    • GridSearch 中每个进程 2 GB! (将线性相乘 + 一些常量,具体取决于 job_dispatch 参数)
  • 此外:大多数数据预处理方法都会杀死稀疏数据!(您将失去稀疏性 -> 非零的数量增加)
    • 通常:稀疏输入 -> 密集输出(在最坏的情况下:仍存储为稀疏矩阵)
    • 例如减去平均值!

所以:

  • (1) 观察你的记忆
  • (2) 检查矩阵类型和统计信息(例如使用numpy.count_nonzero
  • (3) 检查您的预处理理论

【讨论】:

  • 谢谢,我已经对此进行了更多测试并更新了我的帖子,非常感谢任何反馈
  • @Ziqi Everything 你添加/编辑的仍然指向我说的内存问题。我什至给了你不同行为的原因(没有分析你使用的算法)。所以有什么问题?通读这些算法的文档,检查它们之间的大小,你就会理解每一个细节(我已经在我的回答中暗示了这些步骤)。您可能甚至没有检查 GridSearch 的效果(这并不像预期的那么简单 -> job_dispatch)
【解决方案2】:

首先尝试获取数据矩阵的小样本,例如 1000x100 行 x 特征。用这个小矩阵做所有的计算,看看它是否工作没有错误。

【讨论】:

  • 是的,它确实有效。我一直在一个较小的集合上进行开发,因为整个矩阵会导致问题,我现在只能在这个较小的集合上进行测试......
  • 好的,现在尝试找到数据的最大工作大小。当您可以划分行时,对工作数据集进行训练和预测,并在最后平均所有预测。以防万一找不到使原始代码工作的方法。
  • 好吧……理论上这应该可行,但唯一的问题是训练只看到整个数据集的部分图片,并且与“完整”训练可能存在一些差异?跨度>
  • 刚刚又更新了,不知道是不是内存不足?
  • 将数据分割成小的子集并平均结束是应对内存不足的最实用的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
相关资源
最近更新 更多