做者 | Viet Hoang Tran Duongphp
来源 | DeepHub IMBApython
头图 | CSDN付费下载于视觉中国git
数据是新的石油,文本是咱们须要更深刻钻探的油井。文本数据无处不在,在实际使用以前,咱们必须对其进行预处理,以使其适合咱们的需求。对于数据也是如此,咱们必须清理和预处理数据以符合咱们的目的。这篇文章将包括一些简单的方法来清洗和预处理文本数据以进行文本分析任务。
github
咱们将在Covid-19 Twitter数据集上对该方法进行建模。这种方法有3个主要组成部分:数组
首先,咱们要清理和过滤全部非英语的推文/文本,由于咱们但愿数据保持一致。安全
其次,咱们为复杂的文本数据建立一个简化的版本。app
最后,咱们将文本向量化并保存其嵌入以供未来分析。机器学习
清理和过滤文本
首先,为了简化文本,咱们要将文本标准化为仅为英文字符。此函数将删除全部非英语字符。函数
def clean_non_english(txt): txt = re.sub(r'\W+', ' ', txt) txt = txt.lower() txt = txt.replace("[^a-zA-Z]", " ") word_tokens = word_tokenize(txt) filtered_word = [w for w in word_tokens if all(ord(c) < 128 for c in w)] filtered_word = [w + " " for w in filtered_word] return "".join(filtered_word)
咱们甚至能够经过删除中止词来作得更好。停词是出如今英语句子中对意思没有多大帮助的常见词。咱们将使用nltk包来过滤stopwords。因为咱们的主要任务是使用word cloud将tweet的主题可视化,因此这一步须要避免使用“the,”“a,”等常见单词。可是,若是你的任务须要完整的句子结构,好比下一个单词预测或语法检查,你能够跳过这一步。性能
import nltk nltk.download('punkt') # one time execution nltk.download('stopwords') from nltk.corpus import stopwords stop_words = set(stopwords.words('english'))def clean_text(english_txt): try: word_tokens = word_tokenize(english_txt) filtered_word = [w for w in word_tokens if not w in stop_words] filtered_word = [w + " " for w in filtered_word] return "".join(filtered_word) except: return np.nan
对于tweets,在清理以前咱们须要考虑一个特殊的特性:说起@。您的数据可能具备这样的特殊特性(也可能没有),这是具体状况,而不是广泛要求。所以,在盲目地清理和预处理数据以前,要充分了解您的数据!
def get_mention(txt): mention = [] for i in txt.split(" "): if len(i) > 0 and i[0] == "@": mention.append(i) return "".join([mention[i] + ", " if i != len(mention) - 1 else mention[i] for i in range(len(mention))]
之前,咱们清理非英文字符。如今,咱们删除非英语文本(语义上)。Langdetect是一个python包,它容许检查文本的语言。它是谷歌的语言检测库从Java到Python的直接端移植。
from langdetect import detect def detect_lang(txt): try: return detect(txt) except: return np.nan
而后咱们过滤掉全部不是“en”语言的列。
简化复杂的数据
对于数值数据,良好的处理方法是缩放,标准化和规范化。此资源有助于理解并将这些方法应用于您的数据。在本文的讨论范围内,因为其余资源在此方面作得很好,所以我将不作进一步讨论。
对于分类数据,有许多方法。两种名义上的方法是标签编码器(为每一个标签分配一个不一样的编号)和一种热编码(以0和1的向量表示)。有关这些分类值的方法的更多详细信息,请参见此处。与我提到的这两种资源相比,此资源很是丰富,具备更多类型的编码。
这篇文章将介绍一些减小数据特别是位置数据复杂性的方法。在个人数据集中,有一列位置,带有做者的地址。可是,因为这些原始数据过于混乱和复杂(具备城市,县,州,国家/地区),所以我没法对其进行太多分析。所以,咱们能够将文本标准化,并将其缩小到“国家”级别。处理位置数据的程序包是geopy。它能够识别正确的地址并将这些位置从新格式化为标准格式。而后,您能够选择保留所需的任何信息。对我来讲,国家,国家足够体面。
from geopy.geocoders import Nominatim geolocator = Nominatim(user_agent="twitter")def get_nation(txt): try: location = geolocator.geocode(txt) x = location.address.split(",")[-1] return x except: return np.nan
向量化和嵌入
文本向量化将文本转换为值的向量以表示其含义。早些时候,咱们有一种热编码方法,其向量的大小与咱们的词汇量相同,在出现文本的任何地方都为1,在其余地方为0。现在,咱们拥有更高级的方法,例如spacy,GloVe甚至bert嵌入。对于本项目的范围,我将向您介绍python和Jupiter笔记本中的GloVe。
首先,咱们下载嵌入向量。您能够在此处手动下载或直接在笔记本中进行下载。
!wget http://nlp.stanford.edu/data/glove.6B.zip !unzip glove*.zip
而后,咱们建立一个向量矢量化每一个数据点的函数。句子是每一个单词的平均表示。对于空句子,咱们将其默认为零向量。
def vectorize(value, word_embeddings, dim = 100): sentences = value.to_list() sentence_vectors = [] for i in sentences: if len(i) != 0: v = sum([word_embeddings.get(w, np.zeros((dim,))) for w in i.split()])/(len(i.split())+0.001) else: v = np.zeros((dim,)) sentence_vectors.append(v) sentence_vectors = np.array(sentence_vectors) return sentence_vectors
最后,咱们对整个数据集进行矢量化处理,并将矢量化的numpy数组另存为文件,所以咱们没必要在每次运行代码时都再次进行此过程。矢量化版本将以.npy文件的形式保存为numpy数组。Numpy包方便存储和处理海量数组数据。
做为个人我的标准作法,我尝试将每一个部分以后的全部数据保存为单独的文件,以评估数据并更灵活地更改代码。
def vectorize_data(data = data, value = 'english_text', dim = 100): # Extract word vectors word_embeddings = {} f = open('glove.6B.{}d.txt'.format(str(dim)), encoding='utf-8') for line in f: values = line.split() word = values[0] coefs = np.asarray(values[1:], dtype='float32') word_embeddings[word] = coefs f.close() text_vec = vectorize(data[value], word_embeddings, dim) np.save("vectorized_{}.npy".format(str(dim)), text_vec) print("Done. Data:", text_vec.shape) return True
总结
数据预处理,特别是文本预处理,多是一个很是麻烦的过程。机器学习工程师工做流程的很大一部分将用于这些清理和格式化数据(若是您的数据已经彻底清理好了,那么,幸运的是,对于全部实现这一目标的工程师来讲,他们都感到很荣幸)。
这篇文章中的全部代码都是很是抽象的,能够应用于许多数据项目(您只需更改列名,全部代码均可以正常工做)。在笔记本中,我还添加了异常功能来处理故障状况,以确保您的代码不会在中途崩溃。我但愿它对您的项目有帮助,就像对个人帮助同样。
最后,全部的代码能够在这里找到:
https://github.com/viethoangtranduong/covid19-tweets
更多精彩推荐