探索モデル オブジェクトを使用して k 最近傍を探索 - MATLAB knnsearch - MathWorks 日本 (2024)

探索モデル オブジェクトを使用して k 最近傍を探索

ページ内をすべて折りたたむ

構文

Idx = knnsearch(Mdl,Y)

Idx = knnsearch(Mdl,Y,Name,Value)

[Idx,D] = knnsearch(___)

説明

Idx = knnsearch(Mdl,Y) は、網羅的探索、Kd 木、または Hierarchical Navigable Small Worlds 近似探索を使用して、クエリ データ Y の各点 (行または観測値) に対する最近傍 (最も近い点、行、または観測値) を Mdl.X から探索します。knnsearchIdx を返します。これは、最近傍を表す Mdl.X 内のインデックスから構成される列ベクトルです。

Idx = knnsearch(Mdl,Y,Name,Value) は、1 つ以上の Name,Value ペア引数で指定された追加オプションを使用して、Y に対して最も近い Mdl.X 内の点のインデックスを返します。たとえば、探索する最近傍の数や、Mdl.Distance に格納されているものとは異なる距離計量を指定します。また、最も近い距離が同順位の場合に行う処理を指定することもできます。

[Idx,D] = knnsearch(___) は、前の構文の入力引数のいずれかを使用して、さらに行列 D を返します。D には、Mdl.X 内の最も近い観測値に対応する Y 内の各観測値間の距離が格納されます。既定では、D の列は、距離計量による近さの昇順で並べ替えられます。

すべて折りたたむ

Kd 木と網羅的探索による最近傍の探索

ライブ スクリプトを開く

knnsearch は、ExhaustiveSearcher または KDTreeSearcher モデル オブジェクトを受け入れて、クエリ データに対する最近傍を学習データから探索します。ExhaustiveSearcher モデルは、網羅的探索アルゴリズムを呼び出します。KDTreeSearcher モデルは、knnsearch で最近傍の探索に使用される Kd 木を定義します。

フィッシャーのアヤメのデータ セットを読み込みます。クエリ データ用に 5 つの観測値をデータから無作為に抽出します。

load fisheririsrng(1); % For reproducibilityn = size(meas,1);idx = randsample(n,5);X = meas(~ismember(1:n,idx),:); % Training dataY = meas(idx,:); % Query data

変数 meas には 4 つの予測子が含まれています。

既定の 4 次元 Kd 木を成長させます。

MdlKDT = KDTreeSearcher(X)
MdlKDT = KDTreeSearcher with properties: BucketSize: 50 Distance: 'euclidean' DistParameter: [] X: [145x4 double]

MdlKDTKDTreeSearcher モデル オブジェクトです。書き込み可能なプロパティは、ドット表記を使用して変更できます。

網羅的最近傍探索モデルを準備します。

MdlES = ExhaustiveSearcher(X)
MdlES = ExhaustiveSearcher with properties: Distance: 'euclidean' DistParameter: [] X: [145x4 double]

MdlKDTExhaustiveSearcher モデル オブジェクトです。このオブジェクトには、最近傍の探索に使用する距離計量などのオプションが格納されています。

Kd 木の成長と網羅的最近傍探索モデルの準備には、createns も使用できます。

各クエリ観測値に対応する最近傍のインデックスを学習データから探索します。既定の設定を使用して、両方のタイプの探索を実行します。既定の設定では、各クエリ観測値について探索する近傍の数は 1 です。

IdxKDT = knnsearch(MdlKDT,Y);IdxES = knnsearch(MdlES,Y);[IdxKDT IdxES]
ans = 5×2 17 17 6 6 1 1 89 89 124 124

この場合、探索の結果は同じです。

ミンコフスキー距離によるクエリ データの最近傍の探索

ライブ スクリプトを開く

関数 createns を使用して、Kd 木最近傍探索モデル オブジェクトを成長させます。k 最近傍を探索するため、オブジェクトとクエリ データを関数 knnsearch に渡します。

フィッシャーのアヤメのデータ セットを読み込みます。

load fisheriris

クエリ セットとして使用するため、5 つのアヤメのデータを無作為に予測子データから抽出します。

