利用Python实现TF-IDF算法进行文章分类

一、TF-IDF算法

       TF(Term Frequency)指词频,IDF(Inverse Document Frequency)指逆向文件频率。它的主要思想是:如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。简单来说,就是计算字符在文章中的重要性,并给它赋予相应的权,权重大越重要越能作为区分文章的工具。举个例子:“的”这个字在文章中往往出现最多,但是在其他文章中也很多出现,因此认为“的”重要性小,而比如这篇文章中大量出现“数学”,而其他文章中“数学”出现很少,说明对这篇文章来说,“数学”很重要,这篇文章也大概是讲数学的。

二、文章的向量化与分类方式

      那么,知道了每个字符的重要性后如何给文章分类呢?向量就登场了。我们生活在一个三维的空间之中,我们绝大多数人都能够理解的只有直线向量、平面向量和空间向量,它们分别像是这样a=(-3)(直线向量),b=(5,7)(平面向量),c=(1,6,-4)(空间向量)。而向量在更多维度下的表现对我们来说是不可见的,但是是可算的,比如五维的向量e1=(2,5,1,7,13)、e2=(14,6,4,9,10),我们没法把它们画出来,但是我们可以利用向量外积计算它们之间的夹角的余弦值,在每条维度上的数值都大于零时,夹角的范围便被限定为[0, ],所以余弦值越大,夹角越小,相反余弦值越小,夹角越大。而当我们将每一个字符都作为一个维度,文章中它们的权重作为它们的坐标,那么文章就可以用一条高维向量来表示,不同的文章会有不同的向量,当两篇文章所对应的向量夹角小的时候,说明具有区分度词或短语在这两篇文章中重合率越高,也就说明两篇文章越相似,相反向量夹角大,就说明两篇文章差别越大。将向量夹角小的文章分为一类,也就完成了将相似的文章分为一类这一任务,正确率不亚于人工。

三、python实现

首先我们需要一个字典,利用字典建立向量,这里我找了一个两千五百字的常用字字典命名为dictionary.txt

read_dictionary.py

def txttermnumber(files):
    """计算txt文件中每个字出现的个数"""
    # 打开文件
    fr = open(files, 'r', encoding='UTF-8')
    # 读取文件所有行
    content = fr.readlines()
    contentLines = ''

    characers = []
    stat = {}

    # 依次迭代所有行
    for line in content:
        # 去除空格
        line = line.strip()
        if len(line) == 0:
            continue
        contentLines = contentLines + line
        # 统计每一字出现的个数
        for x in range(0, len(line)):
            # 如果字符第一次出现 加入到字符数组中
            if not line[x] in characers:
                characers.append(line[x])
            # 如果是字符第一次出现 加入到字典中
            if line[x] not in stat:
                stat[line[x]] = 0
            # 出现次数加一
            stat[line[x]] += 0

    # 对字典进行倒数排序 从高到低 其中e表示dict.items()中的一个元素,
    # e[1]则表示按 值排序如果把e[1]改成e[0],那么则是按键排序,
    # reverse=False可以省略,默认为升序排列

    return stat

其次需要将文章转化为向量形式,注意在IDF中作为语料库的文案我是找的论文,地址为dll/

txt_turnto_vector.py

from read_dictionary import txttermnumber
from math import log


def tf(file):
    """计算词频"""
    dictionary = txttermnumber("dictionary.txt")
    # 打开文件
    fr = open(file, 'r', encoding='UTF-8')
    # 读取文件所有行
    content = fr.readlines()
    contentLines = ''

    characers = []
    stat = {}

    # 依次迭代所有行
    for line in content:
        # 去除空格
        line = line.strip()
        if len(line) == 0:
            continue
        contentLines = contentLines + line
        # 统计每一字出现的个数
        for x in range(0, len(line)):
            # 如果字符第一次出现 加入到字符数组中
            if not line[x] in characers:
                characers.append(line[x])
            # 如果是字符第一次出现 加入到字典中
            if line[x] not in stat:
                stat[line[x]] = 0
            # 出现次数加一
            stat[line[x]] += 1

    # 对字典进行倒数排序 从高到低 其中e表示dict.items()中的一个元素,
    # e[1]则表示按 值排序如果把e[1]改成e[0],那么则是按键排序,
    # reverse=False可以省略,默认为升序排列
    stat = sorted(stat.items(), key=lambda e: e[1], reverse=True)
    # 打印stat 每个字和其出现的次数 stat经过排序后变成二元组
    for i in stat:
        # 将stat里面所有在字典中的字输出加入到字典中
        if i[0] in dictionary.keys():
            dictionary[i[0]] += i[1]
        else:
            continue

    fr.close()
    for a in dictionary.keys():
        dictionary[a] = dictionary[a]/len(contentLines)
    return dictionary


