特征選擇
- TF-IDF原理以及利用其進行特征篩選
- 互信息的原理以及利用其進行特征篩選
TF-IDF
- 原理:
如何提取一篇文章的的關鍵詞?
文章關鍵詞:指能體現一篇文章或一部著作的中心概念的詞語。指檢索資料時所查內容中必須有的詞語。
那么查找文章關鍵詞需要,在文章中出現次數多,且是非停用詞的詞,且在文章中重要程度高的詞。如何衡量某個詞的重要程度則為TF-IDF的重點部分,因為在文章中出現次數多的詞語,有可能是常見詞語比如:“中國”、“學習”等與文章中心概念不相關的詞匯,為了篩選這樣的詞匯,則需要一個重要性調節系數,來衡量這個詞是不是常見詞。那么如果某個詞比較少見,但是它在這篇文章中多次出現,那么它很可能就反映了這篇文章的特性,正是我們所需要的關鍵詞。
- 詞頻(TF)
查找關鍵字前,統計詞在文章中出現的次數
- 為了便于不同文章的比較,進行“詞頻”標準化
或者
- 逆文檔頻率(IDF)
在詞頻的基礎上,要對每個詞分配一個"重要性"權重。最常見的詞("的"、"是"、"在")給予最小的權重,較常見的詞("中國")給予較小的權重,較少見的詞給予較大的權重。
此時需要一個語料庫,用來模擬語言的使用環境
-
計算TF-IDF
- 利用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值準確性較低,僅僅作為練習
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
互信息
- 原理
-
點互信息PMI
公式如下:
如果x,y不相關,則
如果x,y相關,則當二者相關性越大相比于
則越大
在出現的情況下
出現的條件概率
除以
本身出現的概率
,自然就表示x跟y的相關程度。
- 互信息MI
用來衡量兩個數據分布的吻合程度
其中值越大意味著結果與真實情況越吻合
公式如下:
其衡量的是兩個隨機變量之間的相關性,即一個隨機變量中包含的關于另一個隨機變量的信息量;
所謂的隨機變量,即隨機試驗結果的量的表示,可以簡單理解為按照一個概率分布進行取值的變量,比如隨機抽查的一個人的身高就是一個隨機變量;
其中互信息其實就是對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