rng(1) % For reproducibilityn = size(meas,1); % Sample sizeqIdx = randsample(n,5); % Indices of query datatIdx = ~ismember(1:n,qIdx); % Indices of training dataQ = meas(qIdx,:);X = meas(tIdx,:);

学習データを使用して 4 次元の Kd 木を成長させます。最近傍の探索にミンコフスキー距離を指定します。

Mdl = createns(X,'Distance','minkowski')
Mdl = KDTreeSearcher with properties: BucketSize: 50 Distance: 'minkowski' DistParameter: 2 X: [145x4 double]

X には 4 つの列があり、距離計量がミンコフスキーであるため、既定では creatensKDTreeSearcher モデル オブジェクトを作成します。既定では、ミンコフスキー距離の指数は 2 です。

求める学習データ (Mdl.X) のインデックスは、クエリ データ (Q) の各点における 2 つの最近傍です。

IdxNN = knnsearch(Mdl,Q,'K',2)
IdxNN = 5×2 17 4 6 2 1 12 89 66 124 100

IdxNN の各行はクエリ データの観測値に、列の順序は距離の昇順で並べ替えた最近傍の順序に対応しています。たとえば、ミンコフスキー距離に基づくと、Q(3,:) の 2 番目の最近傍は X(12,:) になります。

最近傍探索に同順位を含める

ライブ スクリプトを開く

フィッシャーのアヤメのデータ セットを読み込みます。

クエリ セットとして使用するため、5 つのアヤメのデータを無作為に予測子データから抽出します。

rng(4); % For reproducibilityn = size(meas,1); % Sample sizeqIdx = randsample(n,5); % Indices of query dataX = meas(~ismember(1:n,qIdx),:);Y = meas(qIdx,:);

学習データを使用して 4 次元の Kd 木を成長させます。最近傍の探索にミンコフスキー距離を指定します。

Mdl = KDTreeSearcher(X);

MdlKDTreeSearcher モデル オブジェクトです。既定の設定では、最近傍を探索するための距離計量はユークリッド尺度です。

求める学習データ (X) のインデックスは、クエリ データ (Y) の各点における 7 つの最近傍です。

[Idx,D] = knnsearch(Mdl,Y,'K',7,'IncludeTies',true);

IdxD は、5 つのベクトルが含まれている cell 配列です。各ベクトルには少なくとも 7 つの要素が含まれています。

Idx に含まれているベクトルの長さを表示します。

cellfun('length',Idx)
ans = 5×1 8 7 7 7 7

セル 1 には長さが k = 7 より大きいベクトルが含まれているので、クエリ観測値 1 (Y(1,:)) は X 内の観測値の少なくとも 2 つと同じ距離にあります。

Y(1,:) に対する最近傍のインデックスとその距離を表示します。

nn5 = Idx{1}
nn5 = 1×8 91 98 67 69 71 93 88 95
nn5d = D{1}
nn5d = 1×8 0.1414 0.2646 0.2828 0.3000 0.3464 0.3742 0.3873 0.3873

学習観測値 88 および 95 は、クエリ観測値 1 から 0.3873 cm 離れています。

異なる距離計量を使用した k 最近傍の比較

ライブ スクリプトを開く

異なる距離計量を使用して 2 つの KDTreeSearcher モデルに学習をさせ、この 2 つのモデルでクエリ データの k 最近傍を比較します。

フィッシャーのアヤメのデータ セットを読み込みます。花弁の測定値を予測子と考えます。

load fisheririsX = meas(:,3:4); % PredictorsY = species; % Response

予測子を使用して KDTreeSearcher モデル オブジェクトに学習をさせます。指数が 5 のミンコフスキー距離を指定します。

KDTreeMdl = KDTreeSearcher(X,'Distance','minkowski','P',5)
KDTreeMdl = KDTreeSearcher with properties: BucketSize: 50 Distance: 'minkowski' DistParameter: 5 X: [150x2 double]

最初にミンコフスキー距離計量を、次にチェビシェフ距離計量を使用して、クエリ点 (newpoint) に対する 10 個の最近傍を X から探索します。クエリ点は、モデルの学習に使用したデータと列次元が同じでなければなりません。

