做者 | 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
更多精彩推薦