咕咕这次又咕掉了她的专业课学习,来DataWhale零基础入门nlp,想着对大创有些帮助。
这次是Datawhale与天池联合发起的0基础入门系列赛事第三场 —— 零基础入门NLP之新闻文本分类挑战赛。
数据读取与数据分析
学习目标
- 学习使用
Pandas
读取赛题数据 - 分析赛题数据的分布规律
参考文献/辅助阅读:
数据读取
import pandas as pd
import numpy as np
import re
import matplotlib.pyplot as plt
file_path='train_set.csv'
train_df=pd.read_csv(file_path,sep='\t')
train_df
可以看到有20w条数据,其中第一列为新闻的类别,第二列为新闻的字符。
数据分析
赛题数据中,新闻文本的长度是多少?
# 句子长度分析:统计单词的个数
%pylab inline
train_df['text_len'] = train_df['text'].apply(lambda x: len(x.split(' ')))
print(train_df['text_len'].describe()) # 查看统计信息
# 统计信息
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
# 绘制直方图
_=plt.hist(train_df['text_len'],bins=200)
plt.xlabel('Text char count')
plt.title("Histogram of char count")
Text(0.5, 0, 'category')
-
DataFrame.apply(self, func, axis=0, broadcast=None, raw=False, reduce=None, result_type=None, args=(), **kwds)[source]
apply是对
DataFrame
的行或列应用一个方法。 -
lambda 函数是一种小的匿名函数。
赛题数据的类别分布是怎么样的,哪些类别比较多?
# 新闻类别统计:使用pandas进行绘图
train_df['label'].value_counts().plot(kind='bar')
plt.title('News class count')
plt.xlabel("category")
Text(0.5, 0, 'category')
这是数据集中标签对应的关系:
{'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4, '社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}
赛题数据中,字符分布是怎么样的?
# 字符分布统计:将训练集中所有句子进行拼接,划分为字符,统计每个字符的个数
from collections import Counter
all_lines=' '.join(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
# 标点符号预测:对每条新闻中出现的字符进行去重,然后将所有句子拼接,统计每个字符的个数
train_df['text_unique']=train_df['text'].apply(lambda x: ' '.join(list(set(x.split(' ')))))
all_lines_unique=' '.join(train_df['text_unique'])
word_count_unique=Counter(all_lines_unique.split(' '))
word_count_unique=sorted(word_count_unique.items(),key=lambda d:int(d[1]),reverse=True)
word_count_unique[0:5]
[('3750', 197997),
('900', 197653),
('648', 191975),
('2465', 177310),
('6122', 176543)]
可以看到,3750、900和648字符出现次数>190000,也就是出现频率>95,可能是标点符号。
数据分析的结论
通过上述分析我们可以得出以下结论:
- 赛题中每个新闻包含的字符个数平均为1000个,还有一些新闻字符较长;
- 赛题中新闻类别分布不均匀,科技类新闻样本量接近4w,星座类新闻样本量不到1k;
- 赛题总共包括7000-8000个字符;
通过数据分析,我们还可以得出以下结论:
-
每个新闻平均字符个数较多,可能需要截断;
-
由于类别不均衡,会严重影响模型的精度;
本章作业
-
假设字符3750,字符900和字符648是句子的标点符号,请分析赛题每篇新闻平均由多少个句子构成?
思路:将每篇新闻用3750,900 ,648划分为句子,统计每篇新闻的句子个数。
train_df['sentence_num'] = train_df['text'].apply(lambda x: len(re.split('3750|900|648', x))) train_df['sentence_num'].describe()
count 200000.000000 mean 80.802370 std 86.955448 min 1.000000 25% 29.000000 50% 57.000000 75% 103.000000 max 3460.000000 Name: sentence_num, dtype: float64
可以看到,赛题每篇新闻平均由80.8个句子构成。
-
统计每类新闻中出现次数对多的字符。
思路:将训练集中所有句子去掉标点符号后,按label进行拼接,划分为字符,统计每个字符的个数。
all_lines_by_class=[]
for i in range(14):
line=' '.join(train_df[train_df['label']==i]['text'])
all_lines_by_class.append(re.sub('3750|940|648','',line))
for i,line in enumerate(all_lines_by_class):
line=filter(lambda x:x,line.split(' '))
word_count=Counter(line)
word_count=sorted(word_count.items(),key=lambda d:d[1],reverse=True)
print(i,":",word_count[0][0])
0 : 900
1 : 3370
2 : 900
3 : 900
4 : 900
5 : 900
6 : 900
7 : 900
8 : 900
9 : 900
10 : 900
11 : 900
12 : 4464
13 : 900
网友评论