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中大型数据集的文本分类的主要内容,如果未能解决你的问题,请参考以下文章

BERT-多标签文本分类实战之四——数据集预处理

BERT-多标签文本分类实战之四——数据集预处理

BERT-多标签文本分类实战之四——数据集预处理

大型多类 NLP 分类的不平衡数据和样本量

重要朴素贝叶斯分类器详解及中文文本舆情分析(附代码实践)

使用来自 LDA 的主题建模信息作为特征,通过 SVM 执行文本分类