python中大型数据集的文本分类
Posted
技术标签:
【中文标题】python中大型数据集的文本分类【英文标题】:text classification of large dataset in python 【发布时间】:2018-05-17 02:52:51 【问题描述】:我有 220 万个数据样本可以分为 7500 多个类别。我正在使用 pandas 和 sckit-learn of python 来做到这一点。
以下是我的数据集示例
itemid description category
11802974 SPRO VUH3C1 DIFFUSER VUH1 TRIPLE Space heaters Architectural Diffusers
10688548 ANTIQUE BRONZE FINISH PUSHBUTTON switch Door Bell Pushbuttons
9836436 Descente pour Cable tray fitting and accessories Tray Cable Drop Outs
以下是我遵循的步骤:
-
预处理
矢量表示
培训
dataset=pd.read_csv("trainset.csv",encoding = "ISO-8859-1",low_memory=False)
dataset['description']=dataset['description'].str.replace('[^a-zA-Z]', ' ')
dataset['description']=dataset['description'].str.replace('[\d]', ' ')
dataset['description']=dataset['description'].str.lower()
stop = stopwords.words('english')
lemmatizer = WordNetLemmatizer()
dataset['description']=dataset['description'].str.replace(r'\b(' + r'|'.join(stop) + r')\b\s*', ' ')
dataset['description']=dataset['description'].str.replace('\s\s+',' ')
dataset['description'] =dataset['description'].apply(word_tokenize)
ADJ, ADJ_SAT, ADV, NOUN, VERB = 'a', 's', 'r', 'n', 'v'
POS_LIST = [NOUN, VERB, ADJ, ADV]
for tag in POS_LIST:
dataset['description'] = dataset['description'].apply(lambda x:
list(set([lemmatizer.lemmatize(item,tag) for item in x])))
dataset['description']=dataset['description'].apply(lambda x : " ".join(x))
countvec = CountVectorizer(min_df=0.0005)
documenttermmatrix=countvec.fit_transform(dataset['description'])
column=countvec.get_feature_names()
y_train=dataset['category']
y_train=dataset['category'].tolist()
del dataset
del stop
del tag
生成的文档术语矩阵将是 scipy csr 矩阵类型,具有 12k 个特征和 220 万个样本。
我尝试使用 xgboost 的 sckit learn 进行培训
model = XGBClassifier(silent=False,n_estimators=500,objective='multi:softmax',subsample=0.8)
model.fit(documenttermmatrix,y_train,verbose=True)
执行上述代码 2-3 分钟后出现错误
OSError: [WinError 541541187] Windows Error 0x20474343
我还尝试了 sckit learn 的朴素贝叶斯,但我得到了内存错误
问题
我使用了 Scipy 矩阵,它消耗的内存非常少,而且我在执行 xgboost 或 Naive bayes 之前删除了所有未使用的对象,我正在使用具有 128GB RAM 的系统,但在训练时仍然遇到内存问题.
我是 python 新手。我的代码有什么问题吗? 谁能告诉我如何有效地使用内存并继续前进?
【问题讨论】:
(1)朴素贝叶斯:检查documenttermmatrix=countvec.fit_transform(dataset['description'])
后面的类型。文档表明它很密集,而手动调用 transform 会很稀疏。这听起来很疯狂,就像一个糟糕的设计决策。检查! (2) XGBoost:我认为内部使用了密集向量(用于特征?)!
documenttermmatrix.shape Out[26]: (2346724, 12520)type(documenttermmatrix) Out[28]: scipy.sparse.csr.csr_matrix
【参考方案1】:
我想我可以在您的代码中解释问题所在。 操作系统错误似乎是:
"
ERROR_DS_RIDMGR_DISABLED
8263 (0x2047)
目录服务检测到分配相对标识符的子系统已禁用。当系统确定相当一部分的相关标识符 (RID) 已用尽时,这可以作为一种保护机制发生。
" 通过https://msdn.microsoft.com/en-us/library/windows/desktop/ms681390
我认为您在代码中的这一步用尽了很大一部分 RID:
dataset['description'] = dataset['description'].apply(lambda x:
list(set([lemmatizer.lemmatize(item,tag) for item in x])))
您在 lambda 中传递了一个词形还原器,但 lambda 是匿名的,因此看起来您可能会在运行时制作 220 万个该词形还原器的副本。
当您遇到内存问题时,您应该尝试将 low_memory 标志更改为 true。
回复评论-
我查看了 Pandas 文档,您可以在 dataset['description'].apply() 之外定义一个函数,然后在对 dataset['description'].apply() 的调用中引用该函数。以下是我将如何编写所述函数。
def lemmatize_descriptions(x):
return list(set([lemmatizer.lemmatize(item,tag) for item in x]))
然后,对 apply() 的调用将是-
dataset['description'] = dataset['description'].apply(lemmatize_descriptions)
Here is the documentation.
【讨论】:
我将 low_memory 标志更改为 true,但仍然出现错误OSError: [WinError 541541187] Windows Error 0x20474343
有什么方法可以删除 lambda 函数创建的数据副本?
我在对原始答案的编辑中添加了对您评论的回复。以上是关于python中大型数据集的文本分类的主要内容,如果未能解决你的问题,请参考以下文章