含稀疏与数值特征的NLP分类任务崩溃问题及优化咨询
问题解答
疑问2:转密集矩阵后笔记本崩溃是否为内存问题?
是,完全是内存问题。
你当前的特征矩阵是971426行 × 10001列,转成密集矩阵后,每个浮点数按8字节计算,总内存占用约为:971426 * 10001 * 8 ≈ 77.7GB
普通笔记本的内存通常在8-32GB之间,根本无法承载这么大的密集矩阵,因此会直接导致内存溢出、系统崩溃。而稀疏矩阵仅存储非零值,TF-IDF生成的矩阵本身非零比例极低,内存占用远小于密集矩阵,所以仅用稀疏矩阵时能正常运行。
疑问1:稀疏矩阵与数值列的更优合并方法
最优方案是保持稀疏格式合并特征,不要将稀疏矩阵转为密集矩阵。具体可以用scipy.sparse.hstack将TF-IDF稀疏矩阵与归一化后的duration列(转为稀疏格式)合并,得到的整体矩阵依然是稀疏的,既节省内存,又能直接输入scikit-learn的LogisticRegression模型(该模型原生支持稀疏矩阵输入,且对稀疏数据有训练优化)。
修改后的核心代码
import scipy.sparse def get_training_data(df): df = shuffle(pd.read_csv(df).dropna()) data = df[['name_title', 'Duration']] # 归一化duration并转为稀疏矩阵 X_duration = normalize(data, col='Duration') X_duration_sparse = scipy.sparse.csr_matrix(X_duration) # 生成TF-IDF稀疏矩阵 X_sparse = tfidf(data, col='name_title') # 稀疏矩阵横向合并 X = scipy.sparse.hstack([X_sparse, X_duration_sparse]) y = df['target'] return X, y def logistic_regression(X, y): X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle=True) lr = LogisticRegression(C=100.0, random_state=1, solver='lbfgs', multi_class='ovr', n_jobs=-1) # 注:n_jobs=-1可利用多核加速训练,针对大样本更友好 lr.fit(X_train, y_train) y_predict = lr.predict(X_test) print(y_predict) print("Logistic Regression Accuracy %.3f" % metrics.accuracy_score(y_test, y_predict))
额外优化建议
- 无需提前shuffle数据:
train_test_split默认会shuffle数据(shuffle=True),可以去掉开头的shuffle(pd.read_csv(...)),减少内存开销。 - 针对大样本调整LogisticRegression参数:使用
solver='saga'替代lbfgs,saga求解器对大样本和稀疏数据的训练效率更高,且支持L1正则化。
内容的提问来源于stack exchange,提问作者Sharhad Bashar
相关产品推荐
相关产品推荐

