浅谈NLP 文本分类/情感分析 任务中的文本预处理工作

前言

之所以心血来潮想写这篇博客,是因为最近在关注NLP文本分类这类任务中的文本预处理工作,想总结一下自己的所学所想,老规矩,本博文记载仅供备忘与参考,不具备学术价值,本文默认使用python3编程(代码能力是屎山级别的,请谅解),默认文本为英文,代码主要使用Pytorch(博主老笨蛋了,之前一直执迷不悟用Keras,现在刚刚开始用torch,怎么说呢,挺香的 XD)

NLP相关的文本预处理

NLP文本预处理一直是一个很受关注的问题,当下最常用的文本预处理工具当属nltk,功能统一,api也很简单,安装的话直接输入:

pip install nltk
python#进入python
import nltk
nltk.download()#下载需要的内容

一般来讲,最简单最常见的预处理就是把一整段文本分词化(Tokenize),对于一段文本(Sentence),可以直接调用nltk库功能将其分词化,返回结果为一个词表(word list)。

import nltk# 为方便,任何import都只在所有代码块中出现一遍,以后的也同理
word_list=nltk.word_tokenize(sentence)

一般来讲在预处理数据的时候还会选择去除标点以及不需要的url等等内容,因此我在自己做实验的时候选择使用以下配置来作为基础的预处理方法。

import string
import re PUNCT_TO_REMOVE = string.punctuation
url_pattern = re.compile(r'https?://\S+|www\.\S+')
sentence=url_pattern.sub(r'', sentence)
#remove punc
sentence=sentence.translate(str.maketrans('', '', PUNCT_TO_REMOVE))
tmp_word_list=nltk.word_tokenize(sentence)
word_list=[]
for word in tmp_word_list:
#lower
word=word.lower()
word_list.append(word)

事实上,文本预处理的方法是非常多样的,根据下边代码块中的参考内容链接,你可以找到各种各样数十种有针对性或者泛用的预处理方法,有的是为了处理Twitter中的一些tag,有的是是为了对文本进行词根化,有的是为了将双重否定转换成肯定……总而言之,一切预处理方法都是为了使得NLP任务更好地被执行,使得数据集更容易也更好地被训练。因此在我们针对NLP任务选择预处理方法时也应当注意选择合适的方法。如果我们在一个新闻数据集中使用去除Twitter中tag的预处理方法进行处理的话只会浪费时间。

# 参考链接
https://medium.com/sciforce/text-preprocessing-for-nlp-and-machine-learning-tasks-3e077aa4946e
https://towardsdatascience.com/all-you-need-to-know-about-text-preprocessing-for-nlp-and-machine-learning-bc1c5765ff67
https://towardsdatascience.com/nlp-text-preprocessing-a-practical-guide-and-template-d80874676e79
https://www.kaggle.com/sudalairajkumar/getting-started-with-text-preprocessing
https://www.kaggle.com/theoviel/improve-your-score-with-text-preprocessing-v2
https://medium.com/datadriveninvestor/data-cleaning-character-encoding-b4e0e9c65b2a
https://github.com/Deffro/text-preprocessing-techniques/blob/master/techniques.py

当然,很多预处理方法在常见的场合并不适用,例如文本中表情处理在Reuters新闻分类以及IMDB情感分析等常用任务上就没有什么用处。

为此我总结了5个我认为常用的预处理方法在下面的代码中

# 1. stem词根化
porter = nltk.stem.porter.PorterStemmer()
tmp_word_list=nltk.word_tokenize(sentence)
word_list=[]
for word in tmp_word_list:
word=porter.stem(word)
word_list.append(word) # 2. spell check拼写检查
# pip install pyspellchecker
from spellchecker import SpellChecker
spell=SpellChecker()
tmp_word_list=nltk.word_tokenize(sentence)
word_list=[]
for word in tmp_word_list:
#lower
misspelled_words = spell.unknown(word.split())
if word in misspelled_words:
word_list.append(spell.correction(word))
else:
word_list.append(word) # 3. negation否定词替换
token=nltk.word_tokenize(token)
word_list=[]
i, l = 0, len(token)
while i < l:
word = token[i]
if word == 'not' and i+1 < l:
ant = replace(token[i+1])
if ant:
word_list.append(ant)
i += 2
continue
word_list.append(word)
i += 1 def replace(self,word, pos=None):
""" Creates a set of all antonyms for the word and if there is only one antonym, it returns it """
antonyms = set()
for syn in nltk.corpus.wordnet.synsets(word, pos=pos):
for lemma in syn.lemmas():
for antonym in lemma.antonyms():
antonyms.add(antonym.name())
if len(antonyms) == 1:
return antonyms.pop()
else:
return None # 4. stop word 停用词替换
stops_list = set(nltk.corpus.stopwords.words('english'))
tmp_word_list=nltk.word_tokenize(token)
word_list=[]
for word in tmp_word_list:
if word not in stops_list:
word_list.append(word) # 5. contraction 连接词分离
# pip install contractions
import contractions as ctr
tmp_word_list=token.split(' ')
word_list=[]
for word in tmp_word_list:
word=ctr.fix(word)
tmp=nltk.word_tokenize(word)
for w in tmp:
word_list.append(w)

