2017-01-16 6 views
2

私はライブラリをデバッグする過程にあり、k-最近傍を計算することを含んでいます。私は理解するのが難しい例を用いて質問を構想しています。RとJava + WEKA間の最近隣の計算での不一致

最初に、おもちゃの例を使って説明し、次に質問につながる出力を示します。

タスク

デモは、ここでは2次元データ点の10数を有するCSVファイルを読み込みます。この作業は、最初のデータポイントからすべてのデータポイントの距離を見つけ、すべてのポイントと最初のデータポイントからの距離を降順に並べることです。

基本的に、これはkNNベースのアルゴリズムのコンポーネントであり、Javaバージョン(ライブラリのコンポーネント)を実行したときとRに書き込むときに矛盾があります。矛盾を実証するには、 。

コード1:Javaの+ WEKA

次のコードは、JavaとWEKAを使用しています。私はLinearNNSearchを使って最近隣を計算しました。これは、LinearNNSearchが特定のライブラリで使用されており、デバッグしている、またはRコードと比較しているためです。

import weka.core.converters.CSVLoader; 
import weka.core.Instances; 
import weka.core.DistanceFunction; 
import weka.core.EuclideanDistance; 
import weka.core.Instances; 
import weka.core.neighboursearch.LinearNNSearch; 
import java.io.File; 

class testnn 
{ 
    public static void main (String args[]) throws Exception 
    { 
    // Load csv 
    CSVLoader loader = new CSVLoader(); 
    loader.setSource (new File (args[0])); 

    Instances df = loader.getDataSet(); 

    // Set the LinearNNSearch object 
    EuclideanDistance dist_obj = new EuclideanDistance(); 

    LinearNNSearch lnn = new LinearNNSearch(); 
    lnn.setDistanceFunction(dist_obj); 
    lnn.setInstances(df); 
    lnn.setMeasurePerformance(false); 

    // Compute the K-nearest neighbours of the first datapoint (index 0). 
    Instances knn_pts = lnn.kNearestNeighbours (df.instance (0), df.numInstances()); 

    // Get the distances. 
    double [] dist_arr = lnn.getDistances(); 

    // Print 
    System.out.println ("Points sorted in increasing order from "); 
    System.out.println (df.instance (0)); 
    System.out.println ("V1,\t" + "V2,\t" + "dist"); 
    for (int j = 0; j < knn_pts.numInstances(); j++) 
    { 
     System.out.println (knn_pts.instance (j) + "," + dist_arr[j]); 
    } 
    } 
} 

コード2:R

私はdistを使用していた距離を計算します。 daisyを使用しても同じ回答が得られます。簡単に比較のために

// Read file 
df <- read.csv ("dat.csv", header = TRUE); 

// All to all distances, and select distances of points from first datapoint (index 1) 
dist_mat <- as.matrix (dist (df, diag=TRUE, upper=TRUE, method="euclidean")); 
first_pt_to_all <- dist_mat[,1]; 

// Sort the datapoints and also record the ordering 
sorted_order <- sort (first_pt_to_all, index.return = TRUE, decreasing = FALSE); 

// Prepare dataset with the datapoints ordered in the non-decreasing order of the distance from the first datapoint 
df_sorted <- cbind (df[sorted_order$ix[-1],], dist = sorted_order$x[-1]); 

// Print 
print ("Points sorted in increasing order from "); 
print (df[1,]); 

print (df_sorted); 

出力

は私が側で2つの出力側を配置しています。どちらのテーブルも、降順でポイントを表示します。

  • R出力の一番左の列は、元のデータポイントのインデックスを示すと左側テーブルは、Rによって生成されます。
  • 右側の表はJava + WEKAによって生成されます。
 
    R            Java + WEKA 
[1] "Points sorted in increasing order from " Points sorted in increasing order from 
     V1  V2 
1 0.560954 0.313231      0.560954,0.313231 
     V1  V2  dist    V1,  V2,  dist 
