上一章节主要介绍了赛题内容和解决方案的思路。本章节会对原始样本集读取数据并对文本作简单的分析。
import re
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
通过read_csv
方法读取.csv
格式的数据。
train_df = pd.read_csv('../input/train_set.csv', sep='\t')
train_df.head()
可以看到,数据集包含两列,分别是label(标签)和text(匿名处理后的字符)。
%pylab inline
train_df['text_len'] = train_df['text'].apply(lambda x: len(x.split(' ')))
print(train_df['text_len'].describe())
Populating the interactive namespace from numpy and matplotlib
count 200000.000000
mean 907.207110
std 996.029036
min 2.000000
25% 374.000000
50% 676.000000
75% 1131.000000
max 57921.000000
Name: text_len, dtype: float64
对新闻句子的统计可以得出,本次赛题给定的文本比较长,每个句子平均由907个字符构成,最短的句子长度为2,最长的句子长度为57921。
下图将句子长度绘制了直方图,可见大部分句子的长度都集中在2000以内。
_ = plt.hist(train_df['text_len'], bins=200)
plt.xlabel('Text char count')
plt.title('Histogram of char count')
统计每类新闻的样本个数。
train_df['label'].value_counts().plot(kind='bar')
plt.xlabel('News class count')
plt.title('category')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rNwNSQMj-1595420042029)(img/类别分布.png)]
可以看出科技
、股票
类新闻达到35000条以上,而彩票
、星座
类新闻少于2500条。各类别的样本分布严重不平衡。
all_lines = ' '.join(list(train_df['text']))
word_count = Counter(all_lines.split(' '))
word_count = sorted(word_count.items(), key=lambda d: d[1], reverse=True)
print(len(word_count)) # 6869
print(word_count[0]) # ('3750', 7482224)
print(word_count[-1]) # ('3133', 1)
从统计结果中可以看出,在训练集中总共包括6869个字,其中编号3750的字出现的次数最多,编号3133的字出现的次数最少。
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 d: int(d[1]), reverse=True)
print(word_count[0]) # ('3750', 197997)
print(word_count[1]) # ('900', 197653)
print(word_count[2]) # ('648', 191975)
可以看出字符在不同文本中出现频率的前三甲分别是3750、900、648,出现在1.9万条新闻文本中,在总样本为2万条的数据中,覆盖率达99%,我们有理由相信这三个字符是标点符号。
# 通过3750、900、648标点符号分割新闻。
train_df['seme_list'] = train_df['text'].apply(lambda x: re.split('3750|900|648', x))
# 对分割后的句子前后去空格,过滤分割后空的字符,计算新闻短句数。
train_df['seme_num'] = train_df['seme_list'].apply(lambda x: len(list(filter(None, [i.strip() for i in x]))))
print(train_df['seme_num'].describe())
count 200000.000000
mean 79.466030
std 85.383165
min 1.000000
25% 28.000000
50% 56.000000
75% 102.000000
max 3393.000000
Name: seme_num, dtype: float64
统计分析得出,每篇新闻平均有79个短句,最少的新闻仅为1个句子,最长的新闻有3393个短句。
# 对每类新闻聚合并拼接
label_pd = train_df.groupby('label')['text'].apply(lambda x: x.str.cat(sep=' ')).reset_index()
# 过滤标点符号
label_pd['text'] = label_pd['text'].apply(lambda x: re.sub('3750 | 3750|900 | 900|648 | 648', '', x))
# 统计每类新闻的相同字符个数
label_pd['word_count'] = label_pd['text'].apply(lambda x: Counter(x.split(' ')))
# 降序排序
label_pd['word_count'] = label_pd['word_count'].apply(lambda x: sorted(x.items(), key=lambda d: d[1], reverse=True))
# 统计每类新闻中出现次数最多的字符
label_pd['word_most'] = label_pd['word_count'].apply(lambda x: x[0])
print(label_pd[['label', 'word_most']])
label word_most
0 0 (3370, 501743)
1 1 (3370, 625227)
2 2 (7399, 351630)
3 3 (6122, 187767)
4 4 (4411, 120314)
5 5 (6122, 159073)
6 6 (6248, 193521)
7 7 (3370, 158886)
8 8 (6122, 57282)
9 9 (7328, 46451)
10 10 (3370, 67703)
11 11 (4939, 18574)
12 12 (4464, 51418)
13 13 (4939, 9640)
统计得出,字符3370在科技
、股票
、财经
、房产
这四类新闻中出现的次数最多。
本章节对赛题数据进行读取,并新闻句子长度、类别和字符进行了可视化分析。可以得到以下结论:
科技
、股票
、财经
、房产
这四类新闻中出现的次数最多。同时,需要考虑以下问题: