Task3

特征選擇

  1. TF-IDF原理以及利用其進行特征篩選
  2. 互信息的原理以及利用其進行特征篩選

TF-IDF

  1. 原理:

如何提取一篇文章的的關鍵詞?

文章關鍵詞:指能體現一篇文章或一部著作的中心概念的詞語。指檢索資料時所查內容中必須有的詞語。
那么查找文章關鍵詞需要,在文章中出現次數多,且是非停用詞的詞,且在文章中重要程度高的詞。

如何衡量某個詞的重要程度則為TF-IDF的重點部分,因為在文章中出現次數多的詞語,有可能是常見詞語比如:“中國”、“學習”等與文章中心概念不相關的詞匯,為了篩選這樣的詞匯,則需要一個重要性調節系數,來衡量這個詞是不是常見詞。那么如果某個詞比較少見,但是它在這篇文章中多次出現,那么它很可能就反映了這篇文章的特性,正是我們所需要的關鍵詞。

  1. 詞頻(TF)

查找關鍵字前,統計詞在文章中出現的次數

詞頻(TF) = 某個詞在文章中的出現次數

  • 為了便于不同文章的比較,進行“詞頻”標準化
    詞頻(TF) = \frac{某個詞在文章中的出現次數}{文章的總次數}
    或者
    詞頻(TF) = \frac{某個詞在文章中的出現次數}{該文中出現次數最多的詞的出現次數}
  1. 逆文檔頻率(IDF)

在詞頻的基礎上,要對每個詞分配一個"重要性"權重。最常見的詞("的"、"是"、"在")給予最小的權重,較常見的詞("中國")給予較小的權重,較少見的詞給予較大的權重。
此時需要一個語料庫,用來模擬語言的使用環境
逆文檔頻率(IDF) = log(\frac{語料庫的文檔總數}{包含該詞的文檔數+1})

  1. 計算TF-IDF
    TF - IDF = 詞頻(TF) \times 逆文檔頻率(IDF)
  2. 利用TF-IDF進行特征篩選
    • 使用sklearn提取文本tfidf特征
def tfidf_weight_sklearn(words):
  '''
      使用sklearn提取文本tfidf特征
  '''
  vectorizer = CountVectorizer()      # 將詞語轉換成詞頻矩陣
  transformer = TfidfTransformer()    # 將統計每個詞語的tf-idf權值
  tfidf = transformer.fit_transform(vectorizer.fit_transform(words))
  word = vectorizer.get_feature_names()   # 獲取詞袋模型中的所有詞語
  weight = tfidf.toarray()
  weight = pd.DataFrame(weight,columns = word)
  return weight
  • 使用gensim提取文本tfidf特征
def tf_idf_weight_gensim(words):
    '''
        使用gensim提取文本的tfidf特征
    '''
    word_list = [ sentence.split(' ') for sentence in words]
    # 賦給語料庫中每個詞(不重復的詞)一個整數id
    dictionary = corpora.Dictionary(word_list)
    # 通過下面的方法可以看到語料庫中每個詞對應的id
    print(dictionary.token2id)
    new_corpus = [dictionary.doc2bow(text) for text in word_list]
    
    # 載入模型
    tfidf = models.TfidfModel(new_corpus)
    tfidf.save("my_model.tfidf")
    
    # 使用模型計算tfidf值
    tfidf = models.TfidfModel.load("my_model.tfidf")
    tfidf_vec = []
    for text in words:
        string_bow = dictionary.doc2bow(text.lower().split())
        tfidf_vec.append(tfidf[string_bow])
    
    return tfidf_vec

其中訓練數據為以下數據:

corpus = [
    'this is the first document',
    'this is the second second document',
    'and the third one',
    'is this the first document'
]

gensim賦給訓練數據的每個詞的id如下:

詞-id對應字典

第一句話詞id對應TF-IDF值list

第一句話為'this is the first document',但是由最終的結果可以看出最終結果去除了停用詞the,可知gensim有自動去除停用詞的功能;

  • 利用python自己實現TF-IDF
    其中不依賴庫的情況下,計算出的TF-IDF值準確性較低,僅僅作為練習
def get_tf(word_list, words_count):
    '''
        根據分詞列表以及詞頻列表計算詞頻
    '''
    words_tf = []
    for i in range(len(word_list)):
        word_tf_dict = dict()
        for word in word_list[i]: 
            print(words_count[i][word])
            word_tf_dict[word] = words_count[i][word] / sum(words_count[i].values())
        words_tf.append(word_tf_dict)
    return words_tf


def get_contain(word, word_list):
    count = 0
    for text in word_list:
        if word in text:
            count += 1
    return count


def get_idf(word_list):
    # 統計包含該詞的文檔數
    all_text = []
    for text in word_list:
        all_text += text
    all_word = list(set(all_text))
    word_idf = dict()
    for word in all_word:
        word_count = get_contain(word, word_list)
        word_idf[word] = math.log(len(word_list) / (1 + word_count))
    
    return word_idf
            

def get_tfidf(words):
    '''
        手動實現TF-IDF
    '''    
    # 分詞
    word_list = [sentence.split(' ') for sentence in words]
    # 統計詞頻
    sentence_list = []
    for sentence in word_list:
        sentence_list.append(Counter(sentence))
    # 計算tf值
    words_tf = get_tf(word_list, sentence_list)
    # 計算idf值
    words_idf = get_idf(word_list)
    # 計算TF-IDF
    tf_idf_weight = []
    for i in range(len(word_list)):
        tf_idf_dict = dict()
        for word in word_list[i]:
            tf_idf_dict[word] = words_tf[i][word] * words_idf[word]
        tf_idf_weight.append(tf_idf_dict)
    
    # 轉成DataFrame
    tf_idf = pd.DataFrame()
    for word in words_idf.keys():
        value = []
        for text in tf_idf_weight:
            if word in text.keys():
                value.append(text[word])
            else:
                value.append(0.0)
        tf_idf[word] = value
        
    return tf_idf

互信息

  1. 原理
  • 點互信息PMI
    公式如下:
    PMI(x;y) = log\frac{p(x,y)}{p(x)p(y)}=log\frac{p(x|y)}{p(x)}=log\frac{p(y|x)}{p(x)}

如果x,y不相關,則P(x,y) = P(x)P(y)
如果x,y相關,則當二者相關性越大P(x,y)相比于P(x)P(y)則越大
y出現的情況下x出現的條件概率p(x|y)除以x本身出現的概率p(x),自然就表示x跟y的相關程度。

  • 互信息MI

用來衡量兩個數據分布的吻合程度
其中值越大意味著結果與真實情況越吻合

公式如下:
I(X;Y) = \sum_{x\in X}\sum_{y\in Y}p(x, y)log\frac {p(x,y)}{p(x)p(y)}

其衡量的是兩個隨機變量之間的相關性,即一個隨機變量中包含的關于另一個隨機變量的信息量;
所謂的隨機變量,即隨機試驗結果的量的表示,可以簡單理解為按照一個概率分布進行取值的變量,比如隨機抽查的一個人的身高就是一個隨機變量;
其中互信息其實就是對X和Y的所有可能的取值情況的點互信息PMI的加權和

# 互信息
labels_true = [0, 0, 0, 1, 1, 1]
labels_pred = [0, 0, 1, 1, 2, 2]
mr.adjusted_mutual_info_score(labels_true, labels_pred)

完整代碼見github

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容