newpoint = [5 1.45];[IdxMk,DMk] = knnsearch(KDTreeMdl,newpoint,'k',10);[IdxCb,DCb] = knnsearch(KDTreeMdl,newpoint,'k',10,'Distance','chebychev');

IdxMkIdxCb はそれぞれ、ミンコフスキー距離計量とチェビシェフ距離計量を使用した newpoint に対する最近傍に対応する X の行インデックスが格納されている 1 行 10 列の行列です。要素 (1,1) は最も近い要素、要素 (1,2) は次に近い要素です。以後についても同様です。

学習データ、クエリ点および最近傍をプロットします。

figure;gscatter(X(:,1),X(:,2),Y);title('Fisher''s Iris Data -- Nearest Neighbors');xlabel('Petal length (cm)');ylabel('Petal width (cm)');hold onplot(newpoint(1),newpoint(2),'kx','MarkerSize',10,'LineWidth',2); % Query point plot(X(IdxMk,1),X(IdxMk,2),'o','Color',[.5 .5 .5],'MarkerSize',10); % Minkowski nearest neighborsplot(X(IdxCb,1),X(IdxCb,2),'p','Color',[.5 .5 .5],'MarkerSize',10); % Chebychev nearest neighborslegend('setosa','versicolor','virginica','query point',... 'minkowski','chebychev','Location','Best');

探索モデル オブジェクトを使用して k 最近傍を探索 - MATLAB knnsearch- MathWorks 日本 (1)

目的の点を拡大します。

h = gca; % Get current axis handle.h.XLim = [4.5 5.5];h.YLim = [1 2];axis square;

探索モデル オブジェクトを使用して k 最近傍を探索 - MATLAB knnsearch- MathWorks 日本 (2)

いくつかの観測値は等しいので、プロットで識別できる最近傍は 8 つだけです。

大規模データに対する HNSW の速度と精度

ライブ スクリプトを開く

大規模なデータ セットを作成し、1000 個のクエリ点についての HNSW 探索モデルの速度と網羅的探索モデルの速度を比較します。

データを作成します。

rng default % For reproducibilityA = diag(1:100);B = randn(100,10);K = kron(A,B);ss = size(K)
ss = 1×2 10000 1000

データ K の行数は 1e4、列数は 1e3 になります。

データ K から HNSW 探索モデル オブジェクト h を作成します。

tic;h = hnswSearcher(K);chnsw = toc
chnsw = 10.6544

1000 個のランダムなクエリ点を作成します。特徴量 (列) は 1000 個です。5 つの最近傍を探索するように指定します。

Y = randn(1000, 1000);tic;[idx, D] = knnsearch(h,Y,K=5);thnsw = toc
thnsw = 0.0797

データ K から網羅的探索モデル オブジェクト e を作成します。

tice = ExhaustiveSearcher(K);ces = toc
ces = 0.0021

網羅的探索モデルの作成は HNSW 探索モデルの作成よりもはるかに高速になります。

e を使用した探索時間を測定し、その結果を HNSW 探索モデル h を使用した時間と比較します。

tic;[idx0, D0] = knnsearch(e,Y,K=5);tes = toc
tes = 1.4841

このケースでは、HNSW 探索モデルの方が網羅的探索モデルよりも計算が約 20 倍高速になります。

HNSW 探索の結果に、網羅的探索の結果と何らかの点で異なる結果がいくつあるかを調べます。

v = abs(idx - idx0); % Count any difference in the five found entriesvv = sum(v,2); % vv = 0 means no differencenz = nnz(vv) % Out of 1000 rows how many differ at all?
nz = 118

ここでは、HNSW 探索の 1000 個の結果のうち 118 個が網羅的探索の結果と異なっています。

既定以外のパラメーターで学習させることで HNSW 探索モデルの精度を改善できるか試します。具体的には、MaxNumLinksPerNodeTrainSetSize の値を大きくします。これらの設定は、学習と最近傍探索の速度に影響します。

