生成高度偏斜数据的直方图

时间:2013-10-10 06:46:03

标签: javascript d3.js statistics dc.js

我正在使用dc.jscrossfilter.jsd3.js生成条形图。

条形图表示信用卡交易的数据。它绘制了交易数量(y轴)与交易金额(x轴)之间的关系。

看起来像这样:

Bar Chart

数据数组基本上如下:

[
  ...
  {
    txn_id: 1,
    txn_amount: 20
  },
  ...
]

根据不同的商家等情况,数据变化很大,我无法对分布做出任何假设。

正如您所看到的,由于数据本身,这个图表并不是那么有用。在这种情况下,-$75002有一个交易,$7500左右。

在其他金额之间,但大多数交易都聚集在$0 - $100附近,您可以看到峰值。

不幸的是,有足够的差异,你甚至看不到频率较低的交易金额。

answer似乎很接近,但并不完全存在。

我真正想要做的是将x轴刻度分成10个合理大小的块,这些块可以合理地对事务量进行分组,使图形更有用。

例如,假设在这种情况下,平均交易金额为$20。极端最小值和最大值为-$7500$7500

所以在这个特定的例子中,我可能希望将x轴分块,如下:

Bin 1: -$1000 >= transaction amount
Bin 2: -$100 >= transaction amount > -$1000
Bin 3: -$50 >= transaction amount > -$100
Bin 4: $0 >= transaction amount > -$50
Bin 5: $15 >= transaction amount > $0
Bin 6: $25 >= transaction amount > $15
Bin 7: $40 >= transaction amount > $25
Bin 8: $100 >= transaction amount > $40
Bin 9: $1000 >= transaction amount > $100
Bin 10: transaction amount > $1000

(块/ bin大小越来越小,越接近我们得到的平均值)。

不可否认,自从我对统计数据进行过认真研究以来已经很久了,所以我很生气。但似乎我将数据分成垃圾箱/卡盘的方式与我数据的标准偏差有很大关系。

我想我对自己想要的东西有一种良好的感觉,我对如何使用d3.jsd3.mean()d3.quantile()?)和{{1}感到有点迷失获得与我所描述的类似的直方图。

那么正确的方法是什么,或者我应该使用哪些库:

  1. 根据任意给定的数据集创建10个“合理”大小的垃圾箱
  2. 将数据分组到那些箱子中(实际上,这部分应该非常简单)
  3. 就物理间距直方图的x轴而言,我认为不需要或不希望刻度线间隔不均匀(因此可能不再是直方图)。

    尽管块大小不相等,但我更喜欢刻度线保持均匀间隔。我将确保恰当地标记滴答。

    非常感谢任何正确方向的指示。

    更新

    所以似乎dc.js像往常一样领先于我几步,已经让我退缩了。我相信我可以使用d3.js将x轴分成10个分位数(十分位数)。实际上,我已经设置了分位数比例并且它似乎正在做正确的事情,当我将数字直接输入分位数比例函数(通过JS控制台)时,它输出正确的桶(在10中)。

    但不幸的是我的图表仍然搞砸了。这是我的代码:

    d3.scale.quantile()

    以及生成的图表:

    Quantiled Bar Chart

    我想我已经接近了,但仍然不确定我在哪里出错了。

2 个答案:

答案 0 :(得分:1)

你可以使用异常值测试来修剪你的异常值,然后将它们添加回极端箱中。我还将这些箱柜上的文字更改为y,但这可以通过将一组自定义的刻度线传递给轴来轻松完成。

我使用Chauvenet's criterion模拟了一个例子,这是一些异常值测试之一。我原本以为使用Grubbs测试(或者甚至更好的多个Grubbs Beck测试)但是有一些工作来编写它。 Chauvenet的标准很简单,假设任何大于m的标准偏差值都是异常值。

我把这些放在一起here,功能是:

function chauvenet (x) {
    var dMax = 3;
    var mean = d3.mean(x);
    var stdv = Math.sqrt(variance(x));
    var counter = 0;
    var temp = [];

    for (var i = 0; i < x.length; i++) {
        if(dMax > (Math.abs(x[i] - mean))/stdv) {
            temp[counter] = x[i]; 
            counter = counter + 1;
        }
    };

    return temp
}

这些术语都很明显,dMax是标准差的数量,mean是平均值,stdv是标准差(或方差的平方根)。

注意我没有将异常值添加回直方图中,但这应该很容易。

答案 1 :(得分:0)

如果d3给你一个艰难的时间..尝试这个http://imaginea.github.com/uvCharts :) 您必须已经知道nvd3