Sample Dataset Generator

創薬やマテリアルインフォはじめ、様々な分野に機械学習が浸透していますね。

機械学習の基礎を学ぼうとしたときや、自分の手法をテストしようとしたときに、良いデータセットを見つけるのに苦労したことはありませんか？

Sample Dataset Generatorはサンプルデータを自動生成するツールで、まさにそんな時に便利に使えるように自作しました。似たようなツールとして [sklearn.datasets.make_regression](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_regression.html) や [sklearn.datasets.make_classification](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_classification.html) などがありますが、それらより自由度が高く理解しやすいものを作ったつもりです。

以下のコードは https://github.com/maskot1977/sampledataset_generator.git で公開しており、 <a href="https://colab.research.google.com/github/maskot1977/sampledataset_generator/blob/main/sampledataset_generator_basic_usage.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a> で動作確認済みです。


# インストール

次のようにしてインストールできます。

```Python
!pip install git+https://github.com/maskot1977/sampledataset_generator.git
```


# 基本的な使い方

以下のような方法で、説明変数 `X` と目的変数 `Y` を自動的に作成できます。


```Python
from sampledataset_generator import generator

dataset = generator.SampleDatasetGenerator()
dataset.generate()
```


```Python
import pandas as pd

pd.DataFrame(dataset.X)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-0.874719</td>
      <td>0.228159</td>
      <td>1.043060</td>
      <td>-0.064032</td>
      <td>0.062203</td>
      <td>2.938519</td>
      <td>-0.366674</td>
      <td>1.087626</td>
      <td>0.271206</td>
      <td>1.396527</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-0.380454</td>
      <td>0.070878</td>
      <td>0.181825</td>
      <td>-0.172262</td>
      <td>0.080013</td>
      <td>0.420896</td>
      <td>0.734195</td>
      <td>-0.340716</td>
      <td>-0.571168</td>
      <td>1.437683</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-1.624316</td>
      <td>-0.312386</td>
      <td>-0.007409</td>
      <td>-0.001500</td>
      <td>-0.085444</td>
      <td>-0.117991</td>
      <td>-2.223847</td>
      <td>-0.318631</td>
      <td>0.389458</td>
      <td>-0.217023</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-0.379374</td>
      <td>-0.058680</td>
      <td>-0.496479</td>
      <td>0.541437</td>
      <td>0.121997</td>
      <td>-0.468587</td>
      <td>-0.250380</td>
      <td>0.038416</td>
      <td>0.646550</td>
      <td>0.869240</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2.187036</td>
      <td>-0.014006</td>
      <td>0.363903</td>
      <td>-0.509491</td>
      <td>0.001101</td>
      <td>1.084016</td>
      <td>1.328812</td>
      <td>-1.241679</td>
      <td>0.703932</td>
      <td>-0.157089</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>-0.236994</td>
      <td>-0.159133</td>
      <td>0.807234</td>
      <td>-0.083568</td>
      <td>0.078701</td>
      <td>-0.105214</td>
      <td>-2.761139</td>
      <td>0.043162</td>
      <td>-0.096247</td>
      <td>-0.106179</td>
    </tr>
    <tr>
      <th>96</th>
      <td>-0.391223</td>
      <td>-0.014557</td>
      <td>0.804878</td>
      <td>0.040324</td>
      <td>0.022574</td>
      <td>0.717083</td>
      <td>-1.149362</td>
      <td>1.051754</td>
      <td>-0.471551</td>
      <td>0.333957</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0.481387</td>
      <td>-0.038779</td>
      <td>0.380662</td>
      <td>0.857424</td>
      <td>0.067420</td>
      <td>1.599628</td>
      <td>-0.529226</td>
      <td>0.071804</td>
      <td>-0.201889</td>
      <td>-0.087362</td>
    </tr>
    <tr>
      <th>98</th>
      <td>1.422031</td>
      <td>0.021933</td>
      <td>-0.180896</td>
      <td>0.644405</td>
      <td>-0.012918</td>
      <td>-1.929145</td>
      <td>-0.598751</td>
      <td>-1.371636</td>
      <td>0.812930</td>
      <td>0.000721</td>
    </tr>
    <tr>
      <th>99</th>
      <td>-0.176868</td>
      <td>-0.003792</td>
      <td>0.662571</td>
      <td>-0.799834</td>
      <td>-0.011456</td>
      <td>-2.083081</td>
      <td>-0.144673</td>
      <td>0.154913</td>
      <td>0.250457</td>
      <td>0.331734</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 10 columns</p>




```Python
pd.DataFrame(dataset.Y)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>8.584018</td>
    </tr>
    <tr>
      <th>1</th>
      <td>1.502417</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.355069</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-2.698677</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2.331078</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>6.929988</td>
    </tr>
    <tr>
      <th>96</th>
      <td>6.780913</td>
    </tr>
    <tr>
      <th>97</th>
      <td>4.847613</td>
    </tr>
    <tr>
      <th>98</th>
      <td>-0.441276</td>
    </tr>
    <tr>
      <th>99</th>
      <td>4.126107</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 1 columns</p>