tic;h2 = hnswSearcher(K,MaxNumLinksPerNode=48,TrainSetSize=2000);chnsw2 = toc
chnsw2 = 78.4836

これらのパラメーターを使用すると、探索モデルの学習に約 7 倍の時間がかかります。

tic;[idx2, D2] = knnsearch(h2,Y,K=5);thnsw2 = toc
thnsw2 = 0.1049

HNSW を使用した最近傍探索の速度は前より低下しますが、それでも網羅的探索より 10 倍以上高速です。

v = abs(idx2 - idx0);vv = sum(v,2);nz = nnz(vv)
nz = 57

低速になるものの精度が高まる HNSW 探索で、厳密な結果と何らかの点で異なる結果は 1000 個のうち 57 個だけです。時間測定の結果を table にまとめます。

timet = table([chnsw;ces;chnsw2],[thnsw;tes;thnsw2],'RowNames',["HNSW";"Exhaustive";"HNSW2"],'VariableNames',["Creation" "Search"])
timet=3×2 table Creation Search _________ ________ HNSW 10.654 0.079741 Exhaustive 0.0021304 1.4841 HNSW2 78.484 0.10492

入力引数

すべて折りたたむ

名前と値の引数

オプションの引数のペアを Name1=Value1,...,NameN=ValueN として指定します。ここで Name は引数名、Value は対応する値です。名前と値の引数は他の引数の後ろにする必要がありますが、ペアの順序は関係ありません。

R2021a より前では、名前と値をそれぞれコンマを使って区切り、Name を引用符で囲みます。

例: 'K',2,'Distance','minkowski' は、Y の各点に対する 2 つの最近傍を Mdl.X から探索することと、ミンコフスキー距離計量を使用することを指定します。

網羅的最近傍探索モデルと Kd 木最近傍探索モデル

すべて折りたたむ

IncludeTiesすべての最近傍を含むというフラグ
false (0) (既定値) | true (1)

クエリ観測値から同じ距離にある複数の最近傍を含めるかどうかのフラグ。'IncludeTies'false (0) または true (1) をコンマ区切りのペアとして指定します。

IncludeTiestrue の場合、次のようになります。

  • knnsearch は、k 番目に小さい距離に等しい距離をもつすべての最近傍を出力引数に含めます。k は、名前と値のペアの引数 'K' で指定された探索済み最近傍の個数です。

  • IdxD は m 行 1 列の cell 配列になり、それぞれ少なくとも k 個のインデックスと距離のベクトルがセルごとに格納されます。D の各ベクトルには、距離が昇順で並べ替えられて格納されます。Idx の各行には、D 内の距離に対応する最近傍のインデックスが格納されます。

IncludeTiesfalse の場合、knnsearch はクエリ点から同じ距離にある観測値の中でインデックスが最も小さいものを選択します。

例: 'IncludeTies',true

K最近傍の個数
1 (既定値) | 正の整数

各クエリ観測値について学習データで探索する最近傍の数。'K' と正の整数をコンマ区切りのペアとして指定します。

例: 'K',2

データ型: single | double

Kd 木最近傍探索モデル用

すべて折りたたむ

SortIndices返されたインデックスを距離に従って並べ替えるためのフラグ
true (1) (既定値) | false (0)

返されたインデックスを距離に従って並べ替えるためのフラグ。'SortIndices'true (1) または false (0) から構成されるコンマ区切りのペアとして指定します。

以下の場合は、SortIndicesfalse に設定して速度を向上させることができます。

  • X 内に多数の最近傍がある多数の観測値が Y に含まれている。

  • MdlKDTreeSearcher モデル オブジェクトです。

  • IncludeTiesfalse

この場合、knnsearch が返す最近傍のインデックスに特定の順序はありません。SortIndicestrue である場合、最近傍のインデックスは距離の昇順で並べ替えられます。

既定では、SortIndicestrue です。MdlExhaustiveSearcher モデル オブジェクトであるか、IncludeTiestrue である場合、常にインデックスが並べ替えられます。

例: 'SortIndices',false

データ型: logical

網羅的最近傍探索モデルの場合

すべて折りたたむ

