天池学习赛-NLP新闻文本分类(2/6)-数据分析

1 赛题理解

2 数据分析

  • 文本的字符长度分析
    -- 每条新闻的字符数的描述性统计分析
    -- 每条新闻的字符数的可视化分析(三种绘图方法的的直方图)
    -- 数据集的字符的分布统计

  • 标签类别的分析
    -- 两种绘图方法的条形图
    -- 标签类别占比分析

读取训练集数据

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
mpl.rcParams['font.sans-serif'] = ['KaiTi']
mpl.rcParams['font.serif'] = ['KaiTi']

%matplotlib inline

df = pd.read_csv(r'E:\jupyter_lab\天池\新闻文本分类\data\train\train_set.csv',sep='\t',encoding='utf8')
df.head()
训练集数据.png
df.shape   #查看数据大小 (200000,2)

2.1 文本的字符长度分析

1、每条新闻的字符数的描述性统计分析

df['text_len'] = df.text.apply( lambda x: len(x.split(' '))) #统计每行text的字符长度
df['text_len'].describe()

#len(df.loc[0,'text'].split(' '))  返回一个去掉空格后的列表长度
每条新闻字符信息的统计分析.png

2、每条新闻的字符数的可视化分析

三种不同的绘图方式

#pandas库
df.text_len.hist(bins=200)
plt.xlabel('字符长度')
plt.title('字符长度的直方图 histogram')
pandas库.png

seaborn 直方图教程

sns.distplot(df.text_len)
plt.xlabel('字符长度')
plt.title('字符长度的直方图 histogram')
seaborn 库.png
#matplotlib 库
plt.hist(df['text_len'],bins=200)
plt.xlabel('字符长度')
plt.title('字符长度的直方图 histogram')
plt.show()
matplotlib 库.png
字符长度的分析结果

1、由描述统计可知:均值907,方差996,最小值2,最大值57921。text的字符长度偏差很大。
2、由直方图可知:字符长度绝大多数在2000以内。

3、数据集的字符分布统计

from collections import Counter 基本操作及排序用法

from  collections import Counter

all_lines = ' '.join(list(df.text))
word_count = Counter(all_lines.split(' '))
word_count = sorted(word_count.items(), key=lambda x: x[1], reverse=True)

print('总的字符数量', len(word_count))
print('出现次数最多的字符', word_count[0])
print('出现次数最少的字符', word_count[-1])
image.png

根据字符在句子中的出现次数,推测标点符号。

df['text_unique'] = df.text.apply(lambda x: ' '.join(list(set(x.split(' ')))))
all_lines = ' '.join(list(df.text_unique))
word_count = Counter(all_lines.split(' '))
word_count = sorted(word_count.items(), key=lambda x: x[1], reverse=True)

print('出现次数最多的前三个字符', word_count[0],word_count[1],word_count[2])
出现次数最多的前三个字符.png
word_count[2].values/df.shape[0]  #96%

标点符号推测分析:
由于这前三个字符在text中出现占比高达96~%99%,故推测‘3750,‘900’,‘648’为标点符号。

假设出现最多的前三个字符为标点符号,推测每条新闻的句子数。

df['text_list'] = df.text.apply(lambda x: list(x.split(' ')))

df['text_sentence'] = df.text_list.apply(lambda x: x.count('3750')) + df.text_list.apply(lambda x: x.count('900')) + df.text_list.apply(lambda x: x.count('648'))

df.text_sentence.describe()

句子数的统计分析.png

每条新闻的句子数分析结果:
1、每条新闻平均由78个句子组成,标准差为86。
2、由于不包含推测的3种标点符号,故推断最小的句子数为1。以上述3种标点符号划分,每条新闻最多有3417个句子。

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

n=5 #要提取的前n个位置
for i in range(14):
    all_lines = ' '.join(list(df[df.label==i].text))
    word_count = Counter(all_lines.split(' '))
    word_count = sorted(word_count.items(), key=lambda x: x[1], reverse=True)

    print('类别为 %d 的新闻中总的字符数量 %d' %(i,len(word_count)) )
    print('类别为 %d 的新闻中出现次数最多的前 %d 个字符' %(i, n), word_count[:n]) 
每类新闻中出现次数最多的前三个字符(文章推测的标点符号).png

(除推测的标点符号外)每类新闻中出现次数最多的字符.png

可以看到有很多字符都是重复的,这些字符应该对区分文本类别没什么意义。

2.2 标签类别的分析

标签定义:
category = {'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4,'社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}

category = {'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4, '社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}

df.label.value_counts().plot(kind='bar')
plt.title('文本的类别分布条形图')
plt.xlabel('category')
plt.show() #可写可不写
category.png
sns.countplot(df.label)
plt.title('文本的类别分布条形图')
plt.xlabel('category')

category.png

两种绘图方式的区别

  • 1.使用方式不同
    直接用plot(kind='bar')要先计算值的个数,即调用value_counts()函数。
    seaborn画图可以使用countplot(),一起实现计数和画图。
  • 2.呈现方式不同
    df.label.value_counts().plot(kind='bar')按类别数量的大小,由高到低排序。
    sns.countplot(df.lable)按类别的代表名称排序
标签的分布分析结果:

1、标签类别差距较大,分布非常不平衡。
2、体育和娱乐标签最多,彩票和星座的标签最少。

print('最多的三类标签的占比:\n',df.label.value_counts()[0]/df.shape[0],'\n',df.label.value_counts()[1]/df.shape[0],'\n',df.label.value_counts()[2]/df.shape[0])
最多的三类标签的占比.png
print('最少的三类标签的占比:\n',df.label.value_counts()[11]/df.shape[0],'\n',df.label.value_counts()[12]/df.shape[0],'\n',df.label.value_counts()[13]/df.shape[0])
最少的三类标签的占比.png

比赛更新中,预告: 下一篇 基于机器学习的⽂本分类

你可能感兴趣的:(天池学习赛-NLP新闻文本分类(2/6)-数据分析)