デフォルトでは、`X` から `Y` を計算する式は多項式の一次式です。最初の5つの項のみが `Y` を導出するために使用され、残りの項は `Y` から独立しています。


```Python
pd.DataFrame(dataset.coef)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0.060915</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-0.548520</td>
    </tr>
    <tr>
      <th>2</th>
      <td>8.244854</td>
    </tr>
    <tr>
      <th>3</th>
      <td>1.599333</td>
    </tr>
    <tr>
      <th>4</th>
      <td>4.259971</td>
    </tr>
    <tr>
      <th>5</th>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>6</th>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>7</th>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>8</th>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>9</th>
      <td>0.000000</td>
    </tr>
  </tbody>
</table>



# パラメーターと関数

デフォルトでは、`n_samples`=100, `n_features`=10, `n_informative`=5, `noise`=0.0, `function`=`linear`, `independence`=1.0となっています。

- `n_samples` はサンプル数です。
- `n_features` は特徴量の数です。
- `n_informative` はデフォルトの多項式線形関数で Y を導出する際に用いられる「意味のある」特徴量 X の数です. 
- `noise` はノイズの強さを表します。
- `independence`は、Yの導出に用いられない「無関係な」特徴量が、「意味のある」特徴量からどれだけ独立しているかを表します。

非線形関数が必要な場合は、以下のような関数 `friedman1`, `friedman2`, `friedman3` を用いることができます。


```Python
dataset = generator.SampleDatasetGenerator(function=generator.friedman1)
dataset.generate()
```

あるいは、任意の関数を定義して以下のように使用することもできます。


```Python
import numpy as np
my_func = lambda X, coef: np.arctan((X[:, 1] * X[:, 2] - 1 / (X[:, 1] * X[:, 3])) / X[:, 0])

dataset = generator.SampleDatasetGenerator(function=my_func)
dataset.generate()
```

# 欠損値を持つデータの作成

欠損値を含むデータは、以下の方法で作成することができます。欠損値の発生率を調整することができ、例えば `rate` = 0.05 とすることができます。


```Python
dataset = generator.SampleDatasetGenerator()
dataset.generate()
dataset.fill_nan_randomly()
pd.DataFrame(dataset.X)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>NaN</td>
      <td>-0.717267</td>
      <td>0.466119</td>
      <td>0.157829</td>
      <td>0.403057</td>
      <td>0.261670</td>
      <td>1.621723</td>
      <td>-2.384312</td>
      <td>-0.419102</td>
      <td>-0.187467</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-0.226485</td>
      <td>0.529230</td>
      <td>-1.417389</td>
      <td>-0.108385</td>
      <td>0.108098</td>
      <td>0.217466</td>
      <td>1.137134</td>
      <td>0.839975</td>
      <td>-0.329924</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.213283</td>
      <td>-0.980020</td>
      <td>NaN</td>
      <td>-0.031286</td>
      <td>0.252950</td>
      <td>-1.684535</td>
      <td>1.525129</td>
      <td>-1.228553</td>
      <td>-0.815602</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-0.610736</td>
      <td>-0.601983</td>
      <td>0.129403</td>
      <td>-0.041961</td>
      <td>-0.834912</td>
      <td>-0.447463</td>
      <td>1.315553</td>
      <td>-0.935183</td>
      <td>NaN</td>
      <td>-1.116784</td>
    </tr>
    <tr>
      <th>4</th>
      <td>-0.550343</td>
      <td>-0.148456</td>
      <td>NaN</td>
      <td>0.757180</td>
      <td>0.731174</td>
      <td>-0.562547</td>
      <td>0.425136</td>
      <td>-0.848524</td>
      <td>-1.284881</td>
      <td>-0.720632</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>-0.400990</td>
      <td>0.010573</td>
      <td>-0.017612</td>
      <td>0.323151</td>
      <td>0.257867</td>
      <td>0.008553</td>
      <td>-0.781648</td>
      <td>0.031025</td>
      <td>-1.071831</td>
      <td>1.435444</td>
    </tr>
    <tr>
      <th>96</th>
      <td>-0.008266</td>
      <td>-0.945571</td>
      <td>-1.367276</td>
      <td>0.396686</td>
      <td>0.434881</td>
      <td>-0.684910</td>
      <td>-0.845351</td>
      <td>-0.597488</td>
      <td>-1.066122</td>
      <td>0.822694</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0.154777</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>0.259955</td>
      <td>0.008274</td>
      <td>-0.866544</td>
      <td>-1.278649</td>
      <td>-0.711525</td>
      <td>-0.105661</td>
      <td>1.192752</td>
    </tr>
    <tr>
      <th>98</th>
      <td>0.174639</td>
      <td>0.208390</td>
      <td>2.833820</td>
      <td>0.352648</td>
      <td>-0.131895</td>
      <td>1.685485</td>
      <td>1.342137</td>
      <td>-0.594071</td>
      <td>0.882873</td>
      <td>-1.190221</td>
    </tr>
    <tr>
      <th>99</th>
      <td>0.784510</td>
      <td>0.443287</td>
      <td>-0.836974</td>
      <td>0.000743</td>
      <td>0.439658</td>
      <td>-2.741350</td>
      <td>0.887365</td>
      <td>-0.530844</td>
      <td>0.677080</td>
      <td>-0.525392</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 10 columns</p>