HNSW 探索モデル

すべて折りたたむ

SearchSetSize最近傍候補リストのサイズ
max(10,K) (既定値) | K から N までの正の整数

探索プロセスでの単一のクエリ点に対する最近傍候補リストのサイズ。K から N までの正の整数として指定します。値が大きいほど探索が詳細になり、真の最近傍が見つかる可能性が高まりますが、探索にかかる時間は長くなります。SearchSetSize は、データに含まれる特徴量の数 K (Mdl.X の列数) 以上でなければならず、学習データの行数 N (Mdl.X の行数) 以下でなければなりません。

例: SearchSetSize=15

データ型: double

メモ

'Distance''Cov''P' または 'Scale' を指定した場合、Mdl.DistanceMdl.DistParameter の値は変更されません。

出力引数

すべて折りたたむ

Idx — 最近傍の学習データのインデックス
数値行列 | 数値ベクトルの cell 配列

最近傍の学習データのインデックス。数値行列または数値ベクトルの cell 配列として返されます。

  • IncludeTies (既定は false) を指定しなかった場合、Idx は m 行 k 列の数値行列になります。m は Y の行数、k は名前と値のペアの引数 'K' で指定された探索対象の最近傍の個数です。Idx(j,i) は、Mdl.X(Idx(j,i),:) がクエリ観測値 Y(j,:) に対して最も近い Mdl.X 内の k 個の観測値の 1 つであることを示します。

  • 'IncludeTies',true を指定した場合、Idx は m 行 1 列の cell 配列になり、クエリ観測値 Y(j,:) に最も近い Mdl.X 内の観測値のインデックスが少なくとも k 個含まれているベクトルがセル j (Idx{j}) に格納されます。

SortIndicestrue である場合、knnsearch はインデックスを距離の昇順で並べ替えます。

D — 最近傍の距離
数値行列 | 数値ベクトルの cell 配列

クエリ データに対する最近傍の距離。数値行列または数値ベクトルの cell 配列として返されます。

  • IncludeTies (既定は false) を指定しなかった場合、D は m 行 k 列の数値行列になります。m は Y の行数、k は名前と値のペアの引数 'K' で指定された探索対象の最近傍の個数です。D(j,i) は、距離計量による Mdl.X(Idx(j,i),:) とクエリ観測値 Y(j,:) の間の距離です。

  • 'IncludeTies',true を指定した場合、D は m 行 1 列の cell 配列になり、クエリ観測値 Y(j,:) に最も近い Mdl.X 内の観測値の距離が少なくとも k 個含まれているベクトルがセル j (D{j}) に格納されます。

SortIndicestrue である場合、knnsearch は距離を昇順で並べ替えます。

ヒント

knnsearch は、Y の各点についての k 最近傍である k (正の整数) 個の点を Mdl.X 内で探索します。これに対して rangesearch は、Y の各点に対する距離が r (正のスカラー) 以内であるすべての点を Mdl.X 内で探索します。

アルゴリズム

すべて折りたたむ

高速ユークリッド距離アルゴリズム

Distance 引数の fast から始まる値 ('fasteuclidean''fastseuclidean' など) で使用されるアルゴリズムでは、計算時間の短縮のために追加のメモリを使用してユークリッド距離が計算されます。このアルゴリズムは、Albanie の[1]などで "ユークリッド距離行列トリック" として提唱されているものです。内部テストでは、このアルゴリズムによって予測子の数が 10 個以上の場合に時間の短縮になることが確認されています。'fast' から始まるアルゴリズムでは、スパース データはサポートされません。

このアルゴリズムでは、xi と xj のすべての点間の距離の行列 D を求めるために (xi のそれぞれに n 個の変数を格納)、次の方程式の最後の行を使用して距離を計算します。

Di,j2=xixj2=(xixj)T(xixj)=xi22xiTxj+xj2.

方程式の最後の行にある行列 xiTxj"グラム行列" と呼ばれます。正方化と加算によって平方距離を計算する代わりに、グラム行列を計算して使用すると、一連の平方距離の計算は高速になりますが、数値的安定性は少し低くなります。詳細については、Albanie の[1]を参照してください。

