文本特征提取之TF-IDF算法(原理+Python代码)

数据来源于天池赛题:零基础入门数据分析-学术前沿趋势分析

目录

    • 一、原理介绍
    • 二、代码实现
      • 2.1数据预处理
      • 2.2使用TF-IDF提取特征
      • 2.3建立分类模型
    • 三、结果解释

一、原理介绍

TF-IDF方法常用来评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。在一个特定文件中,当某类词语出现的频率较高,同时该类词语在整个语料库中出现频率较低时,该类词语的TF-IDF就会比较高。

TF-IDF在中文中指词频-逆向文件频率,由TF(词频)和IDF(逆向文件频率)两个部分组成。

其中,TF(词频)指的是某一个给定的词语在该文件中出现的次数,TF的计算公式为:

T F w = 在 某 一 类 中 词 条 w 出 现 的 次 数 该 类 中 所 有 的 词 条 数 目 TF_{w}=\frac{在某一类中词条w出现的次数}{该类中所有的词条数目} TFw=w

IDF(逆向文件频率)的主要思想是:如果包含词条t的文档越少, IDF越大,则说明词条具有很好的类别区分能力。TDF的计算公式为:

I D F = l o g ( 语 料 库 的 文 档 总 数 包 含 词 条 w 的 文 档 数 + 1 ) IDF=log\left ( \frac{语料库的文档总数}{包含词条w的文档数+1}\right ) IDF=log(w+1)

公式中分母之所以要加1,是为了避免分母为0

这里通过对计算机领域论文的标题和摘要进行文本特征提取,并根据这些文本特征来训练多分类模型,以此来识别不同类型的论文。

二、代码实现

# 导入所需的package
import seaborn as sns #用于画图
from bs4 import BeautifulSoup #用于爬取arxiv的数据
import re #用于正则表达式,匹配字符串的模式
import requests #用于网络连接,发送网络请求,使用域名获取对应信息
import json #读取数据,我们的数据为json格式的
import pandas as pd #数据处理,数据分析
import matplotlib.pyplot as plt #画图工具
import warnings
warnings.filterwarnings("ignore") #过滤掉警告的意思
from pyforest import *
#定义读取文本数据的函数
def readArxivFile(path, columns=['id', 'submitter', 'authors', 'title', 'comments', 'journal-ref', 'doi',
       'report-no', 'categories', 'license', 'abstract', 'versions',
       'update_date', 'authors_parsed'], count=None):
    '''
    定义读取文件的函数
        path: 文件路径
        columns: 需要选择的列
        count: 读取行数
    '''
    
    data  = []
    with open(path, 'r') as f: 
        for idx, line in enumerate(f): 
            if idx == count:
                break
                
            d = json.loads(line)
            d = {col : d[col] for col in columns}
            data.append(d)

    data = pd.DataFrame(data)
    return data

data = readArxivFile('F:/data/arxiv-metadata-oai-2019.json', 
                     ['id', 'title', 'categories', 'abstract'],
                    200000)
#查看数据前五行
data.head()
id title categories abstract
0 0704.0297 Remnant evolution after a carbon-oxygen white ... astro-ph We systematically explore the evolution of t...
1 0704.0342 Cofibrations in the Category of Frolicher Spac... math.AT Cofibrations are defined in the category of ...
2 0704.0360 Torsional oscillations of longitudinally inhom... astro-ph We explore the effect of an inhomogeneous ma...
3 0704.0525 On the Energy-Momentum Problem in Static Einst... gr-qc This paper has been removed by arXiv adminis...
4 0704.0535 The Formation of Globular Cluster Systems in M... astro-ph The most massive elliptical galaxies show a ...

2.1数据预处理

#将数据中的'title'列与'abstract'列进行合并,便于后续分类模型的训练
data['text'] = data['title'] + data['abstract']

data['text'] = data['text'].apply(lambda x: x.replace('\n',' '))
data['text'] = data['text'].apply(lambda x: x.lower())
data = data.drop(['abstract', 'title'], axis=1) #删除原有的列
#对数据中的多个类别和单个类别进行处理
# 多个类别,包含子分类
data['categories'] = data['categories'].apply(lambda x : x.split(' '))