# 疎なデータの作成

以下のようにゼロ値を持つデータを作成することができます。 例えば、`rate`＝0.9 のように、ゼロ値の出現率を調整することができます。


```Python
dataset = generator.SampleDatasetGenerator()
dataset.generate()
dataset.fill_zero_randomly()
pd.DataFrame(dataset.X)
```



<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>2</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>3</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>1.290429</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>-0.620650</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>2.746314</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>96</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.254578</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>1.269509</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>98</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>99</th>
      <td>0.0</td>
      <td>0.0</td>
      <td>1.480686</td>
      <td>0.0</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.673103</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>0.000000</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 10 columns</p>



# 分類問題の目的変数

デフォルトでは、目的変数は連続であり、回帰問題を解くことを想定していますが、以下のようにすることで、目的変数を離散値として分類問題として扱うことができます。


```Python
dataset = generator.SampleDatasetGenerator()
dataset.generate()
dataset.categoricalize()
pd.DataFrame(dataset.Y)
```



<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>1</td>
    </tr>
    <tr>
      <th>1</th>
      <td>1</td>
    </tr>
    <tr>
      <th>2</th>
      <td>0</td>
    </tr>
    <tr>
      <th>3</th>
      <td>1</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>0</td>
    </tr>
    <tr>
      <th>96</th>
      <td>0</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0</td>
    </tr>
    <tr>
      <th>98</th>
      <td>0</td>
    </tr>
    <tr>
      <th>99</th>
      <td>0</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 1 columns</p>



以下のようにすることで、任意のバイアスを持つ任意の数のカテゴリデータを生成できます。


```Python
dataset = generator.SampleDatasetGenerator()
dataset.generate()
dataset.categoricalize(
    labels=["beer", "wine", "whiskey"], 
    classification_ratio=0.4
)
pd.DataFrame(dataset.Y)
```



<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>1</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>2</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>3</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>4</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>96</th>
      <td>whiskey</td>
    </tr>
    <tr>
      <th>97</th>
      <td>beer</td>
    </tr>
    <tr>
      <th>98</th>
      <td>wine</td>
    </tr>
    <tr>
      <th>99</th>
      <td>whiskey</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 1 columns</p>



# 説明変数に離散値を含める

以下のようにすることで、与えられた列の説明変数をカテゴリ変数にできます。