参照

[1] Albanie, Samuel. Euclidean Distance Matrix Trick. June, 2019. Available at https://www.robots.ox.ac.uk/%7Ealbanie/notes/Euclidean_distance_trick.pdf.

代替機能

  • knnsearch は、ExhaustiveSearcherKDTreeSearcher、または hnswSearcher モデル オブジェクトとクエリ データを必要とするオブジェクト関数です。同じ条件下の網羅的探索または Kd 木探索で、オブジェクト関数 knnsearch は、名前と値の引数 NSMethod="exhaustive" または NSMethod="kdtree" をそれぞれ指定した関数 knnsearch と同じ結果を返します。関数 knnsearch には hnswSearcher モデルを指定するための同様の名前と値の引数はないことに注意してください。

  • k 最近傍分類については、fitcknnClassificationKNN を参照してください。

参照

[1] Friedman, J. H., Bentley, J., and Finkel, R. A. (1977). “An Algorithm for Finding Best Matches in Logarithmic Expected Time.” ACM Transactions on Mathematical Software Vol. 3, Issue 3, Sept. 1977, pp. 209–226.

[2] Malkov, Yu. A., and D. A. Yashunin. Efficient and Robust Approximate Nearest Neighbor Search Using Hierarchical Navigable Small World Graphs. Available at https://arxiv.org/abs/1603.09320.

拡張機能

バージョン履歴

R2010a で導入

すべて展開する

hnswSearcher モデル オブジェクトを使用して近似最近傍を探索します。hnswSearcher オブジェクトは、ExhaustiveSearcher オブジェクトや KDTreeSearcher オブジェクトよりも作成に時間がかかりますが、近似最近傍の計算は高速になります。hnswSearcher オブジェクトを作成するには、関数 hnswSearcher を使用するか、NSMethod="hnsw" を指定して createns を使用します。詳細については、hnswSearcher を参照してください。

'fasteuclidean' および 'fastseuclidean' の距離計量では、キャッシュと別のアルゴリズムを使用してユークリッド距離の計算が高速化されます (アルゴリズムを参照)。

参考

createns | ExhaustiveSearcher | KDTreeSearcher | hnswSearcher | rangesearch | knnsearch | fitcknn | ClassificationKNN

トピック

  • k 最近傍探索および半径探索
  • 距離計量

MATLAB コマンド

次の MATLAB コマンドに対応するリンクがクリックされました。

 

コマンドを MATLAB コマンド ウィンドウに入力して実行してください。Web ブラウザーは MATLAB コマンドをサポートしていません。

探索モデル オブジェクトを使用して k 最近傍を探索 - MATLAB knnsearch- MathWorks 日本 (3)

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list:

Americas

  • América Latina (Español)
  • Canada (English)
  • United States (English)

Europe

  • Belgium (English)
  • Denmark (English)
  • Deutschland (Deutsch)
  • España (Español)
  • Finland (English)
  • France (Français)
  • Ireland (English)
  • Italia (Italiano)
  • Luxembourg (English)
  • Netherlands (English)
  • Norway (English)
  • Österreich (Deutsch)
  • Portugal (English)
  • Sweden (English)
  • Switzerland
    • Deutsch
    • English
    • Français
  • United Kingdom (English)

Asia Pacific

Contact your local office

探索モデル オブジェクトを使用して k 最近傍を探索 - MATLAB knnsearch
- MathWorks 日本 (2024)

References

Top Articles
Latest Posts
Article information

Author: Ray Christiansen

Last Updated:

Views: 5657

Rating: 4.9 / 5 (49 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Ray Christiansen

Birthday: 1998-05-04

Address: Apt. 814 34339 Sauer Islands, Hirtheville, GA 02446-8771

Phone: +337636892828

Job: Lead Hospitality Designer

Hobby: Urban exploration, Tai chi, Lockpicking, Fashion, Gunsmithing, Pottery, Geocaching

Introduction: My name is Ray Christiansen, I am a fair, good, cute, gentle, vast, glamorous, excited person who loves writing and wants to share my knowledge and understanding with you.