5 0.866816 0.476897 0.3468979   0.866816,0.476897,0.3280721928065624 
10 0.262637 0.554558 0.3837079   0.262637,0.554558,0.37871658916675316 
4 1.038752 0.396173 0.4849436   1.038752,0.396173,0.43517244797543775 
2 0.330345 -0.137681 0.5064604   1.053889,0.486349,0.4795184359817083 
7 1.053889 0.486349 0.5224507   1.113799,0.42203,0.506782009966262 
6 1.113799 0.422030 0.5634490   0.330345,-0.137681,0.5448256434359463 
8 0.416051 -0.338858 0.6679947   0.416051,-0.338858,0.7411841020052856 
3 0.870481 -0.302856 0.6894709   0.870481,-0.302856,0.7425541767563134 
9 1.386459 0.425101 0.8330507   1.386459,0.425101,0.7451474897289354 

問題

距離は明らかに異なっており、データポイントの順序の一部も異なっています。

可視化

私は10点をプロットし、プロット中の数字によって示される、それらのソートされた順序に従って、それらの番号を付けました。

  • ブラックテキストは赤色テキストがジャワ+ WEKA
によって生成されたソート済みデータセットからプロットされた点を示しR
  • によって生成されたソート済みデータセットからプロットされた点を示しています

    enter image description here

    したがって、4,5,6が異なります。 2つのデータ点が等距離にある場合、これは異なる順序付けを説明したが、第1のデータ点から等距離にある2つの点は存在しない。

    データセット

     
    "V1", "V2" 
    0.560954,0.313231 
    0.330345,-0.137681 
    0.870481,-0.302856 
    1.038752,0.396173 
    0.866816,0.476897 
    1.113799,0.42203 
    1.053889,0.486349 
    0.416051,-0.338858 
    1.386459,0.425101 
    0.262637,0.554558 
    

    質問

    • distの列の距離が最近傍ポイントの異なる順序付けにつながる、異なっているのはなぜ?
    • コード内で見つかる間違いや、ライブラリの使用方法はありますか?これら(特にWEKA)を正しく使用していますか?

    コメントが不明または詳細については、コメントしてください。

  • +0

    Rの距離が正しいことは容易にわかります。 たとえば、テストポイントとリストの最初のポイントを使用するだけです。 p1 = c(0.560954、0.313231); p2 = c(0.866816,0.476897);sqrt(sum((p1-p2)*(p1-p2))); [1] 0.3468979 – G5W

    +0

    @ G5W Rの距離は正確ですが、間違いありません。問題は解決しませんが、WEKAには何が問題なのですか?それとも間違って使われているのですか? – phoxis

    答えて

    1

    コメントに記されているように、Rの距離は正しいです。問題はWEKAのデフォルトです。

    EuclideanDistance dist_obj = new EuclideanDistance(); 
    

    ユークリッド距離のWEKAには、デフォルトのパラメータがあります。そのうちの1つはDontNormalize=FALSEであり、デフォルトではWEKAは距離を計算する前にデータを正規化する。私はJavaではあまり役に立ちませんので、私はRでこれを行います。各変数に対して最小値がゼロで最大値が1になるようにデータをスケールすると、WEKAによって提供される距離測定値が得られます。

    NData = Data 
    NData[,1] = (NData[,1]-min(NData[,1]))/(max(NData[,1])-min(NData[,1])) 
    NData[,2] = (NData[,2]-min(NData[,2]))/(max(NData[,2])-min(NData[,2])) 
    dist(NData) 
    

    これらの距離は、WEKAの表示と同じです。 Rと同じ結果を得るには、WEKAのEuclideanDistanceのパラメーターを調べてください。

    +0

    'getDontNormalize()'が 'false'を返すことを確認しました。これをもっと見てみましょう。 – phoxis

    +0

    真実なので、私はこれを止める方法を見つける必要があります。リードしてくれてありがとう。 'getDontNormalize()'が 'false'を返すので混乱しました。 – phoxis

    +0

    はい、それは一種の二重否定です。 DontNormalize = FALSEは、Normalize = TRUEと同じです(しかし、パラメータはNormalizeと呼ばれません)。 – G5W

    関連する問題