今天暂时更到这里,后续把自己做实验遇到的其他一些有趣内容补上

浅谈NLP 文本分类/情感分析 任务中的文本预处理工作的更多相关文章

  1. 浅谈layer.open的弹出层中的富文本编辑器为何不起作用!

    很多童鞋都喜欢用贤心的layui框架.是的,我也喜欢用,方便,简单.但是呢,有时候项目中的需求会不一样,导致我们用的时候,显示效果可能会不一样,好吧.这样的话,个别遇到的问题总是解决不好,但是呢还是那 ...

  2. 浅谈PHP随机数安全的分析

    之前在身边有很多学PHP的朋友写一些小程序的时候,很多时候会使用PHP随机数函数rand()和mt_rand()函数去生成随机数 可是,随机数真的随机吗?这篇文章讲从多个实例中探讨随机数,当然,有写作 ...

  3. <转载>浅谈C/C++的浮点数在内存中的存储方式

    C/C++浮点数在内存中的存储方式 任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100.则在Intel CPU架构的系统中 ...

  4. 浅谈Windows下SVN在Android Studio中的配置、基本使用及解除关联

    看到网上很多关于svn环境配置和关联Android-Studio的很多博文,发现很零散,想集大家所长整理一下: 在AndroidStudio中开发版本控制中,除了Git就是SVN,和Eclipse不同 ...

  5. 浅谈如何使用python抓取网页中的动态数据

    我们经常会发现网页中的许多数据并不是写死在HTML中的,而是通过js动态载入的.所以也就引出了什么是动态数据的概念, 动态数据在这里指的是网页中由Javascript动态生成的页面内容,是在页面加载到 ...

  6. 浅谈Excel开发:十 Excel 开发中与线程相关的若干问题

    采用VSTO或者Shared Add-in等技术开发Excel插件,其实是在与Excel提供的API在打交道,Excel本身的组件大多数都是COM组件,也就是说通过Excel PIA来与COM进行交互 ...

  7. 浅谈Excel开发:九 Excel 开发中遇到的常见问题及解决方法

    Excel开发过程中有时候会遇到各种奇怪的问题,下面就列出一些本人在开发中遇到的一些比较典型的问题,并给出了解决方法,希望对大家有所帮助. 一 插件调试不了以及错误导致崩溃的问题 在开发机器上,有时可 ...

  8. 浅谈Bootstrap自适应功能在Web开发中的应用

    随着移动端市场的强势崛起,web的开发也变得愈发复杂,对于个体开发者来说,自己开发的网站,在电脑.手机.Pad等上面都要有正常的显示以及良好的用户体验.如果每次都要自己去调整网页去匹配各个不同的客户端 ...

  9. python 之文本搜索与替换文件中的文本

    #!/usr/local/env python import os, sys nargs = len(sys.argv) if not 3 <= nargs <= 5: print &qu ...

随机推荐

  1. oracle adf 入门

    入门必踩坑 坑1:jdeveloper里没有mysql的driver,在maven库里引入了,connection里连接正常,但是deploy出错,can't load driver.即使在项目和to ...

  2. JVM学习(二)JVM加载类

    一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  3. 2020DASCTF八月浪漫七夕战

    安恒大学 注入点在邮箱注册那里,无法复现了,提一下 ezflask 源代码 #!/usr/bin/env python # -*- coding: utf-8 -*- from flask impor ...

  4. xss的编码原理

    把以前的笔记翻出来整理一下 最前方 xss如何选用编码原理,为什么 找到的挺清楚的文章了:https://www.cnblogs.com/p0laris/p/11898322.html浏览器解析有两种 ...

  5. 阿里内部推出Spring响应式微服务Boot2Cloud文档

    今天要给大家推荐的是Spring响应式微服务SpringBoot2+Spring5+SpringCloud实战的内容,将从目录.主要内容和面向的读者三部分给大家介绍,希望大家能够喜欢!!!(本文整理自 ...

  6. 每日一个知识点:Volatile 和 CAS 的弊端之总线风暴

    每日一个知识点系列的目的是针对某一个知识点进行概括性总结,可在一分钟内完成知识点的阅读理解,此处不涉及详细的原理性解读. 一.什么是总线风暴 总线风暴,听着真是一个帅气的词语,但如果发生在你的系统上那 ...

  7. 你在开发过程中使用Git Rebase还是Git Merge?

    摘要:在git里面经常的一个争论是到底用rebase还是用merge? 1. 痛苦吗?代码历史中的迷失羔羊 我们先来看一个真实的代码提交历史图形化截图: 图片源自 https://storage.kr ...

  8. Vue学习笔记使用系列一【表单】

    脚手架的搭建,请查看另外一篇日记:https://www.cnblogs.com/Fengge518/p/11837078.html 1:直接代码了 1 <!DOCTYPE html> 2 ...

  9. LightningChart运行互动示例介绍

    LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点. LightningChart包括广泛的2D,高级3D,Polar,Smith,3D ...

  10. centos7修改ssh端口及添加ssh监听端口

    ssh 修改默认端口 [root@node-1 ~]# vi /etc/ssh/sshd_config 修改port 为 5522 重启[root@node-1 ~]# systemctl resta ...