```Python
dataset = generator.SampleDatasetGenerator()
dataset.generate()
dataset.categoricalize(column=3)
pd.DataFrame(dataset.X)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-0.069141</td>
      <td>-0.152245</td>
      <td>-0.069177</td>
      <td>1.0</td>
      <td>2.147144</td>
      <td>1.683370</td>
      <td>-1.406095</td>
      <td>-0.288278</td>
      <td>0.021179</td>
      <td>0.386266</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-0.017672</td>
      <td>-0.330113</td>
      <td>-0.233835</td>
      <td>1.0</td>
      <td>-1.383669</td>
      <td>0.352960</td>
      <td>0.937982</td>
      <td>-1.835730</td>
      <td>1.179513</td>
      <td>-0.555153</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.049318</td>
      <td>0.672656</td>
      <td>-0.694506</td>
      <td>1.0</td>
      <td>-0.250240</td>
      <td>1.386238</td>
      <td>1.016130</td>
      <td>0.435432</td>
      <td>-0.102031</td>
      <td>-1.021133</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-0.035957</td>
      <td>-0.070815</td>
      <td>0.086850</td>
      <td>1.0</td>
      <td>-0.044765</td>
      <td>-0.424427</td>
      <td>0.823290</td>
      <td>-2.021052</td>
      <td>-0.740976</td>
      <td>0.774101</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0.054945</td>
      <td>0.316388</td>
      <td>-0.937645</td>
      <td>0.0</td>
      <td>-1.004592</td>
      <td>-1.727037</td>
      <td>-0.325570</td>
      <td>-0.185780</td>
      <td>0.660687</td>
      <td>-0.249081</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>-0.050984</td>
      <td>0.218996</td>
      <td>-0.436951</td>
      <td>1.0</td>
      <td>1.797569</td>
      <td>1.522909</td>
      <td>0.091088</td>
      <td>1.819058</td>
      <td>0.252704</td>
      <td>1.506190</td>
    </tr>
    <tr>
      <th>96</th>
      <td>-0.040341</td>
      <td>0.239490</td>
      <td>-0.118325</td>
      <td>1.0</td>
      <td>-0.750467</td>
      <td>-0.524603</td>
      <td>1.785338</td>
      <td>-0.590646</td>
      <td>-0.311082</td>
      <td>-0.588058</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0.032199</td>
      <td>0.652054</td>
      <td>-0.293499</td>
      <td>1.0</td>
      <td>-0.526053</td>
      <td>0.753688</td>
      <td>1.558890</td>
      <td>-1.672383</td>
      <td>0.610953</td>
      <td>-0.076587</td>
    </tr>
    <tr>
      <th>98</th>
      <td>-0.077576</td>
      <td>0.222219</td>
      <td>-0.018319</td>
      <td>0.0</td>
      <td>-0.393507</td>
      <td>-0.626555</td>
      <td>-0.160973</td>
      <td>-0.469242</td>
      <td>-0.435700</td>
      <td>-1.651206</td>
    </tr>
    <tr>
      <th>99</th>
      <td>0.001802</td>
      <td>0.383190</td>
      <td>-0.018126</td>
      <td>0.0</td>
      <td>-1.859617</td>
      <td>-0.601221</td>
      <td>0.211747</td>
      <td>-0.244071</td>
      <td>-0.559714</td>
      <td>-1.454075</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 10 columns</p>



以下のようにすることで、任意のバイアスを持つ任意の数のカテゴリデータを生成できます。


```Python
dataset.categoricalize(
    column=5, 
    labels=["pen", "pineapple", "apple"], 
    classification_ratio=0.4
)
pd.DataFrame(dataset.X)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-0.0691405</td>
      <td>-0.152245</td>
      <td>-0.0691765</td>
      <td>1</td>
      <td>2.14714</td>
      <td>pineapple</td>
      <td>-1.4061</td>
      <td>-0.288278</td>
      <td>0.0211786</td>
      <td>0.386266</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-0.0176721</td>
      <td>-0.330113</td>
      <td>-0.233835</td>
      <td>1</td>
      <td>-1.38367</td>
      <td>pen</td>
      <td>0.937982</td>
      <td>-1.83573</td>
      <td>1.17951</td>
      <td>-0.555153</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.0493178</td>
      <td>0.672656</td>
      <td>-0.694506</td>
      <td>1</td>
      <td>-0.25024</td>
      <td>pineapple</td>
      <td>1.01613</td>
      <td>0.435432</td>
      <td>-0.102031</td>
      <td>-1.02113</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-0.0359565</td>
      <td>-0.0708147</td>
      <td>0.0868503</td>
      <td>1</td>
      <td>-0.0447651</td>
      <td>apple</td>
      <td>0.82329</td>
      <td>-2.02105</td>
      <td>-0.740976</td>
      <td>0.774101</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0.0549453</td>
      <td>0.316388</td>
      <td>-0.937645</td>
      <td>0</td>
      <td>-1.00459</td>
      <td>apple</td>
      <td>-0.32557</td>
      <td>-0.18578</td>
      <td>0.660687</td>
      <td>-0.249081</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>-0.0509837</td>
      <td>0.218996</td>
      <td>-0.436951</td>
      <td>1</td>
      <td>1.79757</td>
      <td>pineapple</td>
      <td>0.0910875</td>
      <td>1.81906</td>
      <td>0.252704</td>
      <td>1.50619</td>
    </tr>
    <tr>
      <th>96</th>
      <td>-0.0403408</td>
      <td>0.23949</td>
      <td>-0.118325</td>
      <td>1</td>
      <td>-0.750467</td>
      <td>apple</td>
      <td>1.78534</td>
      <td>-0.590646</td>
      <td>-0.311082</td>
      <td>-0.588058</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0.0321993</td>
      <td>0.652054</td>
      <td>-0.293499</td>
      <td>1</td>
      <td>-0.526053</td>
      <td>pineapple</td>
      <td>1.55889</td>
      <td>-1.67238</td>
      <td>0.610953</td>
      <td>-0.0765871</td>
    </tr>
    <tr>
      <th>98</th>
      <td>-0.0775761</td>
      <td>0.222219</td>
      <td>-0.0183187</td>
      <td>0</td>
      <td>-0.393507</td>
      <td>apple</td>
      <td>-0.160973</td>
      <td>-0.469242</td>
      <td>-0.4357</td>
      <td>-1.65121</td>
    </tr>
    <tr>
      <th>99</th>
      <td>0.0018016</td>
      <td>0.38319</td>
      <td>-0.0181257</td>
      <td>0</td>
      <td>-1.85962</td>
      <td>apple</td>
      <td>0.211747</td>
      <td>-0.244071</td>
      <td>-0.559714</td>
      <td>-1.45408</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 10 columns</p>



