在当今数字化时代,数据无处不在,其中超过80%的数据是非结构化的——它们要么存储在数据孤岛中,要么散布在数字档案中。从社交媒体上的每一次对话到新闻来源生成的每条内容,数据的产生从未停止。要从这些数据中提取有意义的可操作性见解,了解如何处理非结构化形式的数据至关重要。作为一名数据科学家,在一家快速成长的决策科学公司工作,主要职责就是从非结构化的文本信息中提取有意义的见解。
处理文本数据的首要步骤是预处理。在数据准备好进行分析之前,这是一个必不可少的步骤。大多数可用的文本数据本质上是高度非结构化和嘈杂的——为了获得更好的见解或构建更好的算法,处理干净的数据是必要的。例如,社交媒体数据是非结构化的——它是一种非正式的交流方式——拼写错误、糟糕的语法、俚语的使用、不需要的内容(如URLs、停用词、表情等)是常见的问题。
以下是可以采取的步骤:
从网络获取的数据通常包含许多HTML实体,如<、>和&,这些实体嵌入在原始数据中。因此,去除这些实体是必要的。一种方法是直接使用特定的正则表达式来移除它们。另一种方法是使用适当的包和模块(例如Python的htmlparser),它们可以将这些实体转换为标准的HTML标签。例如:<转换为“<”,&转换为“&”。
import html
text = html.unescape(text)
这是将信息从复杂符号转换为简单、易于理解的字符的过程。文本数据可能受到不同形式的解码,如“Latin”、“UTF8”等。因此,为了更好的分析,保持完整的数据在标准的编码格式中是必要的。UTF-8编码被广泛接受,推荐使用。
tweet = original_tweet.decode("utf8").encode('ascii', 'ignore')
为了避免文本中的词义消歧,建议保持文本结构的完整性,并遵守上下文无关文法的规则。当使用撇号时,消歧的机会增加。例如,“it’s”是“it is”或“it has”的缩写。所有撇号都应该转换为标准的词汇表。可以使用一个包含所有可能键的查找表来消除歧义。
APPOSTOPHES = {"'s": " is", "'re": " are", ...}
words = tweet.split()
reformed = [APPOSTOPHES[word] if word in APPOSTOPHES else word for word in words]
reformed = " ".join(reformed)
当数据分析需要在单词级别进行时,应该去除常见的出现频率高的词(停用词)。可以创建一个长的停用词列表,或者可以使用预定义的语言特定的库。
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
filtered_words = [word for word in words if word not in stop_words]
所有标点符号应根据优先级处理。例如:“.”、“,”、“?”是重要的标点符号,应该保留,而其他需要被移除。
import string
text = text.translate(str.maketrans('', '', string.punctuation))
文本数据(通常是语音转录)可能包含人类表情,如[笑]、[哭泣]、[观众暂停]。这些表情通常与演讲内容无关,因此需要被移除。简单的正则表达式在这种情况下很有用。
import re
text = re.sub(r'\[.*?\]', '', text)
在社交媒体论坛上生成的文本数据完全是非正式的。大多数推文都伴随着多个连接的单词,如RainyDay、PlayingInTheCold等。这些实体可以使用简单的规则和正则表达式分割成它们的正常形式。
cleaned = " ".join(re.findall('[A-Z][^A-Z]*', original_tweet))
社交媒体包含大多数俚语单词。这些单词应该转换为标准单词,以使自由文本。像luv这样的词将被转换为love,Helo转换为Hello。可以使用类似撇号查找的方法将俚语转换为标准单词。网络上有许多来源提供所有可能的俚语列表,这将是宝典,可以使用它们作为查找字典进行转换。
_slang_loopup = {"luv": "love", "Helo": "Hello", ...}
tweet = _slang_loopup.get(tweet, tweet)
有时单词不在正确的格式中。例如:“I looooveee you”应该是“I love you”。简单的规则和正则表达式可以帮助解决这些情况。
import itertools
tweet = ''.join(''.join(s)[:2] for _, s in itertools.groupby(tweet))
text = re.sub(r'http\S+', '', text)