10000行ages (float), titles (enum/int), scores (float), ...
のボーリングCSVがあります。
だから私たちが厳密に詰まったクラスターに100ポイントを持っていて、距離の1つのポイントの場合、私たちは3つのポイントのようなものを手に入れるでしょう: またはこれを
4点の場合、それはより面白くなり、真ん中にある点を選ぶでしょう。
それで、nから最も遠い行(ポイント)を選択する方法(複雑さと一緒に)? 3Dポイントではなく、特定の解像度を持つND点群の「三角測量」のように見えます。
K = 200およびn = 100000およびNd = 6(KDTreeベース、SOMまたは三角測量に基づく)のために、かなり速いアプローチを検索します(おそらく、KDTreeベース、SOMまたは三角測量)..誰もが知っていますか?
私はおおよその解を提案する。このアイデアは、以下に説明する方法で選択されたkポイントのセットから始めて、これらの点を繰り返しループして、現在のものをセットに属していないn-k + 1ポイントのうち、現在のものは、セットの点からの距離の合計を最大にします。この手順は、任意の単一点の置き換えがセットの点間の距離の合計を減少させるようなk点のセットをもたらす。
プロセスを開始するには、すべてのポイントの平均に最も近いKポイントを取ります。このようにして、最初のループでは、k点のセットが最適に近づくように拡散されることをお勧めします。その後の反復は、n、k、およびndの現在の値に対して数秒で到達可能であるように見えるように見えるように見えるように見えるように見える。エッジケースで過度のループを防ぐために、それにもかかわらずループの数を制限します。
繰り返しがKポイントの間の合計距離を向上させない場合は繰り返します。もちろん、これは極大値です。他の地元の最大値は、初期の条件で、または一度に複数の交換を可能にすることによって達成されますが、私はそれが価値があるとは思わない。
ユークリッドの距離が意味のあるものであるために、各次元における単位変位のために、すなわち、データを調整する必要があります。例えば、あなたの寸法が給与と子供の数であるならば、未調整されていない、アルゴリズムはおそらく極度の給与地域に集中した結果をもたらすでしょう。より現実的な出力を得るためには、子供の標準偏差によって、または子供の数の違いに匹敵する給与の違いがある他の見積もりによって、給料と数を分けることができます。
ランダムなガウス分布の出力をプロットできるようにするには、コードに_ND = 2
_を設定しましたが、要求に従って_ND = 6
_を設定しますが、問題ありません(プロットできないことを除く)。
_import matplotlib.pyplot as plt
import numpy as np
import scipy.spatial as spatial
N, K, ND = 100000, 200, 2
MAX_LOOPS = 20
SIGMA, SEED = 40, 1234
rng = np.random.default_rng(seed=SEED)
means, variances = [0] * ND, [SIGMA**2] * ND
data = rng.multivariate_normal(means, np.diag(variances), N)
def distances(ndarray_0, ndarray_1):
if (ndarray_0.ndim, ndarray_1.ndim) not in ((1, 2), (2, 1)):
raise ValueError("bad ndarray dimensions combination")
return np.linalg.norm(ndarray_0 - ndarray_1, axis=1)
# start with the K points closest to the mean
# (the copy() is only to avoid a view into an otherwise unused array)
indices = np.argsort(distances(data, data.mean(0)))[:K].copy()
# distsums is, for all N points, the sum of the distances from the K points
distsums = spatial.distance.cdist(data, data[indices]).sum(1)
# but the K points themselves should not be considered
# (the trick is that -np.inf ± a finite quantity always yields -np.inf)
distsums[indices] = -np.inf
prev_sum = 0.0
for loop in range(MAX_LOOPS):
for i in range(K):
# remove this point from the K points
old_index = indices[i]
# calculate its sum of distances from the K points
distsums[old_index] = distances(data[indices], data[old_index]).sum()
# update the sums of distances of all points from the K-1 points
distsums -= distances(data, data[old_index])
# choose the point with the greatest sum of distances from the K-1 points
new_index = np.argmax(distsums)
# add it to the K points replacing the old_index
indices[i] = new_index
# don't consider it any more in distsums
distsums[new_index] = -np.inf
# update the sums of distances of all points from the K points
distsums += distances(data, data[new_index])
# sum all mutual distances of the K points
curr_sum = spatial.distance.pdist(data[indices]).sum()
# break if the sum hasn't changed
if curr_sum == prev_sum:
break
prev_sum = curr_sum
if ND == 2:
X, Y = data.T
marker_size = 4
plt.scatter(X, Y, s=marker_size)
plt.scatter(X[indices], Y[indices], s=marker_size)
plt.grid(True)
plt.gca().set_aspect('equal', adjustable='box')
plt.show()
_
N(10000)行とDディメンション(または機能)を_N*D
_ MARTIX Xに読み込む場合は、各点間の距離を計算し、次のように距離行列に保存できます。
_import numpy as np
X = np.asarray(X) ### convert to numpy array
distance_matrix = np.zeros((X.shape[0],X.shape[0]))
for i in range(X.shape[0]):
for j in range(i+1,X.shape[0]):
## We compute triangle matrix and copy the rest. Distance from point A to point B and distance from point B to point A are the same.
distance_matrix[i][j]= np.linalg.norm(X[i]-X[j]) ## Here I am calculating Eucledian distance. Other distance measures can also be used.
#distance_matrix = distance_matrix + distance_matrix.T - np.diag(np.diag(distance_matrix)) ## This syntax can be used to get the lower triangle of distance matrix, which is not really required in your case.
K = 5 ## Number of points that you want to pick
indexes = np.unravel_index(np.argsort(distance_matrix.ravel())[-1*K:], distance_matrix.shape)
print(indexes)
_