扩充 WMT17 训练集的最快方法
Fastest way to augment a WMT17 training set
我有一个包含 3,961,179 行的 WMT17 训练数据集。
我想从这些行中增加 198,058 行随机行,例如通过在包含单词“移动”的每行末尾插入 \tbewegen
(\t
是制表符)。
move可以出现在句子的任意位置,是
这样的句子的子串
1. There was more behind this move than simply wishing to expand their product portfolio .
2. move and collect miles
3. January 16 - Pro@@ hi@@ bition begins in USA . Many li@@ qu@@ or @-@ lo@@ ving Americans move to France .
.
.
.
如果子字符串“move”出现在一行中,那么句子应该是这样的
1. There was more behind this move than simply wishing to expand their product portfolio .\tbewegen
2. move and collect miles\tbewegen
3. January 16 - Pro@@ hi@@ bition begins in USA . Many li@@ qu@@ or @-@ lo@@ ving Americans move to France .\tbewegen
.
.
.
为此我已经制作了一个脚本,但我发现增加 10 行大约需要 2 分钟,而增加 198,058 行需要 39,611 分钟。
这是我的 bash 脚本:
sed -n '=' train.de | shuf | head -198058 > lines
cat lines | while IFS= read -r line ;
do
sed -i.bak "${line}s/move/$/\tbewegen/" train.de;
done
有什么办法可以缩短流程,不用等几天?
更新:假设我想从 https://www.golinuxhub.com/2017/06/sed-insert-word-after-match-in-middle/ 应用插入 before/after 操作。如何重写解决方案中的awk代码?
编辑:
您可以使用以下命令在匹配词之前或之后随机插入一个词:
awk -i inplace '(NR==FNR){a[];next}
(FNR in a) && gsub(/\<the\>/,"Before &")
1
' <(shuf -n 198058 -i 1-$(wc -l < n_train)) n_train
awk -i inplace '(NR==FNR){a[];next}
(FNR in a) && gsub(/\<the\>/,"& After")
1
' <(shuf -n 198058 -i 1-$(wc -l < n_train)) n_train
下面的命令应该能帮到你。它读取一系列随机数,然后处理文件。这不会进行就地修改,而是将输出打印到屏幕上。重定向将保存文件。
awk '(NR==FNR){a[];next}
(FNR in a) && /\<move\>/ {[=10=]=[=10=] "\tbewegen"}
1
' <(shuf -n 198058 -i 1-$(wc -l < train.de)) train.de
这包含几个命令:
1.随机选择行号:
shuf -n 198058 -i 1-$(wc -l < train.de)
此行生成 1-N 范围内的 198058 个数字的随机选择,其中 N 是由 awk 'END{print NR}' train.de
给出的文件 train.de
中的总行数。此行替换代码中的初始行:
sed -n '=' train.de | shuf | head -198058 > lines
2。使用 awk 完成剩下的工作:
awk '(NR==FNR){a[];next}(FNR in a) && /\<move\>/{[=13=]=[=13=] "\tbewegen"}1' file1 file2
我们在这里使用 awk 读取 file1 的输入(shuf
的输出)并将其全部存储在数组 a
中,用作查找 table。当读取第一个文件时,我们检查第二个文件的记录号(行号)FNR
,并检查我们是否在查找中table a
。如果这是真的,我们检查该行是否包含单词“move”。如果满足这两个条件,请通过向其添加 \tbewegen
来更新该行。
您现在可以将此输出存储在新文件中。
这将比以前的版本快得多,因为它只读取文件两次,在您的示例中您读取了 198059 次。
这可能对你有用 (GNU sed):
grep -n move file | shuf | head -198058 | sed 's/:.*/s#$#\tbewegen#/' | sed -f - file
使用 grep 查找(带行号)所有包含 move
.
的行
使用 shuf 随机排列这些行。
取前198058行号
使用 sed 从行号构建 sed 脚本,行号附加 \tbewegen
到文件中标识的每一行。
使用 -f
选项将 sed 脚本传递到另一个 sed 调用中,并针对原始文件进行播放。
如果 198508 行可能包含也可能不包含单词 move
,请使用:
seq $(wc -l <file) | shuf | head -198058 | sed 's/$/s#$#\tbewegen#/' sed -f - file
我有一个包含 3,961,179 行的 WMT17 训练数据集。
我想从这些行中增加 198,058 行随机行,例如通过在包含单词“移动”的每行末尾插入 \tbewegen
(\t
是制表符)。
move可以出现在句子的任意位置,是
这样的句子的子串1. There was more behind this move than simply wishing to expand their product portfolio .
2. move and collect miles
3. January 16 - Pro@@ hi@@ bition begins in USA . Many li@@ qu@@ or @-@ lo@@ ving Americans move to France .
.
.
.
如果子字符串“move”出现在一行中,那么句子应该是这样的
1. There was more behind this move than simply wishing to expand their product portfolio .\tbewegen
2. move and collect miles\tbewegen
3. January 16 - Pro@@ hi@@ bition begins in USA . Many li@@ qu@@ or @-@ lo@@ ving Americans move to France .\tbewegen
.
.
.
为此我已经制作了一个脚本,但我发现增加 10 行大约需要 2 分钟,而增加 198,058 行需要 39,611 分钟。
这是我的 bash 脚本:
sed -n '=' train.de | shuf | head -198058 > lines
cat lines | while IFS= read -r line ;
do
sed -i.bak "${line}s/move/$/\tbewegen/" train.de;
done
有什么办法可以缩短流程,不用等几天?
更新:假设我想从 https://www.golinuxhub.com/2017/06/sed-insert-word-after-match-in-middle/ 应用插入 before/after 操作。如何重写解决方案中的awk代码?
编辑:
您可以使用以下命令在匹配词之前或之后随机插入一个词:
awk -i inplace '(NR==FNR){a[];next}
(FNR in a) && gsub(/\<the\>/,"Before &")
1
' <(shuf -n 198058 -i 1-$(wc -l < n_train)) n_train
awk -i inplace '(NR==FNR){a[];next}
(FNR in a) && gsub(/\<the\>/,"& After")
1
' <(shuf -n 198058 -i 1-$(wc -l < n_train)) n_train
下面的命令应该能帮到你。它读取一系列随机数,然后处理文件。这不会进行就地修改,而是将输出打印到屏幕上。重定向将保存文件。
awk '(NR==FNR){a[];next}
(FNR in a) && /\<move\>/ {[=10=]=[=10=] "\tbewegen"}
1
' <(shuf -n 198058 -i 1-$(wc -l < train.de)) train.de
这包含几个命令:
1.随机选择行号:
shuf -n 198058 -i 1-$(wc -l < train.de)
此行生成 1-N 范围内的 198058 个数字的随机选择,其中 N 是由 awk 'END{print NR}' train.de
给出的文件 train.de
中的总行数。此行替换代码中的初始行:
sed -n '=' train.de | shuf | head -198058 > lines
2。使用 awk 完成剩下的工作:
awk '(NR==FNR){a[];next}(FNR in a) && /\<move\>/{[=13=]=[=13=] "\tbewegen"}1' file1 file2
我们在这里使用 awk 读取 file1 的输入(shuf
的输出)并将其全部存储在数组 a
中,用作查找 table。当读取第一个文件时,我们检查第二个文件的记录号(行号)FNR
,并检查我们是否在查找中table a
。如果这是真的,我们检查该行是否包含单词“move”。如果满足这两个条件,请通过向其添加 \tbewegen
来更新该行。
您现在可以将此输出存储在新文件中。
这将比以前的版本快得多,因为它只读取文件两次,在您的示例中您读取了 198059 次。
这可能对你有用 (GNU sed):
grep -n move file | shuf | head -198058 | sed 's/:.*/s#$#\tbewegen#/' | sed -f - file
使用 grep 查找(带行号)所有包含 move
.
使用 shuf 随机排列这些行。
取前198058行号
使用 sed 从行号构建 sed 脚本,行号附加 \tbewegen
到文件中标识的每一行。
使用 -f
选项将 sed 脚本传递到另一个 sed 调用中,并针对原始文件进行播放。
如果 198508 行可能包含也可能不包含单词 move
,请使用:
seq $(wc -l <file) | shuf | head -198058 | sed 's/$/s#$#\tbewegen#/' sed -f - file