def idf():
    """计算逆向文件频率"""
    n = 1
    dictionary = txttermnumber("dictionary.txt")

    while n < 67:
        n = str(n)
        file = 'dll/' + n + '.txt'
        fr1 = open(file, 'r', encoding='UTF-8')
        # 读取文件所有行
        content = fr1.readlines()
        contentLines = ''

        characers = []
        stat = {}

        # 同上
        for line in content:
            line = line.strip()
            if len(line) == 0:
                continue
            contentLines = contentLines + line
            for x in range(0, len(line)):
                if not line[x] in characers:
                    characers.append(line[x])
                if line[x] not in stat:
                    stat[line[x]] = 0
                stat[line[x]] += 1

        fr1.close()
        # 将文字出现的文章数附到字典中
        for i in stat:
            if i[0] in dictionary.keys():
                dictionary[i[0]] += 1
            else:
                continue
        n = int(n)
        n += 1
        # 计算字典的idf值
        for a in dictionary.keys():
            dictionary[a] = log(66/(dictionary[a]+1), 10)
    return dictionary


print(tf("TF-IDF.txt"))
print(tf("search.txt"))
print(idf())

最后进行向量运算

tfidf.py

from txt_turnto_vector import tf, idf


def tf_idf(file):
    """计算tf-idf"""
    tfidf = {}
    for i in tf(file).keys():
        tfidf[i] = tf(file)[i]*(idf()[i])
    return tfidf


