簡體   English   中英

從兩個文本文件(平行語料庫)中隨機采樣N行

[英]Randomly sample N lines from two text files(parallel corpus) consistently

一次又一次,我面對取樣線特定數量的問題(假設N )兩個文件(即從平行語料庫 ;句子按照行號排列) 一致

對於從事(神經)機器翻譯研究的人員來說,這是一項常見且頻繁的任務。

我想知道一種快速有效的方法來從並行語料庫(可能是從命令行)中采樣(即選擇) N行。

例如,如果我們想選擇4兩個文件行以一致的方式,我們可以在采樣行號線3121723 這應該使我們從兩個文件中獲得這些行。 同樣,最好將此參數N為任意值,以便我們可以根據需要更改它。 此外,這些行應不重復采樣。 並且,需要采樣的行數N總是小於兩個文件中的總行數,其中兩個文件的總行數總是相等。

一旦我們對所需的行進行了采樣,還需要從兩個文件中都未采樣的行中獲取(即獲取未在隨機采樣中選擇的其余行)。

這樣做的整體思路是以一致的方式對兩個文件進行采樣,以保留其線對齊。 (即,選擇N行和NT行,其中T是總行數。)

其中N是要重復采樣的期望行數, NT是其余未采樣的行。

我將如何去做呢? 提前致謝!

如果不允許重復,則最好使用隨機播放算法。 為此已經有一個工具shuf

例如,

$ shuf -n 10 file

將從文件中隨機選擇10行給您(按隨機順序)。 您的請求有兩個附加約束,首先應該對選擇進行排序,其次,對於下一次運行,選擇必須保持一致。 對於第二個要求,您可以向shuf提供隨機性源以兩次獲得相同的序列。 為了排序,我們依靠自己的力量...

$ shuf -n 10 --random-source=file <(cat -n file1) | sort -n | cut -f2- > sample1
$ shuf -n 10 --random-source=file <(cat -n file2) | sort -n | cut -f2- > sample2

將以正確的順序為您提供相同的采樣行。 出於隨機性考慮,您可以使用一個文件或任何其他第三個文件(但兩次運行都應相同)。

另一種選擇是將兩個文件粘貼在一起,然后隨機播放一次,然后拆分樣本。

$ paste -d'|' file1 file2 | cat -n | shuf -n 10 | sort -n | cut -f2 > sample

$ cut -d'|' -f1 sample > sample1
$ cut -d'|' -f2 sample > sample2

要獲取未選擇的行,您需要保留行號。 使用第二種選擇

$ paste -d'|' file1 file2 | cat -n | shuf -n 10 | sort -n > n_samples
$ cut -f2- n_samples > samples
$ awk 'NR==FNR{a[$1];next} !(FNR in a)' <(cut -f1 n_samples) samples > notselected

您可以像以前一樣拆分樣本和未選擇的文件。

使用第一種替代方法,將從文件中未選擇的行寫入具有相同名稱和擴展名“ .not”的文件

$ cat -n file1 | shuf -n 10 --random-source=file | sort -n > n_sample1
$ cut -f2- n_sample1 > sample1
$ cat -n file2 | shuf -n 10 --random-source=file | sort -n | cut -f2- > sample2
$ awk 'NR==FNR    {a[$1];next} 
      !(FNR in a) {print > FILENAME".not"}' <(cut -f1 n_sample1) sample1 sample2 
#!/bin/bash
samples=$1
file1="$2"
file2="$3"

maxlines=$(cat "$file1" | wc -l)
nums=($(shuf -e $(echo $(seq 1 $maxlines))))
lines=$(for i in $(seq 1 $samples); do echo ${nums[$i]}p" "; done | sort -n)
sed -n "$lines" "$file1"
sed -n "$lines" "$file2"

#rows1=($(sed -n "$lines" "$file1"))
#rows2=($(sed -n "$lines" "$file2"))
  • 參數$ 1,2,3:樣本數,文件名1和2。
  • 帶有wc -l和cat的maxline,因為這樣我們就不需要去除文件名。 (這里沒有貓獎的無用使用)。
  • seq xy生成一個從x到y的序列,這里是1到maxlines。 沒有一一對應的錯誤,因為源wc和sed一樣從1開始計數(以后)。
  • shuf -e隨機播放數字,而-e不期望它們按行排列
  • 要獲取樣本數量,請從前面拉線號,
    • 但對它們進行排序,以便sed只需要遍歷文件一次。
    • 后綴“ p”用於sed。
  • sed -n,對於一個11行的小文件,sample = 4,看起來像這樣:

    sed -n 3p 4p 5p 7p mul.sh

如果您不希望按文件輸出而是按行輸出,則將它們收集在數組中:

rows1=($(sed -n "$lines" "$file1"))
rows2=($(sed -n "$lines" "$file2"))

這樣,sed仍然只需要遍歷可能較大的文件一次。 使用從0到$ sample-1的數組索引,您可以遍歷兩個行數組並進行比較-或執行任何工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM