词频统计之TF-IDF

1.TF-IDF介绍

1.1.概述

        TF-IDF(term frequency-inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重
要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
        主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类,也就可以作为上文中所提到的关键

1.2.词频(TF)和逆文档频率IDF
1.2.1.TF:词频 

TF = 某个词在这篇文章中出现的(Σ次数) / (Σ文章的总词数)
词频越高,则认为这个词的重要性越高

1.2.2.停用词(即过滤词频) 

        类似"的"、"是"、"了"这类词的出现次数应该最多,它们叫做停用词,对找到结果完全毫无帮助,是我们必须要过滤掉的词。
        例如单独拿出来"的",你无法判断这个文章讲什么,但是单独拿出来"聚类算法",你可能能猜测这个文章讲算法。

1.2.3.IDF:逆文档频率(即权重)

1、假定我们现在要在一个关于聚类的文章中找寻关键字。我们可能发现见"聚类"和"算法"的出现次数一样多,那么它们的重要性就是一样的么?答案当然是否定的,相对于"聚类"而言,"算法"更为常见,出现次数同样多,我们就有理由认为"聚类"的重要程度要大于"算法"。
2、什么叫做"相对于"聚类"而言,"算法"更为常见"
3、逆文档频率(IDF)=log(词料库的文档总数/包含该词的文档数+1)
4、我们做客服文本的时候,以每个聊天记录作为一个样本,这时候样本们可以认为是一个个文档,所有文档构成了整个词料库

1.2.4.计算TF-IDF值

TF-IDF值=TF *IDF

1.2.5.求出关键字

计算出文章中每个词的TF-IDF值之后,进行排序,选取其中值最高的N个作为关键字。jieba包中topK为返回几个TF/IDF权重最大的关键词,默认值为20

1.2.6.计算文章的相似性

        计算出每篇文章的关键词,从中各选取相同个数的关键词,合并成一个集合,计算每篇文章对于这个集合中的词的词频,生成两两文章之间的词频向量,进而通过欧氏距离或余弦距离求出两个向
量的余弦相似度,值越大就表示越相似。
大致解释一下欧氏距离和余弦距离
1、欧氏距离
实际上就是二范数,或者是协方差
若有向量A=[x1,y1,Z1,...]T,B=[x2, y2,Z2..]T,则向量A和B的欧式武距离为:


显然,如果x,y,z...之间处于不同的量级单位,则这个距离结果很多受影响,所以我们考虑要做个"标准化

2、余弦距离
实际上就是欧式距离的类"标准化",就是对协方差计算相似度的过程


如上式,我们计算对xi,yi各自除以他们的二阶中心矩(也可以说是标不准差),然后一除,就是每个值距离中心几个标准差而实现标准化。从而计算余弦距离。
显然计算相似度,余弦距离比欧式距离更加适合

2.TF-IDF的算法实现及代码解析(Sklearn)

2.1.公式
2.2.两种分词办法

CountVectorizer+TfidfTransformer的组合 = TfidfVectorizer

2.2.1.方法一:CountVectorizer+TfidfTransformer

1.CountVectorizer()函数只考虑每个单词出现的频率;
2.通过CountVectorizer()构成一个特征矩阵,每一行表示一个训练文本的词频统计结果;
3. CountVectorizer()是通过fit_transform(函数将文本中的词语转换为词频矩阵。其思想是,先根据所有训练文本,不考虑其出现顺序,只只将训练文本中每个出现过的词汇单独视为一列特征,构
成一个词汇表(vocabulary list),该方法又称为词袋法(Bag of Words)。
4.注意CountVectorizer(函数用在中文时候,需要先对文本做jieba分词,否则默认以标点符号作为一个词的分割符。

# 导入包
from sklearn.feature_extraction.text 
import CountVectorizer,TfidfVectorizer,TfidfTransformer
import jieba

# 训练样本texts
texts=["你好,我想办理提前结清手续。你好,为了您的财产安全,我们需要对您进行身份认证,才能办理",
"你好,我想提前结清,请问要支付多少利息",
"你好,为什么我办理提前结清失败了?",
"你好,帮我查一下我一次还清需要多少钱",
"怎么回事?我的会员费没办法取消?我要举报你们",
"为啥我申请成功了,却没办法提现?",
"请问可以给我做个分期么?还不起钱了,收入太低了"]

#获取停用词列表
def stop_word_list(file_path):
    stop_words = [line.strip() for line in open(file_path,'r',encoding='utf8').readlines()]
    return stop_words

#分词器
def cut_word(text):
    #添加常用词
    jieba.load_userdict("./use_dict.txt")
    #新增常用词
    jieba.add_word("还清")
    #添加停用词
    file_path=r'./stop.txt'
    stop_words = stop_word_list(file_path=file_path)
    #进行中文分词
    sentence=jieba.cut(text.strip())
    result = ""
    for word in sentence:
        if word not in stop_words:
            if word != '\t':
                result += word
                result += " "
    return result

data_new = []
for sent in texts:
    data_new.append(cut_word(sent))
print("句子分词后:\n",data_new)

# 新建对象,cv,用于将文本转化为词频矩阵
# max_features设置最多的特征值个数,所有会话,我们值希望是最多的特征个数
# cv = CountVectorizer(max_features=12)
cv = CountVectorizer()

#计算每个词语出现的次数
cv_fit = cv.fit_transform(data_new)

#cv已经将所有关键字作为一个
print("查看所有文本关键字")
print(cv.get_feature_names()) # 查看所有文本关键字

print("\n词频矩阵的位置信息")
print(cv_fit)

print("\n查看词频矩阵")
print(cv_fit.toarray()) #查看次词频矩阵

# 新建对象tf_idf_transformer,用于计算每个词语的TF-IDF值
tf_idf_transformer = TfidfTransformer()

# 计算tf-idf
tf_idf = tf_idf_transformer.fit_transform(cv_fit)

# 元素a[i][j]表示j词在i文本中的tf-idf权重
texts_train_weight= tf_idf.toarray()
# print("\ntf_idf的结果打印")
# print(tf_idf)
print("\n tf_idf的结果打印展开成稀疏矩阵的样式")
print(texts_train_weight)


 2.2.2.关于函数CountVectorizer小结

1、CountVectorizer是属于常见的特征数值计算类,是一个文本特正提取方法。
2、对于每一个训练文本,它只考虑每种词汇在该训练文本中出现的的频率。CountVectorizer会将文本中的词语转换为词频矩阵,通过类美中的fit_transform函数实现。

# CountVectorizer的详细参数设置
CountVectorizer(input='content',
    encoding='utf-8',
    decode_error='strict',
    strip_accents=None,
    lowercase=True,
    preprocessor=None,
    tokenizer=None,
    stop_words=None,
    token_pattern='(?u)\b\w\w+\b',
    ngram_range=(1,1),
    analyzer='word',
    max_df=1.0,
    min_df=1,
    max_features=None,
    vocabulary=None,
    binary=False,
    dtype=<class 'numpy.int64>)

ngram_rang:词组切分的长度范围
max_df:可以设置为范围在10.01.0的hoat,也可以设置为没有范围限制的int,默认为1.0。这个参数的作用是作为一个岗值,当构造语料库的关键词集的时候,如果某个词的document frequence大于max_df,这个词不会被当作关键词。如果这个参数是foat,则表示词出现的次数与语料库文档数的百分比,如果是int,则表示词出现的次数。如果参数中已经给定了vocabulary,则这个参数无效
min_df:类似于max_df,不同之处在于如果某个词的document frequence小于min_df,则这个词不会被当作关键词,

max_features:默认为None,可设为int,对所有关键词的term frequency进行降序排序,只取前max_features个作为关键词集
1、CountVectorizer是通过fit_transform函数将文本中的词语转换为为词频矩阵
2、矩阵元素a[i][j]表示j词在第i个文本下的词频。即各个词语出现的次数 
3、通过get_feature_names(可看到所有文本的关键字,通过toarray(可看多到词频矩阵的结果。

2.2.3.方法二:TfidfVectorizer
# 添加停用词
file_path=r'./stop.txt'
stop_words = stop_word_list(file_path=file_path)

# 新建对象
tfidfvectorizer = TfidfVectorizer(stop_words=stop_words)

# 计算
new_tf_data = tfidfvectorizer.fit_transform(data_new)

#tf_idf的结果打印展开成稀疏矩阵的样式
weight = new_tf_data.toarray()
print("tf_idf的结果打印展开成稀疏矩阵的样式")
print(weight)

word = tfidfvectorizer.get_feature_names()
print(word)

#获取词频
print("获取词频")
tfidfvectorizer.vocabulary_
2.2.4.TfidfVectorizer和TfidfTransformer的区别

1.相同点: 二者都可以计算词频的权值
2.不同点:
        TfidfTransformer()就是将类变换成tfidf的值,通常和CountVectorizer()结合,先将文本类转化为机器所能训练识别的数字特征。再通过TfidfTransformer()来计算权值,从而得到重要性程
度,Tfidfvectorizer()简单讲就是将上面两个类合并,一次性从文本类型转化,得到最后的权值。

2.2.5.关于函数TfidfVectorizer小结

TfidfVectorizer()相关常用参数
1.get_feature_names_out0:得到最后的特征数组(numpy.ndarray类型)
2.get_feature_names0:和get_feature_names_out(结果一样,随着skleann版本的升级,官方更加推荐使用get_feature_names_out()
3.toarray():并不是TfidfVectorizer0的参数,但是因为经常转化成比较容易看的数组,会将权值数组进行矩阵转化。
4. vocabulary:返回所有特征和特征在TD-IDF中的位置对应关系
5.stop_words:停用词集合,当为'english'时,ENGLISH_STOP_WORDS中定义的词会被忽略,如果为list,list中的单词即为要忽略的词。
6.max_df:设定当某个词超过一个df(document frequency)的上限时就忽略该词。当为0~1的float时表示d的比例,当为int时表示df数量
7.idf:输出一串权值数组,但是具体含义不清楚。该参数找了很多资料没有记录,等待后续有了解待补充。

 3. 画图

        3.1.词云图
from wordcloud import WordCloud
from matplotlib import pyplot as plt

def show_word_cloud(word_fre):
    # font_path表示指定字体路径
    # word_fre为一个字典,而画词云图的关键就是得到这个字典,字典的形式为{'word':weight},其中weight既可以是词频(如通过分词后统计每个词的词频),也可以是词语对应的权重值
    word_cloud = WordCloud(font_path='./simhei.ttf',
                           background_color='white'
                           colormap='autumn',
                           width=800,
                           height=400,
                           scale=4,
                           max_font_size=70)
    word_cloud.fit_words(word_fre)
    plt.figure(figsize=(8,6))
    plt.imshow(word_cloud)
    plt.xticks([])    # 去掉废坐标
    plt.yticks([])    # 去掉纵坐标
    plt.show()

4.结果提取

import pandas as pd
df = pd.DataFrame(list(tfidfvectorizer.vocabulary_.items()),columns=['vector', 'freq'])
df.sort_values(by=['freq'],ascending=[False], inplace=True)
df.head()

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值