如何從文本中提取特徵信息?

雖然以前也寫過gensim庫的word2vec的教程,可是對於文本分析的特徵提取並不太理解。最近看了幾篇scikit的外文教程,對機器學習中文本的特徵提取有了一些瞭解。機器學習

首先作文本的機器學習(天然語言處理),咱們要理解這幾個概念:ide

  • 文檔(document)這裏是指一段單獨的文本信息。這多是一則短信、一條推特、一封郵件、一本書、或者一首歌詞。通常一個文檔對應於一個觀測值或一行數據。學習

  • 語料(corpus) 文檔的集合(語料大於等於1條文檔)。這至關於咱們要研究對象的全部文本數據測試

  • 單詞或詞語(token) 英文中對應的是單詞,漢語是詞語。例如「How are you」這個文檔,是由how、are、you三個單詞組成的。token至關於機器學習中的特徵(列)。

首先讓咱們給出一個語料例子。編碼

corpus = ["Hey hey hey lets go get lunch today :)",
           "Did you go home?",
           "Hey!!! I need a favor"]

CountVectorizer
首先咱們要明白,計算機是不能從文本字符串中發現規律的。只有將字符串編碼爲計算機能夠理解的數字,計算機纔有可能發現文本中的規律。spa

最容易理解的實現思路:3d

  • 對文本編碼,就是讓詞語與數字對應起來,創建基於給定文本的詞典。(fit方法 )code

  • 再根據詞典對全部的文本數據進行轉碼。(transform方法)

scikit庫的CountVectorize類就是這種思路。orm

from sklearn.feature_extraction.text import CountVectorizer

vectorize = CountVectorizer()

使用fit方法,CountVectorizer()類的會從corpus語料中學習到全部詞語,進而構建出corpus詞典。對象

#fit學會語料中的全部詞語,構建詞典

vectorize.fit(corpus)
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,
        strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b',
        tokenizer=None, vocabulary=None)
#這裏咱們查看下「詞典」,也就是特徵集(11個特徵詞)
vectorize.get_feature_names()
['did',
 'favor',
 'get',
 'go',
 'hey',
 'home',
 'lets',
 'lunch',
 'need',
 'today',
 'you']

這裏,特徵集(get_feature——name)返回的結果,有要注意的事情:

  • 全部的單詞都是小寫

  • 單詞長度小於兩個字母的,會被剔除掉

  • 標點符號會剔除掉

  • 不重複

  • 這個特徵集是有順序的

接下來會按照這個順序去編碼文本數據,這裏會出現一個新概念文檔-詞頻矩陣(document-term matrix),英文簡寫爲dtm。咱們讓機器挖掘文本中的規律時,餵給機器的數據就是 這文檔-詞頻矩陣(document-term matrix)。

#構建 文檔詞頻矩陣
dtm = vectorize.transform(corpus)dtm
<3x11 sparse matrix of type '<class 'numpy.int64'>'
    with 13 stored elements in Compressed Sparse Row format>

構建文檔詞頻矩陣。結果3*11。

3指的是語料中的三個文檔;11指的是corpus中11個特徵詞。爲了方便咱們理解,我用pandas庫將其展示出來

import pandas as pd

pd.DataFrame(dtm.toarray(), columns = vectorize.get_feature_names())

如何從文本中提取特徵信息?
從上面的dataframe表中,行表明一個文檔,列表明特徵詞。好比第1行,hey列的所對應的單元格值爲3,說明corpus中第一個document(Hey hey hey lets go get lunch today :) 出現了三次hey。

這裏有一個我要提示的重點,在此時咱們已經構件號了文檔詞頻矩陣dtm,若是你還想加入新的文檔。咱們應該注意tranform和fit的區別。

new_document = ['Hey lets go get a drink tonight']
new_dtm = vectorize.transform(new_document)
pd.DataFrame(new_dtm.toarray(), columns=vectorize.get_feature_names())

如何從文本中提取特徵信息?

即便new_document含有6個單詞,可是在上面的dataframe表中只有4個特徵詞被有效編碼,drink和tonight詞未被表徵。這是由於咱們初識的corpus語料所構建的詞典並未含有這些詞。可是對文本進行特徵表徵時,使用的確實corpus所生產的詞典。

咱們機器學習所用的數據,通常被分紅訓練集和測試集。訓練集是爲了讓機器學習數據的規律,測試集是爲了驗證規律的有效性。訓練集本質上表明的是過去及如今已知的數據,測試集本質上表明的是將來的未知數據(如今不存在的數據),咱們是用已知的數據預測將來。

因此咱們只能讓fit方法操做於訓練集,構建基於過去或已知數據的特徵集。

TfidfVectorizer
scikit庫除了CountVectorizer類,還有TfidfVectorizer類。TF-IDF這個定義相信你們應該已經耳熟能詳了:

TF 詞頻出現的次數 IDF = 1/(語料中含有該詞語的文檔的數目)

TF簡單點說有的時候詞語出現越多,這個詞越是特徵詞。但同時,有些「的它呢」等無心義詞出現的多並無什麼意義,反而是像「核能」這種詞,雖然不怎麼出現,可是一出現每每很具備特徵性。

綜合TF*IDF,就能很好的刻畫一個詞語是否具備表徵文本信息能力,做爲特徵是否合適。有了上面的基礎知識,咱們接下來繼續寫代碼,便於理解TFIDF

from sklearn.feature_extraction.text import TfidfVectorizer

def createDTM(corpus):
    """構建文檔詞語矩陣"""
    vectorize = TfidfVectorizer()
    #注意fit_transform至關於fit以後又transform。
    dtm = vectorize.fit_transform(corpus)

    #打印dtm
    return pd.DataFrame(dtm.toarray(), columns=vectorize.get_feature_names()) 

corpus = ["Hey lets get lunch :)",
           "Hey!!! I need a favor"]
createDTM(corpus)

如何從文本中提取特徵信息?
咱們看到hey這個詞在全部大於0的值裏面,是最小的。由於hey同時出如今兩個文檔中,不具備文本的表徵能力,因此TFIDF小。而favor和need由於他們僅僅出如今第二個文檔中,因此他們的TFIDF值更高。

如今咱們改變corpus內容。將第一個文檔從Hey lets get lunch改成Hey hey hey lets get lunch。咱們但願第一個文檔的hey詞頻增大,進而使得其TFIDF值變大。

corpus = ["Hey hey hey lets get lunch :)",
           "Hey!!! I need a favor"]

createDTM(corpus)

如何從文本中提取特徵信息?

咱們發現第一個文檔hey的TFIDF值變大,但這裏有兩點要注意:

  • 第一個文檔中其他特徵詞的TFIDF值變小了

  • 第二個文檔中hey的TFIDF未發生變化

上面的例子是經過TF詞頻操做TFIDF值的。下面咱們從IDF出發,改變TFIDF值。

corpus = ["Hey hey hey lets get lunch :)",
           "I need a favor"]

createDTM(corpus)

如何從文本中提取特徵信息?

相關文章
相關標籤/搜索