【发布时间】: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