Arduinoを使用して環境ノイズの変化を検出し、C言語で記述するデバイスを構築しています。連続データから近似値の中央値を求めるにはどうすればよいですか?
サウンドセンサーは1秒ごとに音量を与えますので、すべての連続データ?現在の環境騒音レベルに変化があると判断する最良の方法は何ですか?
Arduinoを使用して環境ノイズの変化を検出し、C言語で記述するデバイスを構築しています。連続データから近似値の中央値を求めるにはどうすればよいですか?
サウンドセンサーは1秒ごとに音量を与えますので、すべての連続データ?現在の環境騒音レベルに変化があると判断する最良の方法は何ですか?
"find running median"を検索します。最初にstackoverflowを検索してください。あなたのデータの既知の特性に基づいて適合性を持つ、多くのアプローチがあります。
単純なアプローチの1つは、整数配列、たとえば等しい範囲の20個の要素を作成することです。各サンプルが採取されると、その値を設定された範囲にマップし、そのカウンタに1を加える。完了したら、カウンタ値を分析して近似された中央値を計算することができる。
あなたに最適な方法を判断するには、いくつかの方法を試す必要があります。
あなたが望むように聞こえるのは、(非常に類似しているmoving average)というと呼ばれます。これは、最後のn
値を配列に格納し、中央値を計算する必要がある場合に発生します。あなたはデータの数百時間の中央値を取得したい場合は、他の一方で、あなたはすべてのデータ値を格納する必要が
int data[5] = {0, 0, 0, 0, 0};
int dataI = 0;
int sortedData[5] = {0, 0, 0, 0, 0};
void pushNewData(int d) {
data[dataI] = d;
dataI++;
if(dataI > 4) {
dataI = 0;
}
}
int median() {
for(int i = 0; i < 5; i++) {
sortedData[i] = data[i];
}
// Use a sorting algorithm here to sort sortedData
return sortedData[3];
}
:ここ
が、これは次のようになります。これがあなたのユースケースの場合は、を代わりに使用することを強くお勧めします。平均値はsum/n
なので、2つの変数を追加して追加することができます。もちろん、オーバーフローを考慮する必要があります。
のは、あなたはまだ中央値は、(あなたがあなたのデータを心配している場合、たとえば、対称型されていないか、外れ値心配している)したいとしましょう。その場合、簡単にヒストグラムを作成し、それを使って中央値を推定することができます。
これは、intの配列を作成することで行います。インデックス0は値0-5
であり、インデックス2は値6-10
であり、以下同様である。新しいデータポイントが来るたびに、ポイントがどのバケット(値域)に入っているかチェックし、その配列の対応するカウンタをインクリメントします。
このデータから中央値を近似するのは簡単です。このデータを抽出したとしましょう:
Values 00-05: 1
Values 06-10: 7
Values 11-15: 8
Values 16-20: 2
Values 21-25: 1
Values 26-30: 5
n = 24なので、中央値はn = 12になります。 12番目のデータポイントは11-15
の範囲になるため、中央値は11と15の間になります。
5の範囲の代わりに、同じ効果で3または1の範囲を簡単に行うことができます。オーバーフローとメモリの使用に注意してください:あまりにも多くのバケットを使用しないようにすることに加えて、unsigned longの配列を使用する必要があります。
メジアンを求める入力の数から教えてください。 – Billa
@Billaは無限になる可能性があります。デバイスがオフになっていない限り毎秒入力があるためです – Chen