# 单个类别,不包含子分类
data['categories_big'] = data['categories'].apply(lambda x : [xx.split('.')[0] for xx in x])
#对数据进行类别编码
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
data_label = mlb.fit_transform(data['categories_big'].iloc[:])
data_label.shape

(170618, 34)

2.2使用TF-IDF提取特征

from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(max_features=4000) #提取特征,限定特征提取数量不超过4000个
vectorizer

TfidfVectorizer(analyzer=‘word’, binary=False, decode_error=‘strict’,
dtype=, encoding=‘utf-8’,
input=‘content’, lowercase=True, max_df=1.0, max_features=4000,
min_df=1, ngram_range=(1, 1), norm=‘l2’, preprocessor=None,
smooth_idf=True, stop_words=None, strip_accents=None,
sublinear_tf=False, token_pattern=’(?u)\b\w\w+\b’,
tokenizer=None, use_idf=True, vocabulary=None)

data_tfidf = vectorizer.fit_transform(data['text'].iloc[:])

2.3建立分类模型

# 划分训练集和验证集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(data_tfidf, data_label,
                                                 test_size = 0.2,random_state = 1)
# 构建多标签分类模型
#这里使用先验为多项式分布的朴素贝叶斯模型
from sklearn.multioutput import MultiOutputClassifier
from sklearn.naive_bayes import MultinomialNB 
clf = MultiOutputClassifier(MultinomialNB()).fit(x_train, y_train)
clf

MultiOutputClassifier(estimator=MultinomialNB(alpha=1.0, class_prior=None,
fit_prior=True),
n_jobs=None)

#评估模型拟合效果,输出分类模型报告
from sklearn.metrics import classification_report
print(classification_report(y_test, clf.predict(x_test)))
              precision    recall  f1-score   support

           0       0.00      0.00      0.00         0
           1       0.00      0.00      0.00         1
           2       0.00      0.00      0.00         0
           3       0.91      0.85      0.88      3625
           4       0.00      0.00      0.00         4
           5       0.00      0.00      0.00         0
           6       0.00      0.00      0.00         1
           7       0.00      0.00      0.00         0
           8       0.77      0.76      0.77      3801
           9       0.84      0.89      0.86     10715
          10       0.00      0.00      0.00         0
          11       0.00      0.00      0.00       186
          12       0.44      0.41      0.42      1621
          13       0.00      0.00      0.00         1
          14       0.75      0.59      0.66      1096
          15       0.61      0.80      0.69      1078
          16       0.90      0.19      0.32       242
          17       0.53      0.67      0.59      1451
          18       0.71      0.54      0.62      1400
          19       0.88      0.84      0.86     10243
          20       0.40      0.09      0.15       934
          21       0.00      0.00      0.00         1
          22       0.87      0.03      0.06       414
          23       0.48      0.65      0.55       517
          24       0.37      0.33      0.35       539
          25       0.00      0.00      0.00         1
          26       0.60      0.42      0.49      3891
          27       0.00      0.00      0.00         0
          28       0.82      0.08      0.15       676
          29       0.86      0.12      0.21       297
          30       0.80      0.40      0.53      1714
          31       0.00      0.00      0.00         4
          32       0.56      0.65      0.60      3398
          33       0.00      0.00      0.00         0

   micro avg       0.76      0.70      0.72     47851
   macro avg       0.39      0.27      0.29     47851
weighted avg       0.75      0.70      0.71     47851
 samples avg       0.74      0.76      0.72     47851

三、结果解释

在上面文本分类模型的评估结果中,precision表示查准率,recall表示查全率,f1-score表示F1值,support表示准确分类的论文数量。从评估结果可以看出,在模型训练的33个类别中,不同类别上的准确率差异很大。平均而言,准确率有百分之七十多。

你可能感兴趣的:(python,机器学习,人工智能,深度学习,自然语言处理)