整数や非負数にしたい場合は以下のようにします。


```Python
dataset.categoricalize(
    column=7, 
    labels=range(10), 
    classification_ratio=0.4
)
pd.DataFrame(dataset.X)
```




<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-0.0691405</td>
      <td>-0.152245</td>
      <td>-0.0691765</td>
      <td>1</td>
      <td>2.14714</td>
      <td>pineapple</td>
      <td>-1.4061</td>
      <td>0</td>
      <td>0.0211786</td>
      <td>0.386266</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-0.0176721</td>
      <td>-0.330113</td>
      <td>-0.233835</td>
      <td>1</td>
      <td>-1.38367</td>
      <td>pen</td>
      <td>0.937982</td>
      <td>5</td>
      <td>1.17951</td>
      <td>-0.555153</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.0493178</td>
      <td>0.672656</td>
      <td>-0.694506</td>
      <td>1</td>
      <td>-0.25024</td>
      <td>pineapple</td>
      <td>1.01613</td>
      <td>6</td>
      <td>-0.102031</td>
      <td>-1.02113</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-0.0359565</td>
      <td>-0.0708147</td>
      <td>0.0868503</td>
      <td>1</td>
      <td>-0.0447651</td>
      <td>apple</td>
      <td>0.82329</td>
      <td>5</td>
      <td>-0.740976</td>
      <td>0.774101</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0.0549453</td>
      <td>0.316388</td>
      <td>-0.937645</td>
      <td>0</td>
      <td>-1.00459</td>
      <td>apple</td>
      <td>-0.32557</td>
      <td>2</td>
      <td>0.660687</td>
      <td>-0.249081</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>-0.0509837</td>
      <td>0.218996</td>
      <td>-0.436951</td>
      <td>1</td>
      <td>1.79757</td>
      <td>pineapple</td>
      <td>0.0910875</td>
      <td>6</td>
      <td>0.252704</td>
      <td>1.50619</td>
    </tr>
    <tr>
      <th>96</th>
      <td>-0.0403408</td>
      <td>0.23949</td>
      <td>-0.118325</td>
      <td>1</td>
      <td>-0.750467</td>
      <td>apple</td>
      <td>1.78534</td>
      <td>0</td>
      <td>-0.311082</td>
      <td>-0.588058</td>
    </tr>
    <tr>
      <th>97</th>
      <td>0.0321993</td>
      <td>0.652054</td>
      <td>-0.293499</td>
      <td>1</td>
      <td>-0.526053</td>
      <td>pineapple</td>
      <td>1.55889</td>
      <td>5</td>
      <td>0.610953</td>
      <td>-0.0765871</td>
    </tr>
    <tr>
      <th>98</th>
      <td>-0.0775761</td>
      <td>0.222219</td>
      <td>-0.0183187</td>
      <td>0</td>
      <td>-0.393507</td>
      <td>apple</td>
      <td>-0.160973</td>
      <td>0</td>
      <td>-0.4357</td>
      <td>-1.65121</td>
    </tr>
    <tr>
      <th>99</th>
      <td>0.0018016</td>
      <td>0.38319</td>
      <td>-0.0181257</td>
      <td>0</td>
      <td>-1.85962</td>
      <td>apple</td>
      <td>0.211747</td>
      <td>2</td>
      <td>-0.559714</td>
      <td>-1.45408</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 10 columns</p>


