Datawhale-零基础入门NLP-新闻文本分类Task02

Task01里边对赛题进行了分析,接下来进行数据读取与数据分析,通过使用Pandas库完成数据读取和分析操作。

1 数据读取

由赛题数据格式可知,可通过read_csv读取train_set.csv数据:

import pandas  as pd
import numpy as np
import matplotlib.pyplot as plt

#读取全量数据
train_df = pd.read_csv('./data/data45216/train_set.csv',sep='\t')
train_df.shape

#读取部分数据
train_df = pd.read_csv('./data/data45216/train_set.csv',sep='\t',nrows=100)
train_df.shape

参数:sep每列的分隔符,用‘\t’分割,nrows=100,读取100条数据

Pandas还可以读取sql,excel,table,html,json等格式数据。

2 数据分析

2.1 计算新闻文本的长度

赛题数据中每行句子的字符使用空格进行分隔,可通过直接统计单词的个数得到每个句子的长度。

train_df['text_len'] = train_df['text'].apply(lambda x:len(x.split(' ')))
print(train_df['text_len'].describe())

由输出结果可知,句子的长度均值在907,最短的长度是2,最大的长度是57921:

查看句子长度的直方图:

_ = plt.hist(train_df['text_len'],bins=50)
plt.xlabel('Text char count')
plt.title('Histogram of char count')

输出结果:

2.2 查看赛题数据的类别分布

通过绘制直方图来查看每个新闻类别的分布。

train_df['label'].value_counts().plot(kind='bar')
plt.title('News class count')
plt.xlabel('category')

由输出结果可知,大部分的新闻分布是0,1,2,最少的是13,新闻的类别标识为:{‘科技’:0,‘股票’:1,‘体育’:2,‘娱乐’:3,‘时政’:4,‘社会’:5,‘教育’:6,‘财经’:7,‘家居’:8,‘游戏’:9,‘房产’:10,‘时尚’:11,‘彩票’:12,‘星座’:13}。

2.3 字符分布

统计每个字符出现的次数,将句子进行拼接进而划分为字符,并统计每个字符的个数。通过统计,知道3750,900,648的出现频率较高,可推测为标点符号。

from collections import Counter

#将文本变为一个list
all_lines = ' '.join(list(train_df['text']))
print(len(all_lines))
#对每个词统计个数
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])

使用Lambda函数,先对train_df['text']的数据进行去重,然后拼接统计:

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(len(word_count))
print(word_count[0])
print(word_count[-1])

分析结论:

1.每个新闻的字符个数在900多,还有个别新闻较长,可能需要截断;

2.新闻类别分布不均匀,会影响模型精度。

3 作业

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

一、利用for循环实现

flaglist1 = []
flaglist2 = []
flaglist3 = []
for i in range(train_df['text'].shape[0]):
    flag1,flag2,flag3 = train_df['text'].loc[i].split(' ').count('3750'),train_df['text'].loc[i].split(' ').count('900'),train_df['text'].loc[i].split(' ').count('648')
    flaglist1.append(flag1)
    flaglist2.append(flag2)
    flaglist3.append(flag3)
flaglist = list(map(lambda x:x[0]+x[1]+x[2],zip(flaglist1,flaglist2,flaglist3)))
train_df['flag_freq'] = flaglist
train_df['flag_freq'].mean()

二、用Counter实现

train_df['text_freq'] = train_df['text'].apply(lambda x: ' '.join(list(x.split(' '))))
print(len(train_df['text']))
# # #将文本变为一个list
strlist1 = []
strlist2 = []
strlist3 = []
for i in range(train_df['text_freq'].shape[0]):
    all_lines = train_df['text_freq'].loc[i]
    # #对每个词统计个数
    word_count = Counter(all_lines.split(' '))
    # print(word_count['3750'],word_count['900'],word_count['648'])
    strlist1.append(word_count['3750'])
    strlist2.append(word_count['900'])
    strlist3.append(word_count['648'])
    

flaglist = list(map(lambda x:x[0]+x[1]+x[2],zip(strlist1,strlist2,strlist3)))
train_df['flag_freq'] = flaglist
train_df['flag_freq'].mean()

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

一、用groupby进行分组实现

groupdata = train_df.groupby(by=['label'])
print(groupdata.size())

#每类新闻出现最多的词
max_freq = []
for i in range(len(groupdata.size())):
    df = groupdata.get_group(i)['text'].apply(lambda x: ' '.join(list(x.split(' '))))
    all_lines = ' '.join(list(df))
    word_count = Counter(all_lines.split(' '))
    del word_count['3750']
    del word_count['900']
    del word_count['648']
    word_count = sorted(word_count.items(),key=lambda d:int(d[1]),reverse=True)
    print(word_count[1][0])
    max_freq.append(word_count[1][0])

二、通过Pandas的类别数据实现

train_df['new_label'] = pd.cut(train_df['label'],[-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13],labels=['0','1','2','3','4','5','6','7','8','9','10','11','12','13'])
train_df.set_index('new_label').sort_index(ascending=False).head()

max_freq = []
for i in range(14):
    df = train_df[train_df['new_label']==str(i)]['text'].apply(lambda x: ' '.join(list(x.split(' '))))
    all_lines = ' '.join(list(df))
    word_count = Counter(all_lines.split(' '))
    del word_count['3750']
    del word_count['900']
    del word_count['648']
    word_count = sorted(word_count.items(),key=lambda d:int(d[1]),reverse=True)
    print(word_count[1][0])
    max_freq.append(word_count[1][0])

思考:如何解决类别不均衡问题?

猜你喜欢

转载自blog.csdn.net/qq_28409193/article/details/107506625