質問
最後に質問したのは、x座標でデータをビン化する方法です。解決策はシンプルでエレガントであり、私はそれを見なかったことを恥ずかしく思います。この質問は難しいかもしれません(または私はただ盲目かもしれません)。
約140000個のデータポイントから始め、x軸に沿って等間隔で70個のグループに分割し、各グループの平均位置(x_avg、y_avg)を取得してプロットしました。素敵な曲線が現れました。残念ながら、2つの問題があります。まず、グラフの中心よりもエッジの数がはるかに少なくなっています。第二に、一部の領域は他の領域よりも変化するため、より良い解像度が必要です。
したがって、2つの具体的な質問と、提案を投げかける一般的な招待状があります。
matlabには、行列を固定数の小さな行列または固定サイズの小さな行列に分割する組み込みの方法がありますか?
関心領域をより細かくビン化するために必要な境界を決定するためのアルゴリズム(またはmatlab関数ですが、ありそうもないと思います)はありますか?
より一般的には、何万ものデータポイントを簡潔なトレンドに凝縮するより良い方法がありますか?
解決
x値の密度に応じてサイズが異なるビンを使用したいようです。以前の投稿への回答のように、関数HISTCを引き続き使用できると思いますが、別のエッジセットを指定する必要があります。
これが本当に望んでいるかどうかはわかりませんが、1つの提案があります:x軸を70個の等間隔のグループに分割する代わりに、ソートされたxデータを70個の等しいグループに分割し、エッジ値を決定します。このコードは動作するはずです:
% Start by assuming x and y are vectors of data:
nBins = 70;
nValues = length(x);
[xsort,index] = sort(x); % Sort x in ascending order
ysort = y(index); % Sort y the same way as x
binEdges = [xsort(1:ceil(nValues/nBins):nValues) xsort(nValues)+1];
% Bin the data and get the averages as in previous post (using ysort instead of y):
[h,whichBin] = histc(xsort,binEdges);
for i = 1:nBins
flagBinMembers = (whichBin == i);
binMembers = ysort(flagBinMembers);
binMean(i) = mean(binMembers);
end
これにより、データ密度に応じてサイズが異なるビンが得られます。
更新:別のバージョン...
これは、いくつかのコメントの後に思いついた別のアイデアです。このコードを使用して、xの隣接するデータポイント間の差にしきい値(maxDelta)を設定します。 maxDelta以上の量だけ大きい隣人と異なるx値は、(すべて寂しいために)独自のビンに入れられます。引き続きnBinsの値を選択しますが、展開ポイントが独自のビンに降格されると、ビンの最終数はこの値より大きくなります。
% Start by assuming x and y are vectors of data:
maxDelta = 10; % Or whatever suits your data set!
nBins = 70;
nValues = length(x);
[xsort,index] = sort(x); % Sort x in ascending order
ysort = y(index); % Sort y the same way as x
% Create bin edges:
edgeIndex = false(1,nValues);
edgeIndex(1:ceil(nValues/nBins):nValues) = true;
edgeIndex = edgeIndex | ([0 diff(xsort)] >= maxDelta);
nBins = sum(edgeIndex);
binEdges = [xsort(edgeIndex) xsort(nValues)+1];
% Bin the data and get the y averages:
[h,whichBin] = histc(xsort,binEdges);
for i = 1:nBins
flagBinMembers = (whichBin == i);
binMembers = ysort(flagBinMembers);
binMean(i) = mean(binMembers);
end
いくつかの小さなサンプルデータセットでこれをテストしましたが、想定どおりの動作をするようです。それが含まれているものは何でも、あなたのデータセットでも機能することを願っています! =)
他のヒント
matlabを使用したことはありませんが、前の質問を見て、 Kdtree またはバリエーション。
明確化:これについて多少の混乱があるように思えるので、擬似コードの例が適切だと思います。
// Some of this shamelessly borrowed from the wikipedia article
function kdtree(points, lower_bound, upper_bound) {
// lower_bound and upper_bound are the boundaries of your bucket
if(points is empty) {
return nil
}
// It's a trivial exercise to control the minimum size of a partition as well
else {
// Sort the points list and choose the median element
select median from points.x
node.location = median;
node.left = kdtree(select from points where lower_bound < points.x <= median, lower_bound, median);
node.right = kdtree(select from points where median < points.x <= upper_bound, median, upper_bound);
return node
}
}
kdtree(points, -inf, inf)
// or alternatively
kdtree(points, min(points.x), max(points.x))