Python – 無作為抽出(Random Sampling)

Python – 無作為抽出(Random Sampling)

最近非常に注目されているCausal Inferenceですが、今回は業務にて頻繁に使用する無作為抽出(Random Sampling)について記載していきます。

1. データ準備

データ準備として、今回はsklearn.datasetsのcalifornia_housingを使用していきます。このデータは回帰用のSampleデータとして使用できますので、必要に応じて使用してみてください。また、pandas.dataframeを使用するので、pandasもimportし、sklearn.datasetsのcalifornia_housingのデータを変数に格納します。

In [1]: import pandas as pd
   ...: from sklearn.datasets import fetch_california_housing

In [2]: california_housing = fetch_california_housing()

california_housingのデータをpandas.dataframeに変換し、target column「MudHouseVal」をdataframeに追加してデータ準備完了です。

In [3]: df = pd.DataFrame(california_housing.data, columns=california_housing.feature_names)

In [4]: df['MedHouseVal'] = pd.Series(california_housing.target)
   ...: df.head()
Out[4]:
   MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude  MedHouseVal
0  8.3252      41.0  6.984127   1.023810       322.0  2.555556     37.88    -122.23        4.526
1  8.3014      21.0  6.238137   0.971880      2401.0  2.109842     37.86    -122.22        3.585
2  7.2574      52.0  8.288136   1.073446       496.0  2.802260     37.85    -122.24        3.521
3  5.6431      52.0  5.817352   1.073059       558.0  2.547945     37.85    -122.25        3.413
4  3.8462      52.0  6.281853   1.081081       565.0  2.181467     37.85    -122.25        3.422

以上でデータ準備は完了です。

2. 無作為抽出(Random Sampling) – 基礎編

さて、本題の無作為抽出 (Raddom Sampling) を行なってみようと思います。以下がAPI docです。

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.sample.html

非常に簡単で、.sample() を使用するだけでランダムサンプリングができてしまいます。

a. 1レコード取得

まず、1レコードを取得してみようと思います。引数のrandom_state=0は、乱数シードを0で固定しています。

In [5]: df.sample(random_state=0)
Out[5]:
       MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude  MedHouseVal
14740  4.1518      22.0  5.663073   1.075472      1551.0  4.180593     32.58    -117.05        1.369

次に、先ほど設定した同じ乱数シード0で、実行すると同じレコードが取得されることが確認できます。

In [6]: df.sample(random_state=0)
Out[6]:
       MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude  MedHouseVal
14740  4.1518      22.0  5.663073   1.075472      1551.0  4.180593     32.58    -117.05        1.369

b. 複数レコード取得

では、複数レコードをサンプリングしてみます。今回は、5レコード取得してみようと思います。random_stateは先ほどとは別の値を設定します。

In [7]: df.sample(5, random_state=1)
Out[7]:
       MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude  MedHouseVal
4712   3.2500      39.0  4.503205   1.073718      1109.0  1.777244     34.06    -118.36        3.550
2151   1.9784      37.0  4.988584   1.038813      1143.0  2.609589     36.78    -119.78        0.707
15927  4.0132      46.0  4.480296   1.012315      1534.0  3.778325     37.73    -122.42        2.294
82     1.5208      52.0  3.908046   1.114943       200.0  2.298851     37.81    -122.28        1.125
8161   5.1795      37.0  5.406360   1.024735       711.0  2.512367     33.82    -118.13        2.254

もちろん同じrandom_stateを指定すれば同じdatasetが取得できます。

In [8]: df.sample(5, random_state=1)
Out[8]:
       MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude  MedHouseVal
4712   3.2500      39.0  4.503205   1.073718      1109.0  1.777244     34.06    -118.36        3.550
2151   1.9784      37.0  4.988584   1.038813      1143.0  2.609589     36.78    -119.78        0.707
15927  4.0132      46.0  4.480296   1.012315      1534.0  3.778325     37.73    -122.42        2.294
82     1.5208      52.0  3.908046   1.114943       200.0  2.298851     37.81    -122.28        1.125
8161   5.1795      37.0  5.406360   1.024735       711.0  2.512367     33.82    -118.13        2.254

同じdatasetであることが確認できますね。

3. 無作為抽出(Random Sampling) – 比率で取得

では、RCTが行える際なのに、Treatment group, Control group作成の際によく使用する、比率での抽出を行なってみようと思います。その前に、レコード数を見てみようと思います。

In [9]: df.shape
Out[9]: (20640, 9)

20,640レコード格納されていることが確認できました。

では、比率を指定することで無作為抽出 (Random Sampling) してみようと思います。まずは、frac=.5を指定することで、50% (10,320件)のレコードを取得してみようと思います。

In [10]: df_t = df.sample(frac=.5, random_state=2)
    ...: df_t
Out[10]:
       MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup  Latitude  Longitude  MedHouseVal
10385  6.4114      15.0  7.527559   1.049869      2529.0  3.318898     33.60    -117.65        2.787
1943   4.1843      12.0  6.330084   1.041783      2033.0  2.831476     38.62    -120.91        2.076
7490   1.7411      35.0  5.369159   1.294393       909.0  4.247664     33.93    -118.23        0.967
16889  3.4412      39.0  4.173405   1.074573      2156.0  1.937107     37.59    -122.37        3.538
11416  7.8195      16.0  8.602349   1.058725      2142.0  3.593960     33.70    -117.98        3.905
...       ...       ...       ...        ...         ...       ...       ...        ...          ...
11141  3.7500      19.0  4.473146   1.038363       969.0  2.478261     33.84    -117.95        1.734
6202   3.8837      32.0  5.559719   1.053864      1580.0  3.700234     34.07    -117.89        2.003
2220   6.1175      16.0  7.567282   0.992084      1016.0  2.680739     36.83    -119.82        1.447
14556  7.6348       4.0  6.534079   1.060020      2607.0  2.652085     32.98    -117.24        3.370
2137   2.6767      15.0  4.512448   1.170124      1194.0  2.477178     36.81    -119.72        0.875

[10320 rows x 9 columns]

まとめ

ということで、今回はPython – 無作為抽出(Random Sampling)について記載しました。個人的には、API docに記載されている引数の指定のバリエーションを全て使用することはあまりないので、記載していませんが、時間のある時にAPI docを見てみてもよいかと思います。

(Visited 14 times, 1 visits today)