正文之前的BB时间
还是个人实验的需要,实验语料数据句子Sequence的长短不一,最长的和最短的差了两个数量级,一起训练非常耗时。因此想在实验中,根据长度,把句子分成不同的桶Bucket,每个Bucket中句子个数大致相同,对Bucket分别进行训练。
记录一下分Bucket的过程。
这里是正文
分Bucket
share.json文件中的seq2seq_len记录了句子长度的信息,提取seq2seq_len,建立Series。Series中index为句子长度,data为该长度句子的个数。
>>> with open('share.json','r') as f:
data = json.load(f)
data_seq2seq_len = data['seq2seq_len']
data_seq2seq_len = pd.Series(data_seq2seq_len)
>>> data_seq2seq_len
100 4321
1002 1
101 4210
102 4196
...
999 1
Length: 882, dtype: int64
检查一下各个数据的格式。
>>> type(data_seq2seq_len.index[0])
numpy.int64
>>> type(data_seq2seq_len.index)
pandas.core.indexes.numeric.Int64Index
画一个图看看句子长度的大致分布,横坐标为句子长度,纵坐标为该长度句子的个数。
>>> import matplotlib.pyplot as plt
import matplotlib.pyplot
%matplotlib notebook
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
data_seq2seq_len.plot()
可以发现,大部分句子集中在中低长度,基本符合常规预期分布情况。
按句子长度大致平均分成三组,计算一下各组的个数、最大值、平均值和最小值。(注意这里是按句子长度分的,分组跟个数无关)
>>> grouping=pd.qcut(data_seq2seq_len,3)
grouped=data_seq2seq_len.groupby(grouping)
def get_stats(group):
return {'min':group.min(),'max':group.max(),'count':group.count(),'mean':group.mean()}
grouped.apply(get_stats).unstack()
count | max | mean | min | |
---|---|---|---|---|
(0.999, 12.0] | 299.0 | 12.0 | 3.872910 | 1.0 |
(12.0, 301.333] | 289.0 | 299.0 | 92.730104 | 13.0 |
(301.333, 6981.0] | 294.0 | 6981.0 | 2403.653061 | 306.0 |
可以发现,句子长度的跨度非常大,分Bucket真的很有必要。
计算一下句子总数。
>>> data_seq2seq_len.sum()
734631
计划分四个Bucket,那么需要找三个分割点。
734631平分成4,分别为183657.75,367315.5,550973.25,734631。
将整个句子长度-个数Series排序后前向求和,得到一个新Series,每个位置的值为当前位置之前所有值的和。
>>> seq2seq_len_sum=data_seq2seq_len.cumsum()
根据刚才确定的四个分界点,即可找出Bucket的长度分界点。
>>> seq2seq_len_sum[seq2seq_len_sum<550973.25]
12 6
13 20
14 60
...
139 550143
Length: 128, dtype: int64
完成!
正文之后再BB两句
整个过程比较简单,主要就是numpy和pandas的一些函数简单组合应用,记录一下,以后实验做完估计用得就越来越少了。。。