算法演示和完整代码见文末,下一期将带来NLP的经典Word2Vec算法。若需转载请注明来源,谢谢。
-
简要介绍
-
部分理论
-
数据清单
-
分词工具
-
工程复现
-
结果演示
-
优化展望
简要介绍
今天躺在床上看Bert如何使用在DNA上,想着对一些NLP知识的掌握逐渐模糊,就开始从头巩固一遍记录下来,并且融入自己的经验进行工程复现,内容涉及使用基本运算库实现TF-IDF算法进行信息检索等。
部分理论
Name: Term Frequency
Name: Inverse Document Frequency
Model: TF-IDF
扫描二维码关注公众号获取更新更完整文章
数据清单
文本数据集
dataset.zip:包含4行
Fig.1 Context display
分词工具
jieba分词器(国内流行的中文分词工具)
Fig.2 Jieba tokenization algorithm
工程复现
配置基本需求库
""" Import the basic requirements package """
import time
import math
import jieba
import pandas as pd
from collections import defaultdict # Import advanced dictionary
from string import punctuation as str_punc
add_punc = ',。、【 】 “”:;()《》‘’{}?!⑦()、%^>℃:.”“^-——=&#@¥'
all_punc = str_punc + add_punc # Set punctuation list
配置数据集导出函数
""" Dataset export function """
def read_csv():
context = [
"TfIdf是一种统计的方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。",
"字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。",
"TfIdf加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。",
"除了TfIdf以外,因特网上的搜索引擎还会使用基于链接分析的评级方法,以确定文件在搜寻结果中出现的顺序。",
]
return context
配置Jieba分词函数
""" Jieba tokenization function """
def tokenization(context):
token_list = []
words_frequency = defaultdict(int) # Set words frequency dict
for sentence in context:
cut_words = jieba.lcut(sentence)
token = []
for word in cut_words:
if word not in all_punc: # Remove punctuation in sentences
words_frequency[word] += 1
token.append(word)
token_list.append(token)
return token_list, words_frequency
配置Tf计算函数
""" Tf calculation function """
def tf_fit(words_frequency):
words_number = sum(words_frequency.values())
words_tf = {}
for word, word_frequency in words_frequency.items():
words_tf[word] = word_frequency / words_number
return words_tf
配置Idf计算函数
""" Idf calculation function """
def idf_fit(tfidf_params, token_list, words_frequency):
words_idf = {}
words_doc = defaultdict(int)
doc_number = len(token_list)
for word in words_frequency.keys():
for token in token_list:
if word in token:
words_doc[word] += 1
words_idf[word] = doc_number / math.log(words_doc[word] + 1, tfidf_params['log_c'])
return words_idf
配置TfIdf模型函数
""" TfIdf model function """
# create model
def TfIdfVectorizer(log_c=10):
tfidf_params = {
'log_c': log_c, # Set the base of the idf logarithm
}
return tfidf_params
# fit model
def fit(tfidf_params, token_list, words_frequency):
words_tf = tf_fit(words_frequency)
words_idf = idf_fit(tfidf_params, token_list, words_frequency)
words_tfidf = {}
submit = pd.DataFrame(columns=['word', 'word_tf', 'word_idf', 'word_tfidf'])
for word in words_frequency.keys():
words_tfidf[word] = words_tf[word] * words_idf[word]
submit = submit.append( # data append submit
{'word': word,
'word_tf': words_tf[word],
'word_idf': words_idf[word],
'word_tfidf': words_tfidf[word]
},ignore_index=True)
submit = submit.sort_values(by=['word_tfidf'], ascending=False).reset_index(drop=True) # Sort data
print(submit.head(20))
return None
配置训练主进程
""" Tfidf model training host process """
if __name__ == '__main__':
sta_time = time.time()
context = read_csv()
token_list, words_frequency = tokenization(context=context)
model = TfIdfVectorizer(log_c=2)
fit(model, token_list, words_frequency)
print("Time:", time.time() - sta_time)
结果演示
优化展望
在本次复现的结果中,结果并不是非常满意,本人提示有三个以上可以自行优化改进的方向。
-
本次复现数据量非常小,在实际中可以使用数据增强的方法来提高Tf-Idf算法对于文本处理的性能。
-
在结果中有些语气、停用词在占据高位,但是对文本分词结果毫无作用,实际使用Tf-Idf算法中,对文本分词前会引入停用词表来过滤,国内比较出名的有百度、哈工大的开源停用词表等。
-
Tf-Idf算法是非常经典的文本处理算法,其核心思想在于结合了频率公式与逆文档频率公式,对于二者结合的方法却比较简洁,可以通过改进二者公式或二者加权的方法来达到提升算法性能的效果。
完整代码
Github Code后台回复"TFIDF"获取完整代码
参考链接
Jieba
Data augmentation
Stop_words
扫描二维码关注公众号“筝自然语言处理和推荐算法”
获取算法领域更多干货精彩