ヒストグラム

提供: MonoBook
移動: 案内検索

ヒストグラム英語: histogram)とは、縦軸に度数、横軸に階級をとったグラフである。 統計や画像処理でよく用いられる。

概要[編集]

Histogram(ヒストグラム)は、ギリシャ語で「すべてのものを直立にする」(帆船のマスト、織機のバー、ないしはヒストグラムの縦棒など)という意味を持つ histos(ヒストス)と、同じくギリシャ語で「描いたり、記録したり、書いたりすること」という意味を持つ gramma(グラマ)を合わせたものである。この用語は、イギリスの統計学者カール・ピアソンによって1895年に創案された。

日本工業規格JIS Z 9041-1:1999では、「ヒストグラムの書き方 方眼紙又は適当な用紙に図 4 のように横軸に測定値の級の値,縦軸に度数を目盛り,各級に属する度数を柱の高さで示す。図の右上に測定値の総数 n を記入する。」とだけ定義している。累積度数図をその次に説明している。

日本工業規格JIS Z 8101-1 : 1999の2.7 ヒストグラム histogramでは「計量特性の度数分布のグラフ表示の一つ。測定値の存在する範囲をいくつかの区間に分けた場合,各区間を底辺とし,その区間に属する測定値の度数に比例する面積をもつ長方形を並べた図。備考1.ヒストグラムで用いられた区間の幅が一定ならば,長方形の高さは各区間に属する値の度数に比例する。したがって,この場合には高さに対して度数の目盛を与えることができる。 備考2.級の上限を横軸に,累積度数を縦軸にとって打点し,それらの点を結んで得られる折れ線を累積折れ線 (cumulative frequency polygon) という」 と規定している。

実装例[編集]

C#での実装例。

    public class Histogram
    {
        private int[] _values;
        private int _total;
        private int _min;
        private int _max;
        private int _offset;
        private int _window;
        private int _wstart;
        private int _wend;
        private int _wtotal;
 
        public Histogram(int min, int max)
        {
            int range = max - min + 1;
            _values = new int[range];
            _min = min;
            _max = max;
            _offset = -_min;
            _wstart = 0;
            _wend = _values.Length - 1;
            _window = -1;
        }
 
        public int WindowStart
        {
            get { return _wstart - _offset; }
        }
 
        public int WindowEnd
        {
            get { return _wend - _offset; }
        }
 
        public int WindowTotal
        {
            get
            {
                if (_window == -1) 
                    ApplyWindow(100);
                return _wtotal;
            }
        }
 
        public int this[int value]
        {
            get
            {
                int pos = value + _offset;
                if (pos < 0 || _values.Length <= pos) 
                    return 0;
                return _values[pos];
            }
        }
 
        public void Add(int value)
        {
            int pos = value + _offset;
            if (pos < 0 || _values.Length <= pos) 
                return;
 
            _values[pos]++;
            _total++;
 
            if (pos >= _wstart && pos <= _wend) 
                _wtotal++;
        }
 
        public void Clear(int value)
        {
            int pos = value + _offset - 1;
            if (pos < 0 || _values.Length <= pos)
                return;
 
            _total -= _values[pos];
            if (_wstart <= pos && pos <= _wend)
                _wtotal -= _values[pos];
 
            _values[pos] = 0;
        }
 
        public void ApplyWindow(int percent)
        {
            _wstart = 0;
            _wend = _values.Length - 1;
            _window = percent;
            _wtotal = _total;
 
            if (percent == 100 || _total == 0)
                return;
 
            var target = (int)(_total * (percent / 100.0));
 
            while (_wtotal > target)
            {
                var wtotal = _wtotal;
                if (_values[_wend] <= _values[_wstart])
                {
                    wtotal -= _values[_wstart];
                    if (wtotal < target) 
                        break;
                    _wstart++;
                }
                else
                {
                    wtotal -= _values[_wend];
                    if (wtotal < target) 
                        break;
                    _wend--;
                }
 
                _wtotal = wtotal;
 
                if (_wstart == _wend) 
                    break;
            }
        }
 
        public void ApplyWindow(int start, int end)
        {
            _wstart = start + _offset;
            _wend = end + _offset;
 
            if (_wstart == 0 && _wend == _values.Length - 1)
            {
                _window = 100;
                _wtotal = _total;
                return;
            }
 
            for (int i = _wstart; i <= _wend; i++) 
                _wtotal += _values[i];
 
            _window = (int)((double)_wtotal / (double)_total);
        }
    }

関連項目[編集]

参考文献[編集]