def vector_inner_product(vector1, vector2):
    """用于计算两向量的内积"""
    n = 0
    num = 0
    while n < 2500:
        num += vector1[n]*vector2[n]
        n += 1
    num1 = 0
    num2 = 0
    for i in vector1:
        num1 += i**2
    for a in vector2:
        num2 += a**2
    num1 = num1**0.5
    num2 = num2**0.5
    cos12 = num/(num1 * num2)
    return cos12

 最后选择两篇文章可以计算出他们之间的cos值

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
### 回答1: Python中有很多现成的库可以实现tf-idf算法,比如scikit-learn和gensim等。以下是使用scikit-learn库实现tf-idf算法的示例代码: ```python from sklearn.feature_extraction.text import TfidfVectorizer # 定义文本列表 corpus = [ 'This is the first document.', 'This is the second second document.', 'And the third one.', 'Is this the first document?', ] # 创建TfidfVectorizer对象 vectorizer = TfidfVectorizer() # 对文本列表进行tf-idf向量化 X = vectorizer.fit_transform(corpus) # 输出向量化结果 print(X.toarray()) ``` 输出结果为: ``` [[0. 0.46979139 0.58028582 0.46979139 0. 0. 0.38408524 0. ] [0. 0.6876236 0. 0.28108867 0. 0.53864762 0.28108867 0. ] [0.57735027 0. 0. 0. 0.57735027 0. 0. 0.57735027] [0. 0.46979139 0.58028582 0.46979139 0. 0. 0.38408524 0. ]] ``` 可以看到,每个文本被转换成了一个向量,向量的每个元素代表了该文本中每个词的tf-idf值。 ### 回答2: TF-IDF算法是信息检索领域中的一种经典算法,用于评估一个词语在单篇文档或整个文集中的重要程度。在Python中,我们可以通过调用现成的第三方包来实现TF-IDF算法。 目前,Python中广泛使用的开源自然语言处理库是nltk(Natural Language Toolkit)和gensim。在这两个库中,gensim被认为是更适合处理大规模语料库的库。因此,我们在本文中将以gensim包为例,讲解如何使用Python实现TF-IDF算法的调包方法。 1. 安装gensim包 首先,我们需要安装gensim包。你可以通过pip在终端中输入以下命令来安装: ``` pip install -U gensim ``` 2. 导入gensim库 成功安装后我们需要在Python代码中导入gensim库,以方便调用TF-IDF算法。导入方式为: ``` import gensim ``` 3. 准备语料库 在使用gensim库中的TF-IDF算法计算文本相似度之前,我们需要先准备语料库。语料库包括一组文本或单词集合,其中每个文本、文档或语料库都对应着一个向量。在gensim库中,我们可以用List对象或一个文件来表示一个语料库,其中每个元素表示语料库中的一个文档或一行文本。 4. 创建词向量模型 在得到语料库之后,我们可以使用gensim库中的TfidfModel函数来创建文本的词向量模型。代码实现如下: ``` from gensim import corpora, models corpus = ['这是第一个文档', '这是第二个文档', '这是第三个文档'] texts = [[word for word in doc.split()] for doc in corpus] # 创建词袋模型 dictionary = corpora.Dictionary(texts) # 统计词语出现的次数 corpus_bow = [dictionary.doc2bow(text) for text in texts] # 计算TF-IDF权重 tfidf = models.TfidfModel(corpus_bow) ``` 上述代码中,我们首先将原始语料库转化为一个List对象(corpus),接着将每个文档按照单词进行分割,将结果存储到List对象texts中。之后,我们使用gensim库中的corpora.Dictionary函数创建了一个词袋模型。通过将texts中的每个文档转化为其相应的单词索引形式并统计每个单词的出现次数,我们得到了一个包含所有单词的字典(dictionary)以及每篇文档相对应的稀疏向量(corpus_bow)。 最后,我们通过TfidfModel函数计算每篇文档中的每个单词的TF-IDF权重值。通过设置normalize参数为True,我们可以对每个文档中的所有单词的权重进行标准化。 5. 计算相似度 通过上述步骤,我们已经得到了每个文档的词向量模型。接下来,我们还可以使用TF-IDF算法来计算文本之间的相似度。 在gensim库中,我们可以通过使用文本的稀疏向量表示形式来计算两个文本之间的相似度。举个例子,我们可以使用TF-IDF模型中的similarities函数来计算第一个文本与后两个文本之间的相似度。具体实现代码如下: ``` # 计算稀疏向量表示形式 doc1_bow = dictionary.doc2bow(texts[0]) doc2_bow = dictionary.doc2bow(texts[1]) doc3_bow = dictionary.doc2bow(texts[2]) # 计算文本的相似度 doc1_tfidf = tfidf[doc1_bow] doc2_tfidf = tfidf[doc2_bow] doc3_tfidf = tfidf[doc3_bow] similarity_1_2 = similarities.MatrixSimilarity([doc1_tfidf, doc2_tfidf]) print(similarity_1_2) ``` 在这段代码中,我们首先将第一个文本转换为其相应的稀疏向量(doc1_bow),然后使用tfidf函数计算该文本的TF-IDF权重(doc1_tfidf)。接着,我们分别计算第一个文本和第二个文本的相似度,将它们转换为相似度矩阵形式。 需要注意的是,在大规模语料库中,计算相似度的时间可能会非常长。为了避免这种情况,我们可以使用LSI或LSA等方法来降低文本表示空间的维度,以此提高计算速度,同时保持语义相似性不变。 ### 回答3: tf-idf是一种计算文本相似度的方法,在文本处理和自然语言处理中广泛应用。Python语言是一种流行的编程语言,其强大的文本处理功能使它成为实现tf-idf算法的好选择。Python社区中提供了许多流行的库,如Scikit-learn,Gensim等,可以方便地实现tf-idf算法。 在使用Python实现tf-idf算法时,我们可以使用Scikit-learn库中的TfidfVectorizer()方法。TfidfVectorizer()方法将文本数据集转换为tf-idf权重矩阵。它可以自动完成文本的预处理、标记化、停用词移除等任务。以下是Python实现tf-idf算法的步骤: 1. 导入必要的库:首先需要导入用于文本处理和tf-idf计算的库,如numpy、pandas和Scikit-learn中的TfidfVectorizer()方法。 2. 数据预处理:对原始文本进行预处理,包括去除特殊符号、标点符号、停用词等。 3. TfidfVectorizer()参数设置:设置TfidfVectorizer()方法的参数,例如,ngram_range、max_features、tokenizer等。 4. 计算tf-idf权重矩阵:使用TfidfVectorizer()方法计算tf-idf权重矩阵。 5. 选取关键词:根据tf-idf权重矩阵选取权重高的关键词。 6. 可视化结果:将选取的关键词可视化展示,帮助理解文本的主题和内容。 实现tf-idf算法Python代码如下: ``` import numpy as np import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer # 数据预处理 # 实例化 TfidfVectorizer tfidf_vectorizer = TfidfVectorizer(stop_words='english') # 加载数据 data = ["This is a sample document.", "Another document for practice.", "This is a sample sentence."] # 计算tf-idf权重矩阵 tfidf = tfidf_vectorizer.fit_transform(data) # 打印tf-idf矩阵 tfidf.toarray() # 选取关键词 # 获取特征名称 feature_names = tfidf_vectorizer.get_feature_names() # 定义一个函数,用于获取tf-idf权重 top n 关键词 def get_top_n_words(tfidf_vectorizer, tfidf_matrix, n): sorted_nzs = np.argsort(tfidf_matrix.data)[:-(n + 1):-1] return feature_names[tfidf_matrix.indices[sorted_nzs]] # 选取权重最高的前5个关键词 print(get_top_n_words(tfidf_vectorizer, tfidf, 5)) # 可视化结果 import matplotlib.pyplot as plt # 可视化选取的关键词 fig, ax = plt.subplots(figsize=(8, 6)) ax.bar(get_top_n_words(tfidf_vectorizer, tfidf, 5), tfidf.idf_[sorted_indices]) ax.set_ylabel('idf score') ax.set_xlabel('word') ax.set_title('Top 5 Words by TF-IDF Weight') plt.show() ``` 使用Python实现tf-idf算法,我们可以很方便地处理文本数据、计算tf-idf权重矩阵、选取关键词和可视化结果。Python的Scikit-learn库提供了许多有用的方法和函数,使我们能够更轻松地实现tf-idf算法,从而更好地分析和理解文本数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linductor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值