2016-06-18 8 views
3

これはAWK言語を使用しています。主にステップ2の問題があります。サンプルデータセットを示しましたが、元のデータセットは100フィールドと2000レコードで構成されています。awkを使用する最近隣の1人

アルゴリズム

1)R0のための最近傍を検索するには、各レコードrため

 Find the closest other record, o, in the dataset using distance formula 

を精度= 0

2)を初期化し、IはR9にR1とR0を比較するために必要と次のように計算します。square(abs(r0.c1 - r1.c1))+ square ) とそれらの距離を格納します。

3)最小距離を1つ、そのc6値を比較します。 c6の値が等しい場合は、精度を1ずつ増やします。

すべてのレコードについて処理を繰り返した後。

4)最終的に、1nn精度のパーセンテージを (精度/合計記録)* 100で取得します。

サンプルデータセット

 c1 c2 c3 c4 c5 c6 --> Columns 
    r0 0.19 0.33 0.02 0.90 0.12 0.17 --> row1 & row7 nearest neighbour in c1 
    r1 0.34 0.47 0.29 0.32 0.20 1.00  and same values in c6(0.3) so ++accuracy 
    r2 0.37 0.72 0.34 0.60 0.29 0.15 
    r3 0.43 0.39 0.40 0.39 0.32 0.27 
    r4 0.27 0.41 0.08 0.19 0.10 0.18 
    r5 0.48 0.27 0.68 0.23 0.41 0.25 
    r6 0.52 0.68 0.40 0.75 0.75 0.35 
    r7 0.55 0.59 0.61 0.56 0.74 0.76 
    r8 0.04 0.14 0.03 0.24 0.27 0.37 
    r9 0.39 0.07 0.07 0.08 0.08 0.89 

コード

BEGIN { 
      #initialize accuracy and total_records 
      accuracy = 0; 
      total_records = 10; 
     } 


NR==FNR { # Loop through each record and store it in an array 
       for (i=1; i<=NF; i++) 
       { 
        records[i]=$i; 
       } 
      next    
     } 

     { # Re-Loop through the file and compare each record from the array with each record in a file  
       for(i=1; i <= length(records); i++) 
       { 
        for (j=1; j<=NF; j++) 
        {  # here I need to get the difference of each field of the record[i] with each all the records, square them and sum it up. 
          distance[j] = (records[i] - $j)^2; 
        } 
       #Once I have all the distance, I can simply compare the values of field_6 for the record with least distance. 
       if(min(distance[j])) 
       { 
        if(records[$6] == $6) 
        { 
         ++accuracy; 
        } 
       } 
     } 
END{ 
    percentage = 100 * (accuracy/total_records); 
    print percentage; 
} 
+0

あなたはfields [i] = print $ iを意味します。すべてのフィールドを配列に格納しますか?フィールドは独立していますが、一番近い行が見つかると、フィールド[6]にあるclass_valueを見つける必要があります。私が各フィールドを別々にソートすると、データが混乱してしまいました。あなたのアイデアをどうやって伝えるかについてもう少し説明できますか? –

+0

説明にコメントを組み込んだので、今実際の質問は何ですか?私。あなたはステップ2でどんな難しさを持っていますか? – Soren

+0

2つのレコードの各フィールドに式を適用する方法(二乗と和を含む)はわかりません。このビットは間違っています - >> distance [j] =(records [i] - $ j); –

答えて

0

ここであなただけのn *(n-1)の比較する必要があるため、対称性への一つのアプローチ

$ cat -n file > nfile 
$ join nfile{,} -j99 | 
    awk 'function abs(x) {return x>0?x:-x} 
      $1<$8 {minc=999;for(i=2;i<7;i++) 
       {d=abs($i-$(i+7)); 
        if(d<minc)minc=d} 
        print $1,minc,$7==$14}' | 
    sort -u -k1,2 -k3r | 
    awk '!a[$1]++{sum+=$3} END{print sum}' 

7 

がある/ 2レコード、すべてのマッチを準備して余分なものをフィルタリングするためにjoinで簡単に設定する$1<$8で、レコードごとの最小列距離を見つけ、最後のフィールド$7==$14の一致を記録し、各レコードソートの最小距離を最初のレコード番号と距離で求め、最終的に一致するエントリの合計を取得します。

あなたの処方のために、私はあなたが新しい距離関数でダブルカウント(R1〜R7およびR7〜R1)、そうでない場合は 70%

UPDATE
しているので、結果は100*2*7/10=140%になります推測ここ

、スクリプト

$ join nfile{,} -j999 | 
    awk '$1<$8 {d=0; 
       for(i=2;i<7;i++) d+=($i-$(i+7))^2; 
       print $1,d,$7==$14}' | 
    sort -k1,2n -k3r | 
    awk '!a[$1]++{sum+=$3;count++} 
      END{print 100*sum/(count+1)"%"}' 

70% 

説明として再記述することができ

レコード番号の新しいファイルを作成します。 joinは、両方のファイルをstdinから取り込むことができないため、一時ファイルを作成する必要があります。

join nfile{,} -j999レコードのクロス積(各レコードは、あなたのようにそれを想像する場合(クロス積の上三角部分にレコードを除外するすべてのレコード(2つの入れ子ループの同様の効果)

$1<$8と結合します2Dマトリックス)。

for(i=2;i<7;i++) d+=($i-$(i+7))^2;

は他人に対する各レコードの距離の平方を計算する最後のフィールドは、各レコードの最小を見つける

sort -u -k1,2 -k3rソート第3フィールド、逆方向に一致するかどうかを記録、距離の平方、およびインジケータから

print $1,d,$7==$14印刷何かがあれば1が最初になるようにします。

a[$1]++{sum+=$3;count++} count行とレコードから

END{print 100*sum/(count+1)"%"}をそれぞれの指標を合計フィールドの数は、パーセントの書式に変換し、記録からより1つ多いです。

各パイプセクションを段階的に実行していることを理解し、中間結果を検証することをお勧めします。

実際のデータでは、ハードコーディングされた参照値を変更する必要があります。結合されたフィールドはフィールドカウント以上でなければなりません。

+0

私の悪い、データセットに依存しないでください、私は実際のデータセットとして私自身のデータセットをmadeupかなり大きいです。データセットは対称ではありません。値は0.0〜1.0の間の任意の値になります。min-maxは正規化されます。以前は間違っていたと思うので、コードを更新します。ちょうど私に分を与える、私は更新しています。その応答に感謝します。 –

+0

は、R1にR7までの最小距離がある場合は値にかかわらず、R7がR1まで最小距離を持つことを意味します。したがって、より高いインデックスを持つ他のレコードのみとレコードを比較する必要があります。 – karakfa

+0

あなたのコードとその実行方法について説明できますか?私は結合とabs()関数を理解していません。私はAWKにはかなり新しいです。私はR7への部分R1分距離を得て、その逆も同じです。しかし、私はレコード= 10のために2000レコードを持っていると仮定することができます、私はレコードを1から9まで、そしてレコード11から2000まで比較しなければなりません。しかし、私はもっと高いインデックスだけを探す必要があるという事実に同意しない。 –

関連する問題