基于TF-IDF算法的短标题关键词提取

转载请注明出处:http://blog.csdn.net/gamer_gyt 
博主微博:http://weibo.com/234654758 
Github:https://github.com/thinkgamer


搜索与推荐Wiki

扫一扫 关注微信公众号!号主 专注于搜索和推荐系统,尝试使用算法去更好的服务于用户,包括但不局限于机器学习,深度学习,强化学习,自然语言理解,知识图谱,还不定时分享技术,资料,思考等文章!


                             【技术服务】,详情点击查看:https://mp.weixin.qq.com/s/PtX9ukKRBmazAWARprGIAg 


外包服务


TF-IDF算法介绍

TF-IDF(Term Frequency–InverseDocument Frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

TF-IDF实际是TF*IDF,其中TF(Term Frequency)表示词条t在文档Di中的出现的频率,TF的计算公式如下所示:

其中IDF(InverseDocument Frequency)表示总文档与包含词条t的文档的比值求对数,IDF的计算公式如下所示: 

 其中N为所有的文档总数,I(t,Di)表示文档Di是否包含词条t,若包含为1,不包含为0。但此处存在一个问题,即当词条t在所有文档中都没有出现的话公式6.2的分母为0,此时就需要对IDF做平滑处理,改善后的IDF计算公式如下所示:

 

那么最终词条t在文档Di中的TF-IDF值为:TF-IDFt,Di = TFt,Di * IDFt 。

从上述的计算词条t在文档Di中的TF-IDF值计算可以看出:当一个词条在文档中出现的频率越高,且新鲜度低(即普遍度低),则其对应的TF-IDF值越高。

比如现在有一个预料库,包含了100篇(N)论文,其中涉及包含推荐系统(t)这个词条的有20篇,在第一篇论文(D1)中总共有200个技术词汇,其中推荐系统出现了15次,则词条推荐系统的在第一篇论文(D1)中的TF-IDF值为:

短标题关键词提取

废话不多说,直接上代码,实现如下:

 

# -*-coding:utf-8-*-

"""
Data: 2018-08
Author: Thinkgamer
"""
import jieba
import math
import jieba.analyse

class TF_IDF:

    def __init__(self,file,stop_file):
        self.file = file
        self.stop_file = stop_file
        self.stop_words = self.getStopWords()

    # 获取停用词列表
    def getStopWords(self):
        swlist=list()
        for line in open(self.stop_file,"r",encoding="utf-8").readlines():
            swlist.append(line.strip())
        print("加载停用词完成...")
        return swlist

    # 加载商品和其对应的短标题,使用jieba进行分词并去除停用词
    def loadData(self):
        dMap = dict()
        for line in open(self.file,"r",encoding="utf-8").readlines():
            id,title = line.strip().split("\t")
            dMap.setdefault(id, [])
            for word in list(jieba.cut(str(title).replace(" ",""), cut_all=False)):
               if word not in self.stop_words:
                   dMap[id].append(word)
        print("加载商品和对应的短标题,并使用jieba分词和去除停用词完成...")
        return dMap

    # 获取一个短标题中的词频
    def getFreqWord(self,words):
        freqWord = dict()
        for word in words:
            freqWord.setdefault(word,0)
            freqWord[word] += 1
        return freqWord

    # 统计单词在所有短标题中出现的次数
    def getCountWordInFile(self,word,dMap):
        count = 0
        for key in dMap.keys():
            if word in dMap[key]:
                count += 1
        return count

    # 计算TFIDF值
    def getTFIDF(self,words,dMap):
        # 记录单词关键词和对应的tfidf值
        outDic = dict()
        freqWord = self.getFreqWord(words)
        for word in words:
            # 计算TF值,即单个word在整句中出现的次数
            tf = freqWord[word]*1.0 / len(words)
            # 计算IDF值,即log(所有的标题数/(包含单个word的标题数+1))
            idf = math.log(len(dMap)/(self.getCountWordInFile(word,dMap)+1))
            tfidf = tf * idf
            outDic[word] = tfidf
        # 给字典排序
        orderDic = sorted(outDic.items(), key=lambda x:x[1], reverse=True)
        return orderDic

    def getTag(self,words):
        # withWeight 用来设置是否打印权重
        print(jieba.analyse.extract_tags(words, topK=20, withWeight=True))

if __name__ == "__main__":
    # 数据集
    file = "data/id_title.txt"
    # 停用词文件
    stop_file = "data/stop_words.txt"

    tfidf=TF_IDF(file,stop_file)
    tfidf.getTag(open("data/one","r",encoding="utf-8").read(),)

    # dMap 中key为商品id,value为去除停用词后的词
    # dMap = tfidf.loadData()
    # for id in dMap.keys():
    #     tfIdfDic = tfidf.getTFIDF(dMap[id],dMap)
    #     print(id,tfIdfDic)

 

发布了320 篇原创文章 · 获赞 495 · 访问量 205万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览