Datawhale - 入门NLP之新闻文本分类 - task2 数据分析

PS. 前面已经学习记录了: Datawhale - 入门NLP之新闻文本分类 - task1 赛题理解

今天继续学习记录:task2 数据分析,主要是对巡检集的数据进行分析,统计,了解数据整体的分布情况!

目录

1 竞赛数据来源

2 训练集数据分析

3 数据分析结论

4 扩展分析


1 竞赛数据来源

         竞赛数据来源,进入天池实验室 -- “零基础入门NLP - 新闻文本分类”:           https://tianchi.aliyun.com/competition/entrance/531810/information,然后点击报名参赛,再点击“赛题与数据”,即可下载数据了。

        数据下载完成后,按照csv中指定路径再去下载训练集,测试集,和需要提交的数据样式。

2 训练集数据分析

(1)读取数据

''' 读取训练集,空格符分割,前20行 '''
import pandas as pd
train_df = pd.read_csv('data/train_set.csv', sep='\t', nrows=20)
print(train_df)

       这里读取了训练集的前20行,从下面打印结果可以看到,数据集一共两列,第一列是label,第二列是text新闻文本数据,以空格隔开(比赛官方已经将文本数据每个字符进行处理过了)。

    

(2)句子长度分析

        接下来,我们将训练集所有读入,来分析训练每一行(即每个样本的句子)综合的一些句子长度统计分析:

''' 将text进行空格分割开,统计每一行的字符数量,给到text_len列 '''
import pandas as pd
train_df = pd.read_csv('data/train_set.csv', sep='\t')
print(train_df.shape)  # 行/列数
train_df['text_len'] = train_df['text'].apply(lambda x: len(x.split(' ')))
print(train_df.head(20))

         从下面打印结果,可以看到,训练集一共20w行,两列。   然后再为df新增一列‘text_len’表示每一行的字符数:

        继续对‘text_len’进行分析,整体把握训练集的样本字符数情况:

''' 查看text_len列的详情统计描述'''
print(train_df['text_len'].describe())

        从下面打印结果可以看到,每个句子平均由907个字符构成,最短的句子长度为2,最长的句子长度为57921等统计信息:

        再继续讲句子长度信息,绘制直方图:

''' 每一个文本长度的数据直方图统计 '''
import matplotlib.pyplot as plt
_ = plt.hist(train_df['text_len'], bins=200)
plt.xlabel('Text char count')
plt.title("Histogram of char count")
plt.show()  # 显示图片

从直方图结果,结合分析,可以得知,大部分句子的长度都集中在2000以内:

(3)新闻句子的类别统计情况

        下面对训练集中样本的所有类进行统计,看分布情况如何:

''' 所有类别统计情况 '''
import matplotlib.pyplot as plt
train_df['label'].value_counts().plot(kind='bar')
plt.title('News class count')
plt.xlabel("category")
plt.show()  # 显示图片

        从结果,可以看出:  赛题的数据集类别分布存在较为不均匀的情况。在训练集中科技类新闻最多,其次是股票类新闻,最少的新闻是星座新闻。(注:task1中已经解释过,类别对应关系分别为:{'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4, '社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}

(4)所有样本中,字符类别和数量统计:

       前面统计过样本中字符的数量情况(注:由于全部统计单机有点卡,这里我取了1w条数据样本),下面进行统计每一种字符类别和对应数量的一个关系情况:

''' 统计所有训练集中 所有词,出现次数最多的词,出现次数最少的词 '''
from collections import Counter
all_lines = ' '.join(list(train_df['text']))  # 将每一行text再以空格,连起来
word_count = Counter(all_lines.split(" "))  # 统计数字和出现次数
# 每一个字符和它出现的次数,组成元组,按照由多到少排序
word_count = sorted(word_count.items(), key=lambda d: d[1], reverse=True)
print(len(word_count))  # 总共字符类别有多少种
print(word_count[0])  # 统计最多的字符类别
print(word_count[-1])  # 统计最少的字符类别

    从打印结果可以看出:在抽样的1w条样本句子统计中,一共去重后5340个字符,3750的字符最多,6577的字符最少。

    实际上,这里还可以根据字在每个句子的出现情况,反推出标点符号。经官方统计,20w所有样本中:其中字符3750,字符900和字符648在20w新闻的覆盖率接近99%,很有可能是标点符号。

3 数据分析结论

        经对训练集的各种统计,可以得出如下结论:

        (1)赛题中每个新闻包含的字符个数平均为1000个,还有一些新闻字符较长;

        (2)赛题中新闻类别分布不均匀,科技类新闻样本量接近4w,星座类新闻样本量不到1k;

        (3)赛题总共包括7000-8000个字符;

        (4)每个新闻平均字符个数较多,可能需要截断;

        (5)由于类别不均衡,会严重影响模型的精度;

4 扩展分析

        (1)假设前面说的字符3750,字符900和字符648是句子的标点符号,请分析赛题每篇新闻平均由多少个句子构成?

# 统计没有标点的句子数 (按照标点进行split,剩下的就是句子) ####################
import re
import pandas as pd
train_df = pd.read_csv('data/train_set.csv', sep='\t')
train_df['juzi_len'] = train_df['text'].apply(lambda x: len(re.split('3750|900|648', x)))
print(train_df['juzi_len'].describe())

        运行结果来看,平均句子数为:80.802370 

  (2)统计每类新闻中出现次数最多的字符。

''' 统计每类新闻中出现次数最多的字符 '''
import pandas as pd
from collections import Counter
train_df = pd.read_csv('data/train_set.csv', sep='\t')
# 同一类的拼接到一起
for i in range(0, 14):
    df = train_df[train_df['label'] == i]['text']
    all_lines = ' '.join(list(df))  # 将每一行text再以空格,连起来
    word_count = Counter(all_lines.split(" "))  # 统计数字和出现次数
    word_count = sorted(word_count.items(), key=lambda d: d[1], reverse=True)  # 排序
    print(i, word_count[0])

我们发现运行结果如下:

因此,还是需要去掉标点符号再统计!!!!!!!!!!!

新的实现如下:

''' 统计每类新闻中出现次数最多的字符 '''
import pandas as pd
from collections import Counter
train_df = pd.read_csv('data/train_set.csv', sep='\t')
# 同一类的拼接到一起
for i in range(0, 14):
    df = train_df[train_df['label'] == i]['text']
    bioadian = ['3750', '900', '648']
    df_2 = df.apply(lambda x: [i for i in x.split(' ') if i not in bioadian])
    all_lines = str(df_2.values.tolist())
    word_count = Counter(all_lines.split(" "))  # 统计数字和出现次数
    word_count = sorted(word_count.items(), key=lambda d: d[1], reverse=True)  # 排序
    print(i, word_count[0])  # 新闻类,次数最多的字符及次数

最后运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值