casTableのヒストグラムをグラフ化する

[SAS Viya](https://www.sas.com/ja_jp/software/viya.html)はAIプラットフォームになります。Webブラウザ上で機械学習の設計、実行ができるStudioという環境も用意されていますが、開発者はプログラミングコードで開発することも可能です。プログラミング言語はJava/Python/R/SASが選べます。

機械学習を用いる際に専用のテーブル（casTable）を用いますが、今回はグループ化したデータのヒストグラム（分布）を確認する方法を解説します。

## データを取り込む

今回使うのは `organics.sas7bdat` です。年齢、性別ごとに健康状態などが入ったデータです。まずこのデータを読み込みます。

```py
organics = sess.upload('organics.sas7bdat')
```

## グループ化するカラムを指定する

今回は複数カラムをグルーピングに指定します。

```py
organics.casTable.groupby = ['NGroup', 'Gender']
result = organics.casTable.summary(inputs='Age')
result3 = result.concat_bygroups()
result3['Summary'][['N', 'Min', 'Mean', 'Max', 'Std']]
```

そうするとデータは以下のように表示されます。

<table border="1" class="dataframe"><caption>Descriptive Statistics for ORGANICS</caption>
  <thead>
    <tr style="text-align: right;">
      <th title=""></th>
      <th title=""></th>
      <th title="N">N</th>
      <th title="Minimum">Min</th>
      <th title="Mean">Mean</th>
      <th title="Maximum">Max</th>
      <th title="Std Dev">Std</th>
    </tr>
    <tr>
      <th title="NGROUP">NGROUP</th>
      <th title="GENDER">GENDER</th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th rowspan="4" valign="top"></th>
      <th></th>
      <td>57.0</td>
      <td>29.0</td>
      <td>54.298246</td>
      <td>78.0</td>
      <td>12.562650</td>
    </tr>
    <tr>
      <th>F</th>
      <td>365.0</td>
      <td>24.0</td>
      <td>50.682192</td>
      <td>79.0</td>
      <td>13.316223</td>
    </tr>
    <tr>
      <th>M</th>
      <td>155.0</td>
      <td>23.0</td>
      <td>53.858065</td>
      <td>78.0</td>
      <td>13.177331</td>
    </tr>
    <tr>
      <th>U</th>
      <td>43.0</td>
      <td>18.0</td>
      <td>52.627907</td>
      <td>78.0</td>
      <td>15.104435</td>
    </tr>
    <tr>
      <th rowspan="4" valign="top">A</th>
      <th></th>
      <td>228.0</td>
      <td>27.0</td>
      <td>58.070175</td>
      <td>79.0</td>
      <td>10.859308</td>
    </tr>
    <tr>
      <th>F</th>
      <td>892.0</td>
      <td>19.0</td>
      <td>56.383408</td>
      <td>79.0</td>
      <td>13.528325</td>
    </tr>
    <tr>
      <th>M</th>
      <td>452.0</td>
      <td>24.0</td>
      <td>57.488938</td>
      <td>79.0</td>
      <td>11.934127</td>
    </tr>
    <tr>
      <th>U</th>
      <td>153.0</td>
      <td>21.0</td>
      <td>59.150327</td>
      <td>79.0</td>
      <td>11.843148</td>
    </tr>
    <tr>
      <th rowspan="4" valign="top">B</th>
      <th></th>
      <td>451.0</td>
      <td>20.0</td>
      <td>56.416851</td>
      <td>79.0</td>
      <td>12.255215</td>
    </tr>
    <tr>
      <th>F</th>
      <td>2079.0</td>
      <td>19.0</td>
      <td>56.823954</td>
      <td>79.0</td>
      <td>12.702405</td>
    </tr>
    <tr>
      <th>M</th>
      <td>1026.0</td>
      <td>18.0</td>
      <td>57.592593</td>
      <td>79.0</td>
      <td>12.522748</td>
    </tr>
    <tr>
      <th>U</th>
      <td>307.0</td>
      <td>28.0</td>
      <td>57.749186</td>
      <td>79.0</td>
      <td>11.662981</td>
    </tr>
    <tr>
      <th rowspan="4" valign="top">U</th>
      <th></th>
      <td>5.0</td>
      <td>27.0</td>
      <td>56.800000</td>
      <td>76.0</td>
      <td>18.212633</td>
    </tr>
    <tr>
      <th>F</th>
      <td>32.0</td>
      <td>27.0</td>
      <td>47.500000</td>
      <td>77.0</td>
      <td>16.372676</td>
    </tr>
    <tr>
      <th>M</th>
      <td>12.0</td>
      <td>26.0</td>
      <td>46.250000</td>
      <td>57.0</td>
      <td>10.172378</td>
    </tr>
    <tr>
      <th>U</th>
      <td>1.0</td>
      <td>54.0</td>
      <td>54.000000</td>
      <td>54.0</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>

## ヒストグラムを取り出す

ヒストグラムは `histogram` メソッドを使います。

```py
result = organics.casTable.histogram(reqpacks=[{'nicebinning':False, 'nbins':10}], inputs=['BILL'])
```

key関数を使うとデータが分かれているのが分かります。

```py
list(result.keys())
```

実行結果です。

```py
['ByGroupInfo',
 'ByGroup1.BinDetails',
 'ByGroup2.BinDetails',
 'ByGroup3.BinDetails',
 'ByGroup4.BinDetails',
 'ByGroup5.BinDetails',
 'ByGroup6.BinDetails',
 'ByGroup7.BinDetails',
 'ByGroup8.BinDetails',
 'ByGroup9.BinDetails',
 'ByGroup10.BinDetails',
 'ByGroup11.BinDetails',
 'ByGroup12.BinDetails',
 'ByGroup13.BinDetails',
 'ByGroup14.BinDetails',
 'ByGroup15.BinDetails',
 'ByGroup16.BinDetails',
 'ByGroup17.BinDetails',
 'ByGroup18.BinDetails',
 'ByGroup19.BinDetails',
 'ByGroup20.BinDetails',
 'ByGroup21.BinDetails']
```

例えば `result['ByGroup1.BinDetails']` を見ると以下のようになっています。

<table border="1" class="dataframe"><caption>Bin Details for ORGANICS</caption>
  <thead>
    <tr style="text-align: right;">
      <th title=""></th>
      <th title=""></th>
      <th title="Variable">Variable</th>
      <th title="Bin Set ID">BinSetId</th>
      <th title="Bin ID">BinId</th>
      <th title="Lower Bound">BinLowerBnd</th>
      <th title="Upper Bound">BinUpperBnd</th>
      <th title="Bin Width">BinWidth</th>
      <th title="N">NInBin</th>
      <th title="Mean">Mean</th>
      <th title="Standard Deviation">Std</th>
      <th title="Min">Min</th>
      <th title="Max">Max</th>
      <th title="Bin Mid Point">MidPoint</th>
      <th title="Percentage of Obs in Bin">Percent</th>
    </tr>
    <tr>
      <th title="Neighborhood Group">NGROUP</th>
      <th title="GENDER">GENDER</th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
      <th title=""></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th rowspan="10" valign="top">A</th>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>1</td>
      <td>0.010</td>
      <td>7000.009</td>
      <td>6999.999</td>
      <td>734</td>
      <td>2608.377643</td>
      <td>2396.778681</td>
      <td>0.01</td>
      <td>7000.00</td>
      <td>3500.0095</td>
      <td>77.100840</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>2</td>
      <td>7000.009</td>
      <td>14000.008</td>
      <td>6999.999</td>
      <td>124</td>
      <td>10506.032016</td>
      <td>1712.541126</td>
      <td>7100.00</td>
      <td>14000.00</td>
      <td>10500.0085</td>
      <td>13.025210</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>3</td>
      <td>14000.008</td>
      <td>21000.007</td>
      <td>6999.999</td>
      <td>54</td>
      <td>18051.901481</td>
      <td>2189.119118</td>
      <td>14105.32</td>
      <td>20681.55</td>
      <td>17500.0075</td>
      <td>5.672269</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>4</td>
      <td>21000.007</td>
      <td>28000.006</td>
      <td>6999.999</td>
      <td>19</td>
      <td>24540.320526</td>
      <td>2133.572237</td>
      <td>21008.63</td>
      <td>27497.04</td>
      <td>24500.0065</td>
      <td>1.995798</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>5</td>
      <td>28000.006</td>
      <td>35000.005</td>
      <td>6999.999</td>
      <td>11</td>
      <td>31520.056364</td>
      <td>2326.827210</td>
      <td>28113.08</td>
      <td>35000.00</td>
      <td>31500.0055</td>
      <td>1.155462</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>6</td>
      <td>35000.005</td>
      <td>42000.004</td>
      <td>6999.999</td>
      <td>4</td>
      <td>36440.122500</td>
      <td>1095.197998</td>
      <td>35465.20</td>
      <td>38000.00</td>
      <td>38500.0045</td>
      <td>0.420168</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>7</td>
      <td>42000.004</td>
      <td>49000.003</td>
      <td>6999.999</td>
      <td>4</td>
      <td>45857.757500</td>
      <td>2592.275555</td>
      <td>42160.04</td>
      <td>48069.40</td>
      <td>45500.0035</td>
      <td>0.420168</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>8</td>
      <td>49000.003</td>
      <td>56000.002</td>
      <td>6999.999</td>
      <td>1</td>
      <td>50000.000000</td>
      <td>NaN</td>
      <td>50000.00</td>
      <td>50000.00</td>
      <td>52500.0025</td>
      <td>0.105042</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>9</td>
      <td>56000.002</td>
      <td>63000.001</td>
      <td>6999.999</td>
      <td>0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>59500.0015</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>F</th>
      <td>BILL</td>
      <td>1</td>
      <td>10</td>
      <td>63000.001</td>
      <td>70000.000</td>
      <td>6999.999</td>
      <td>1</td>
      <td>70000.000000</td>
      <td>NaN</td>
      <td>70000.00</td>
      <td>70000.00</td>
      <td>66500.0005</td>
      <td>0.105042</td>
    </tr>
  </tbody>
</table>

そしてこれを棒グラフにしてみます。利用するのはbokeh.chartsです。

```python
from bokeh.charts import Bar, Scatter, output_file, show, Area
```

棒グラフを定義します。

```py
p = Bar(result['ByGroup1.BinDetails'], 'MidPoint', values='Percent', color='#1f77b4', agg='mean', title='', legend=None, xlabel='Bill', ylabel='Percent')
```

後はHTMLに出力するだけです。

```python
output_file('visual2.html')
show(p)
```

これでグラフが描画されます。

<img width="1115" alt="Screenshot_ 2019-01-23 16.22.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/274479/c261d9a0-2369-bc75-ab8c-ef5e5db29700.png">


----

データの偏りなどを調べる際にヒストグラムは便利です。ぜひお試しください。