扩充 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