從 App 描述介紹文字中發掘 Python 文本數據預處理實例
本文為 AI 研習社編譯的技術博客,原標題 What App Descriptions Tell Us: Text Data Preprocessing in Python,作者為Finn Qiao。
翻譯 | nick李 校對 | 付騰 整理 | 令雙
除了數據清洗和數據探索的主題外,許多有效的NLP(自然語言處理)分析都是依賴於對文本數據的預處理。因此,我決定手把手展現一個對來自蘋果App Store簡述的文本數據預處理的過程,並且對這些數據使用K均值聚類演算法。
為什麼要選擇App Store呢?Kaggle的數據集包括了7197個應用及其各自的應用簡述。應用開發者在應用簡述中用盡所能來「推銷」他們的應用。我使用這些預處理的數據,檢驗了一個問題——是否能根據應用簡述對應用類別進行良好預測?
我所使用的預處理「框架」主要如下:
翻譯*
去除非字母字元
大寫轉小寫
分詞
去除停用詞
詞幹提取(stemming)**
數據分析
* 我首先對所有簡述進行翻譯的原因是,非字母字元的正則表達式可能會將某些語言去除掉,例如日文和中文。
** 在這一步中我省去了詞形還原(lemmatization)因為我想要在後面的步驟中著眼於辭彙多樣性。
和普遍做法一樣,我們先以讀取csv文件獲得相關數據開始。在這裡,我們將有基本應用信息的數據幀(Dataframe)和有應用簡述的數據幀合併。
由於大部分特徵變數的數據類型都是合理的,讓我們先概覽一下相關數據。
不出所料的是,App Store中大部分應用是遊戲,這一類別大約佔數據集的54%。其次是」娛樂「和」教育「,與遊戲相差甚遠,分別佔比7%和6%。
平均評分最高的類別是」效率「和」音樂「。有趣的是,目前為止」商品指南「、「經濟」和「圖書」為App Store中評分最低的三個應用類別。
預處理過程
1 譯成英文
開始預處理我們首先將所有應用簡述翻譯為英文。此處我們可以使用googletrans包來調用谷歌翻譯的API。遺憾的是,這個API調用有15000個字元的限制。我們可以通過在數據幀的每一行重新初始化translator來應對字數限制,儘管這不是優雅的編程方式。
當應用簡述已經是英文的時候,我們可以使用langdetect包來進行檢測並僅在語言不是英文才調用API,這樣以減少無用的API調用操作。
有46個應用的簡述返回了error。這些應用的簡述可能超出了字數,而其他的應用則沒有問題。考慮到出錯的個數僅僅是整個數據集中的一小部分,我們完全可以拋棄掉這些數據。
2 去除非字母字元
現在我們確信諸如日文和中文的簡述不會被正則表達式篩除,我們可以創建一個表達式[^a-zA-Z]來返回所有字母和空格。除此之外的其他字元被幫助函數cleaned()中的re.sub()方法去除。空格被保留以用於分詞。
3 大寫轉小寫
文本數據正則化的另一步就是將所有字元轉化為小寫。這一步too simple,只需要對數據幀的相應列運行str.lower()方法即可。
4,5,6 分詞,去停用詞和詞幹提取
鑒於這三步已經被nltk實現,我寫了一個幫助函數來把它們集成起來。
分詞指的是講一個長句切分成小的塊或標識符。這個和使用既定的切分器對一個字元串運行切分函數並得到一個它的各個部分的列表的做法差不多。我們在這裡使用nltk包中的word_tokenize()方法來進行分詞。
停用詞是指可以被過濾掉而不影響文本大意的詞。其中包括諸如"a", "to", "and"等詞。我們通過使用stopwords.words("english")來獲得nltk中英文停用詞集合。
詞幹提取指的是去除詞的詞綴。例如,"climbing"去除詞綴變成"climb"。我們使用nltk中的SnowballStemmer("english")來初始化詞幹提取器。
下面的幫助函數首先將句子分詞,然後檢查每個詞是否為停用詞並且過濾停用詞,最後運行詞幹提取器去除詞綴並將詞加入列表中。
7 數據分析
讓我們現在深入已經清洗好的數據。
7.1 詞雲生成
哪些詞被最多地用來描述應用類別呢?儘管使用簡單的詞頻統計或tf-idf vectorizer可以返回詞的排名列表,使用詞雲可能會更加有效地展示那些最常用的詞。
為了給每個類別生成一個詞雲,我為每個建立了一個清洗過的應用簡述語料庫(或者說是集合)。比較幸運的是,wordcloud包可以很方便地從一個給定語料庫生成詞雲。
wordcloud包通過創建語料庫中排名前200的詞列表和它們正則化後的詞頻統計列表來工作。得到詞排名的列表後,我們使用Pythin Image庫來繪製詞雲。這個總結並沒有對他的代碼公正,你可以在下圖得到更多相關信息。
取"遊戲","天氣","購物"和"音樂"的一小部分詞為例,我們可以看出,最顯著的詞其實就是我們所期望的代表其類別的詞。但是,儘管在這些類別中效果顯著,在其他類別中代表詞的區分卻不明顯。我們將會在下文中聚類時討論這一點。
7.2 辭彙多樣性
諸如「遊戲「的不同的類別是否本來就有更多樣的語言和描述呢?我通過使用一個評估辭彙多樣性的簡單公式來回答這個問題。我用每個過濾列表中的唯一詞個數除以相應簡述的詞總數得到一個數值。這個數值越高就表示辭彙多樣性越高。
如同預期的一樣,「遊戲」和「圖書」的平均辭彙多樣性的得分是最高的。可能的原因主要是這兩個類別有較多子類別以及它們的簡述相對更加「吸引人心」。
而商品指南的描述就可以說是相當的無聊了。
7.3 情感分析
是否存在某些類別的應用簡述的態度比其他類別的更加積極?對此我決定用Textblob包來進行情感分析展示。
情感極性為0意味著中立態度,極性小於0表示負面情感,極性大於0表示(你猜對了)正向的情感。
類別「遊戲」、「經濟」和「醫療「具有最低的平均情感極性。如果遊戲內包含有消極主題,例如戰爭與恐懼(這些主題被很好的體現),"遊戲"則可能會有很低的極性。"經濟"和"醫療"的極性很低的原因可能是因為其描述了並不樂觀的經濟或醫療情況。
可能對某幾本催人淚下作品的簡述構成了「圖書」的主要基調。而提到了「捕捉快樂時光」似乎構成了「攝影與錄像「的主旋律。
7.4 K均值聚類
現在來到了我們最初的問題——是否能根據應用簡述對應用類別進行良好預測?
為了回答這個問題,我對詞向量應用可K均值進行聚類並觀察它們映射到實際的類別的表現好壞。
當我們設立10個簇並運行聚類演算法時,每個簇的前10個詞如下圖所示:
乍一看的話,似乎某些簇是可以被解釋並標記的:
簇0: 面向兒童的應用
簇3: 音樂類應用
簇4: 包含戰爭/打鬥/怪獸的遊戲
簇6: 文字遊戲
簇7: 攝影與錄像應用
簇9: 汽車相關應用
那麼這些簇是如何映射到實際中的應用類別的呢?
上面所示的標籤看起來具有代表性但是實際上卻存在一個問題,在這個樣例中,遊戲被過度表示了。其他類別的顏色在圖表中太淺了以至於幾乎沒有意義。下圖展示了去除了「遊戲」後的熱圖分布。
沒有了「遊戲」的過度表示後,其他類別的程度就可以清晰識別了。其中較為明顯的是簇3和「教育」,簇4和「經濟」以及「購物」,簇7和「購物」,還有簇9和「攝影和錄像「。
那如果我們將簇的個數增加到與實際類別數相同會怎麼樣呢(不包含遊戲共22個)?
同樣,還是先橫向比較一下這些簇和各自常用詞之間的關係。
在這20個簇中,比較容易定義的簇有:
簇0:購物
簇9:健康&健美
簇10:音樂
簇11:攝影與錄像
簇13:教育
簇14:經濟
簇17:天氣
可以看到,只有三分之一的類別被較好地表示出來,而且其中兩個最明顯的類別具有很不平衡的樣本大小。而且,各個類別之間的詞存在重疊現象。導致這些的原因有很多。
不平衡的樣本大小
正如一開始所提到的,數據集中大約54%的應用是遊戲。即便在將「遊戲」類別篩除之後,仍有較大部分遊戲被表示在「教育」和「娛樂」類別中。
全都是遊戲
如果在所有類別中都挑選一定的樣本數量,那麼結果可能會更好,但是那樣的基礎是需要一個更大的整體樣本。
詞重疊
儘管樣本的數量很少,「天氣」類應用還是被簇17所表示。那些能夠被簇所表示出來的類別是因為其具有獨特的命名系統。
且看類別「工具「和」參考「的詞雲,它們都包含了一些在其他類別中也有所表示的詞。
也許可以生成一個列表,其中包含一些跨類別詞,並將這個列表中的詞從清洗之後的句子中過濾掉。儘管如此,像」效率「和」工具「這樣的類別還是有可能和其他類別具有重疊的詞,因此無法被完全聚類。
在解決本文的NLP分析里的一些問題後,我想創立一個模型並利用應用簡述以及更多的信息來預測應用類別的模型。
我也在嘗試使用markovify來生成每個類別的應用簡述。這是「體育」類的一些例子:
如你所見,其實也不是特別好(攤手)ˉ\_(ツ)_/ˉ
最後,感謝閱讀,代碼在此
https://github.com/finnqiao/apple_appstore
https://towardsdatascience.com/what-app-descriptions-tell-us-text-data-preprocessing-in-python-afc7ed88360d
※「特徵工程」與「表示學習」
※如何在 Scratch 中用 Python 構建神經網路
TAG:AI研習社 |