# 実験

以下のコードは https://github.com/maskot1977/sampledataset_generator.git で公開しており、 <a href="https://colab.research.google.com/github/maskot1977/sampledataset_generator/blob/main/sampledataset_generator_experiment.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a> で動作確認済みです。

ここからは、データセットの種類や性質を変えることが予測精度にどのように影響するかを確認するために、いくつかの代表的な機械学習手法を実験します。 Sample Dataset Generator リポジトリでは、以下の実験用スクリプトを提供しています。


```Python
from sampledataset_generator import experiment
```

以下に、代表的な回帰手法の結果を載せますので、回帰手法の性質と、データセットの性質を考えながら、何が起こっているのか考えてみましょう！

# 線形重回帰 Linear Regression

`independence`、`noise`、`n_features` を変更した場合の影響を見てみましょう。


```Python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression

experiment.benchmark(
    "LinearRegression", 
    make_pipeline(
        StandardScaler(), 
        LinearRegression()
        )
    )
```

線形関数

![sampledataset_generator_experiment_6_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/287f3f46-d288-b767-401b-984e54ed97be.png)

非線形関数

![sampledataset_generator_experiment_6_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/cb92cc3d-e4cb-4cdf-ee84-dc489ab7f05c.png)



# 偏最小二乗回帰 Partial Least Square (PLS) Regression

`independence`、`noise`、`n_features` を変更した場合の影響を見てみましょう。


```Python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.cross_decomposition import PLSRegression

experiment.benchmark(
    "PLSRegression", 
    make_pipeline(
        StandardScaler(), 
        PLSRegression(n_components=10)
        )
    )
```

線形関数

![sampledataset_generator_experiment_8_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/bfa6ddeb-fdee-463d-4323-0e21a9bdfe6e.png)

非線形関数

![sampledataset_generator_experiment_8_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/80b39de7-4c0f-bdd4-5870-1dadf925cbc1.png)





# サポートベクトル回帰 Support Vector Regression (SVR)

`independence`、`noise`、`n_features` を変更した場合の影響を見てみましょう。


```Python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR

experiment.benchmark(
    "SVR", 
    make_pipeline(
        StandardScaler(), 
        SVR(C=50, gamma='auto', epsilon=1e-05)
        )
    )
```

線形関数

![sampledataset_generator_experiment_10_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b8098c68-bbbc-975f-0c9b-fe03c523c242.png)

非線形関数

![sampledataset_generator_experiment_10_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/4cb5bdb1-3dd2-de6e-0141-3716cc3bdc28.png)




# ランダムフォレスト回帰 Random Forest Regression

`independence`、`noise`、`n_features` を変更した場合の影響を見てみましょう。


```Python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor

experiment.benchmark(
    "RandomForestRegressor", 
    make_pipeline(
        StandardScaler(), 
        RandomForestRegressor(
            random_state=1, 
            max_depth=8, 
            n_estimators=16
            )
        )
    )
```

線形関数

![sampledataset_generator_experiment_12_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/e8c49428-ca08-0bc1-f808-54182ed05790.png)

非線形関数

![sampledataset_generator_experiment_12_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/fb17b9fe-3e1a-66df-f3ce-9118d8279ae9.png)




# 多層パーセプトロン回帰 Multi-Layer Perceptron (MLP) Regression

`independence`、`noise`、`n_features` を変更した場合の影響を見てみましょう。



```Python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPRegressor

experiment.benchmark(
    "MLPRegressor", 
    make_pipeline(
        StandardScaler(), 
        MLPRegressor(
            random_state=1, 
            max_iter=2000, 
            early_stopping=True,
            hidden_layer_sizes=(
                100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100
                )
            )
        )
    )
```

線形関数

![sampledataset_generator_experiment_14_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/afd96a0f-5df2-849f-2ea9-0fd0a0834f05.png)

非線形関数

![sampledataset_generator_experiment_14_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/e1841fa3-564f-8a3f-b527-6a95abdc28b1.png)