特征選擇
- TF-IDF原理以及利用其進行特征篩選
- 互信息的原理以及利用其進行特征篩選
TF-IDF
- 原理:
如何提取一篇文章的的關鍵詞?
文章關鍵詞:指能體現(xiàn)一篇文章或一部著作的中心概念的詞語描沟。指檢索資料時所查內(nèi)容中必須有的詞語殴泰。
那么查找文章關鍵詞需要崔兴,在文章中出現(xiàn)次數(shù)多理卑,且是非停用詞的詞座韵,且在文章中重要程度高的詞煌张。如何衡量某個詞的重要程度則為TF-IDF的重點部分垮卓,因為在文章中出現(xiàn)次數(shù)多的詞語,有可能是常見詞語比如:“中國”令花、“學習”等與文章中心概念不相關的詞匯阻桅,為了篩選這樣的詞匯,則需要一個重要性調(diào)節(jié)系數(shù)兼都,來衡量這個詞是不是常見詞嫂沉。那么如果某個詞比較少見,但是它在這篇文章中多次出現(xiàn)扮碧,那么它很可能就反映了這篇文章的特性趟章,正是我們所需要的關鍵詞。
- 詞頻(TF)
查找關鍵字前慎王,統(tǒng)計詞在文章中出現(xiàn)的次數(shù)
- 為了便于不同文章的比較蚓土,進行“詞頻”標準化
或者
- 逆文檔頻率(IDF)
在詞頻的基礎上,要對每個詞分配一個"重要性"權(quán)重赖淤。最常見的詞("的"蜀漆、"是"、"在")給予最小的權(quán)重咱旱,較常見的詞("中國")給予較小的權(quán)重确丢,較少見的詞給予較大的權(quán)重。
此時需要一個語料庫吐限,用來模擬語言的使用環(huán)境
-
計算TF-IDF
- 利用TF-IDF進行特征篩選
- 使用sklearn提取文本tfidf特征
def tfidf_weight_sklearn(words):
'''
使用sklearn提取文本tfidf特征
'''
vectorizer = CountVectorizer() # 將詞語轉(zhuǎn)換成詞頻矩陣
transformer = TfidfTransformer() # 將統(tǒng)計每個詞語的tf-idf權(quán)值
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]
# 賦給語料庫中每個詞(不重復的詞)一個整數(shù)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
其中訓練數(shù)據(jù)為以下數(shù)據(jù):
corpus = [
'this is the first document',
'this is the second second document',
'and the third one',
'is this the first document'
]
gensim賦給訓練數(shù)據(jù)的每個詞的id如下:
第一句話為
'this is the first document'
鲜侥,但是由最終的結(jié)果可以看出最終結(jié)果去除了停用詞the
,可知gensim
有自動去除停用詞的功能诸典;
- 利用
python
自己實現(xiàn)
其中不依賴庫的情況下描函,計算出的TF-IDF值準確性較低,僅僅作為練習
def get_tf(word_list, words_count):
'''
根據(jù)分詞列表以及詞頻列表計算詞頻
'''
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):
# 統(tǒng)計包含該詞的文檔數(shù)
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):
'''
手動實現(xiàn)TF-IDF
'''
# 分詞
word_list = [sentence.split(' ') for sentence in words]
# 統(tǒng)計詞頻
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)
# 轉(zhuǎn)成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相關赘阀,則當二者相關性越大相比于
則越大
在出現(xiàn)的情況下
出現(xiàn)的條件概率
除以
本身出現(xiàn)的概率
,自然就表示x跟y的相關程度脑奠。
- 互信息MI
用來衡量兩個數(shù)據(jù)分布的吻合程度
其中值越大意味著結(jié)果與真實情況越吻合
公式如下:
其衡量的是兩個隨機變量之間的相關性,即一個隨機變量中包含的關于另一個隨機變量的信息量幅慌;
所謂的隨機變量宋欺,即隨機試驗結(jié)果的量的表示,可以簡單理解為按照一個概率分布進行取值的變量,比如隨機抽查的一個人的身高就是一個隨機變量齿诞;
其中互信息其實就是對X和Y的所有可能的取值情況的點互信息PMI的加權(quán)和酸休。
# 互信息
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