Advertisement

【NLP】天池新闻文本分类(二)——数据读取与数据分析

阅读量:

【NLP】天池新闻文本分类(二)——数据读取与数据分析

  • 前言
  • 数据读取
  • 数据分析
  • 分析结论

前言

NLP之新闻文本分类挑战赛(赛题链接)。
其实上一篇赛题理解时已经做了数据读取和分析,因为一般在分析之后才对题目有初步理解。但为了流程完整性,还是做一篇独立的数据读取与分析,采用Pandas库实现。

数据读取

使用Pandas库完成数据读取操作

复制代码
    #导入包
    import pandas as pd
    train_df = pd.read_csv('./data/训练集数据/train_set.csv',sep='\t',nrows=100)

这里使用到的read_csv由三部分构成:
1.读取文件路径;
2.分隔符sep,为每列分割的字符,本赛题存储的数据分隔符为\t;
3.读取行数nrows,由于数据集比较大,可以先设置为100预览。
读取完后可以浏览下数据

复制代码
    #预览数据
    train_df.head()

在这里插入图片描述
上图是读取好的数据,是表格形式。第一列(label)为新闻的类别,第二列(text)为新闻的字符。

数据分析

使用Pandas库分析赛题数据的分布规律。
1.数据整体情况

复制代码
    train_df = pd.read_csv('./data/训练集数据/train_set.csv',sep='\t')
    train_df.info()
在这里插入图片描述
复制代码
    train_df.describe()

在这里插入图片描述
训练集样本20w条,没有空的数据。
2.新闻文本句子长度分布情况:

复制代码
    #新闻文本句子长度分布情况
    train_df['text_len'] = train_df['text'].apply(lambda x : len(x.split(' ')))
    print(train_df['text_len'].describe())

在这里插入图片描述
对新闻句子的统计看出,本赛题给定的句子文本比较长,每个句子平均由907个字符构成,最短的句子长度为2,最长的句子长度为57921。

绘制句子长度的直方图,以便分析句子长度的分布:

复制代码
    #绘制句子长度的直方图
    import matplotlib.pyplot as plt
    %pylab inline
    _ = plt.hist(train_df['text_len'],bins=200)
    plt.xlabel('Text char count')
    plt.title('Histogram of char count')

在这里插入图片描述
由上可见赛题数据的大部分句子长度都在2000字符以内。
2.新闻类别分布情况:
在数据集中标签的对应关系如下:{‘科技’: 0, ‘股票’: 1, ‘体育’: 2, ‘娱乐’: 3, ‘时政’: 4, ‘社会’: 5, ‘教育’: 6, ‘财经’: 7, ‘家居’: 8, ‘游戏’: 9, ‘房产’: 10, ‘时尚’: 11, ‘彩票’: 12, ‘星座’: 13}

复制代码
    #绘制新闻类别的直方图
    train_df['label'].value_counts().plot(kind='bar')
    plt.title('News class count')
    plt.xlabel("category")

在这里插入图片描述
从以上统计结果可以看出,赛题的数据集类别分布存在较为不均匀的情况。在训练集中科技类新闻最多,其次是股票类新闻,最少的新闻是星座新闻。
3.字符的分布情况:
a.词频统计
新闻各句子的字符分布情况,即词频统计:首先将训练集中所有的句子进行拼接,然后划分为字符,并统计每个字符的个数。

复制代码
    #句子词频统计
    #from collections import Counter  也可以使用计数的包,但是个人电脑内存不足,报MemoryError。
    word_count = {}
    for i in range(len(train_df['text'])):
    for word in train_df['text'][i].split(' '):
        if word not in word_count:
            word_count[word] = 0
        word_count[word] += 1
    word_count = sorted(word_count.items(),key=lambda w:w[1],reverse=True)
    print(len(word_count))
    print(word_count[0])
    print(word_count[-1])

在这里插入图片描述
从统计结果可以看出,在训练集中总共包括了6869个字符,其中编号’3750’的字符出现次数最多,编号’3133’的字符出现次数最少。
b.句子统计
查看唯一字符在每条新闻中出现的频率,通过出现次数太过频繁的反推为标点符号。

复制代码
    #唯一字符在每条新闻中出现的频率,top3
    train_df['text_unique'] = train_df['text'].apply(lambda x : ' '.join(list(set(x.split(' ')))))
    all_lines = ' '.join(list(train_df['text_unique']))
    word_count = Counter(all_lines.split(' '))
    word_count = sorted(word_count.items(),key=lambda w:w[1],reverse=True)
    print(word_count[0:3])

在这里插入图片描述
从统计结果可以看出,top3为编号’3750’、‘900’、‘648’字符,在20w新闻中的覆盖率分别为99.00%、98.83%、95.99%,很有可能是标点符号。
以下假设字符’3750’、‘900’、'648’是新闻text的标点符号,分析每篇新闻的句子数:

复制代码
    #split一次指定多个分隔符可以用re模块
    #假设3750、900、648为标点符号,统计平均每篇新闻由多少个句子组成
    import re
    train_df['text_sentence'] = train_df['text'].apply(lambda x : re.split('3750|900|648',x))
    train_df['text_sentence_count'] = train_df['text_sentence'].apply(lambda x : int(len(x)))
    print(train_df['text_sentence_count'].describe())
    #绘制句子长度的直方图
    _ = plt.hist(train_df['text_sentence_count'],bins=200)
    plt.xlabel('Text sentence count')
    plt.title('Histogram of text sentence count')

在这里插入图片描述
在这里插入图片描述
从统计结果可以看出,在假设字符’3750’、‘900’、'648’是新闻text的标点符号前提下,赛题每篇新闻平均由81个句子构成,最少由1个句子构成,最多由3460个句子构成。
c.按类别词频统计
以下按类别进行词频统计,统计每类新闻中出现次数最多的字符。

复制代码
    #按类别进行词频统计
    from collections import Counter
    category_text_count = {}
    for i in range(len(set(train_df['label']))):
    all_lines = ' '.join(list(train_df.loc[train_df['label']==i,'text']))
    count = Counter(all_lines.split(' '))
    category_text_count[i] = count.most_common(5)
    for k, v in category_text_count.items():
    print(k,v)
在这里插入图片描述

以上统计每类新闻中出现次数top5的字符。

分析结论

通过上述分析,可以得出如下结论
1.赛题中每个新闻包含的字符个数平均为1000个左右,还有一些新闻字符较长;
2.赛题中新闻类别分布不均匀;
3.赛题总共包括7000~8000个字符。
根据结论,如下注意点
1.每个新闻平均字符个数较多,可能需要截断;
2.由于类别不均衡,会严重影响模型的精度。

全部评论 (0)

还没有任何评论哟~