1

ID、機能、頻度の 3 つのフィールドを持つデータセットがあります。私がやりたいことは、与えられた id のグループについて、どの機能が最大の頻度分布を持っているかを見つけることです。私が望む結果は、id のグループを 2 つのサブグループに分割し、その機能の頻度の中央値を使用して、互いに最も異なる 2 つのグループがあることですが、サイズはほぼ同じです。

私が最初に考えたのは、各機能の頻度の分散を計算し、分散が最も高い機能を使用することでした。

次のようなデータベース テーブルがあるとします。

id | feature | frequency
---+---------+-------------
 0 | 0       | 1
 0 | 1       | 1
 0 | 2       | 0
 1 | 0       | 2
 1 | 1       | 2
 1 | 2       | 0
 2 | 0       | 3
 2 | 1       | 3
 2 | 2       | 8
 3 | 0       | 4
 3 | 1       | 8
 3 | 2       | 10
 4 | 0       | 5
 4 | 1       | 10
 4 | 2       | 12
  • 機能 0 の頻度は 1、2、3、4、5 です
  • 機能 1 の頻度は 1、2、3、9、10 です
  • 機能 2 の頻度は 0、0、4、10、12 です

機能 2 が最大の広がりを持ち、4 で分割すると、2 つのグループに分割するのに適していることがわかります (0、0、4 を 1 つのグループに、10 と 12 を別のグループに)。

これは、次の SQL クエリで計算できます。

SELECT feature, variance(frequency) as f FROM Dataset WHERE id IN (<list of ids>) GROUP BY feature ORDER BY f DESC LIMIT 1;

これは問題なく動作しますが、1 つの欠点があります。私のデータセットはまばらで (ほとんどのエントリの頻度はゼロです)、頻度がゼロのアイテムをデータベースに保存するには (スペースとエントリの挿入にかかる時間の両方の点で) コストがかかります。したがって、私の実際のテーブルは次のようになります。

id | feature | frequency
---+---------+-------------
 0 | 0       | 1
 0 | 1       | 1
 1 | 0       | 2
 1 | 1       | 2
 2 | 0       | 3
 2 | 1       | 3
 2 | 2       | 8
 3 | 0       | 4
 3 | 1       | 8
 3 | 2       | 10
 4 | 0       | 5
 4 | 1       | 10
 4 | 2       | 12

上記の SQL クエリでは、正しい分散値を計算するために頻度ゼロのエントリを考慮する必要があるため、正しい結果が得られません。私の SQL スキルは、この制限を回避できる (パフォーマンスの高い) クエリを理解するのに十分ではありません...

私の次の考えは、代わりに最大エントロピーを計算することでしたが、実際の頻度値(および「頻度」/同じ頻度値が同じデータセットにある回数)を考慮していないという事実に苦しんでいます-のみ個別の値の数。エントロピーの公式を誤解していない限り。

だから私の質問は:

  1. SQLでこれを行う方法はありますか?
  2. そうでない場合、ゼロエントリの数を考慮して計算された分散を「調整」する方法はありますか? (省略されたゼロエントリの数を知っていると仮定します)
  3. はいの場合、上記のように単一の SQL クエリでこれを行う方法はありますか? (繰り返しますが、ゼロエントリがいくつ省略されたかを事前に知っていると仮定します)
  4. どちらも不可能な場合、エントロピーを使用して実際の値を調整する方法はありますか?
  5. 考慮すべき他の尺度 (尖度など) はありますか? ゼロエントリの欠落を簡単に調整できるものはありますか?
  6. または、他の提案や代替ソリューションはありますか?
4

1 に答える 1

0

テーブルのギャップを埋めることに関してUNIONは、CROSS JOIN. 「方法」は、使用しているデータベース言語によって異なります。たとえば、3 つの行 (3 つの異なる機能用) を持つ "helper" という名前のテーブルがあるとします。これはうまくいくかもしれません:

select id, feature, frequency
from have
union
select b.id
     , a.feature
     , 0 as frequency
from helper a
cross join have b
where not exists (
   select 1 from have b1
   where b1.id=b.id
     and b1.feature = a.feature
   )

ここに SQLFiddle があります

于 2013-05-13T19:56:32.303 に答える