python, R, vimでデータマイニング

python, R, vim で疑問に思ったことなどを

WEBアプリ作成のためのお勉強

WEBアプリが作りたくなり、お勉強を始めた

はじめはFLASKなどを勉強しようかと思ったが他にも便利そうなフレームワークが多くFLASKは後回しになりそう。

とにかく初学者なのでどんなものがあるかを調べるだけでも便利そうなものが多く見つかるので楽しい。

難しそうかなと思っていたものも大抵のものはサービスとして提供されているのでそれらを組み合わせるだけで自分が作りたいもの程度ならそれほど苦労せずできそう。

 

勉強しそうなリスト

  • firebase 特に認証とストレージ
  • 課金 エスクローサービス
  • node.js
  • Express
  • bootstrap
  • FLASK

R: ps package R install error : ERROR: moving to final location failed

タイトルのエラーでパッケージのインストールに手間取りました。

回答にもなかなかたどり着けなかったので備忘録として

 

https://stackoverflow.com/questions/14382209/r-install-packages-returns-failed-to-create-lock-directory

 

R CMD INSTALL --no-lock <pkg>

これでうまくいきました。

 

ひょっとしたら下記でも成功するのかもしれません。

install.packages("Rcpp", dependencies=TRUE, INSTALL_opts = c('--no-lock'))

 

--no-lockの挙動が全く理解できていなのですが、あくまで備忘録として今日はここまで

 

cross_val_predictで足りない機能を追加

1. 足りない機能

cross_val_predictを良く使用します。
ただ足りないと思う機能が一つあります。
各FOLD毎に構築したestimatorを取得したいのですが
そのような機能がなさそうです。
仕方がないので実作の関数を作成しました。

2. cross_val_classifier

from utils4ml.sklearnwrappers import cross_val_classifier

3. 使用例

predictedとestimatorのリストを取得できます。

Code:
# %%
import numpy as np
import pandas as pd
from lightgbm import LGBMClassifier
from utils4ml.utils import load_bank_classifier
from utils4ml.sklearnwrappers import cross_val_classifier

X, y = load_bank_classifier()
y = y.cat.codes
predicted, estimators = cross_val_classifier(
    LGBMClassifier(),
    X,
    y,
)
# %%

4. estimatorsの適用

別データにestimatorsを適用します。

Code:
# %%
predicted_others = [
    e.predict_proba(X)
    for e in estimators
]
predicted_other = np.mean(
    predicted_others,
    axis=0,
)
predicted_other = pd.DataFrame(predicted_other)
predicted_other.head().to_csv(
    'output/predicted_other.csv'
)
# %%
Table 1. Result:
  0 1

0

0.9872150068879645

0.012784993112035726

1

0.9833755317309659

0.016624468269033875

2

0.9958059169918817

0.004194083008118234

3

0.9965370372207216

0.0034629627792783267

4

0.9981163874399529

0.0018836125600472052

count encodingの実装

データフレーム全体に対してCount Encodingするパッケージを作成しました。

別データに適用することも考慮して

変換テーブルの役割の辞書を作成する関数

上記を適用する関数に分けました。

create_count_encoding_dicts

apply_encode_dicts

 

以下 README

 

3. utils4ml.encoding

Utilities for encoding.

3.1. create_count_encoding_dicts

Create count encoding for pd.DataFrame.

3.1.1. Usage

from utils4ml.encoding import create_count_encoding_dicts

3.1.2. Definition

def create_count_encoding_dicts(
    X: Union[pd.DataFrame, pd.Series],
) -> Dict[str, Dict[str, int]]:

3.1.3. Example

Code:
# %%
import json
from utils4ml.encoding import create_count_encoding_dicts
from utils4ml.encoding import apply_encode_dicts

from utils4ml.utils import load_bank_classifier

X, y = load_bank_classifier()
Xcat = X.select_dtypes(include="category")

encoding_dicts = create_count_encoding_dicts(Xcat)
X_encoded = apply_encode_dicts(
    Xcat,
    encoding_dicts
)
json.dump(
    encoding_dicts,
    open("output/encoding_dicts.json", "w"),
    indent=4
)
X_encoded.head(10).to_csv("output/X_encoded.csv")
# %%
Result: encoding_dicts.json
{
    "job": {
        "management": 969,
        "blue-collar": 946,
        "technician": 768,
        "admin.": 478,
        "services": 417,
        "retired": 230,
        "self-employed": 183,
        "entrepreneur": 168,
        "unemployed": 128,
        "housemaid": 112,
        "student": 84,
        "unknown": 38
    },
    "marital": {
        "married": 2797,
        "single": 1196,
        "divorced": 528
    },
    "education": {
        "secondary": 2306,
        "tertiary": 1350,
        "primary": 678,
        "unknown": 187
    },
    "default": {
        "no": 4445,
        "yes": 76
    },
    "housing": {
        "yes": 2559,
        "no": 1962
    },
    "loan": {
        "no": 3830,
        "yes": 691
    },
    "contact": {
        "cellular": 2896,
        "unknown": 1324,
        "telephone": 301
    },
    "month": {
        "may": 1398,
        "jul": 706,
        "aug": 633,
        "jun": 531,
        "nov": 389,
        "apr": 293,
        "feb": 222,
        "jan": 148,
        "oct": 80,
        "sep": 52,
        "mar": 49,
        "dec": 20
    },
    "poutcome": {
        "unknown": 3705,
        "failure": 490,
        "other": 197,
        "success": 129
    }
}

3.2. apply_encode_dicts

apply encoding_dicts for pd.DataFrame.

3.2.1. Usage

from utils4ml.encoding import apply_encode_dicts

3.2.2. Definition

def apply_encode_dicts(
    X: Union[pd.DataFrame, pd.Series],
    encode_dicts: Dict[str, Dict[str, int]],
    suffix: str='',
    fillna: int=1,
) -> pd.DataFrame:

3.2.3. Example

Code:
# %%
import json
from utils4ml.encoding import create_count_encoding_dicts
from utils4ml.encoding import apply_encode_dicts

from utils4ml.utils import load_bank_classifier

X, y = load_bank_classifier()
Xcat = X.select_dtypes(include="category")

encoding_dicts = create_count_encoding_dicts(Xcat)
X_encoded = apply_encode_dicts(
    Xcat,
    encoding_dicts
)
json.dump(
    encoding_dicts,
    open("output/encoding_dicts.json", "w"),
    indent=4
)
X_encoded.head(10).to_csv("output/X_encoded.csv")
# %%
Table 6. Result: X_encoded.csv
  job marital education default housing loan contact month poutcome

0

128

2797

678

4445

1962

3830

2896

80

3705

1

417

2797

2306

4445

2559

691

2896

1398

490

2

969

1196

1350

4445

2559

3830

2896

293

490

3

969

2797

1350

4445

2559

691

1324

531

3705

4

946

2797

2306

4445

2559

3830

1324

1398

3705

5

969

1196

1350

4445

1962

3830

2896

222

490

6

183

2797

1350

4445

2559

3830

2896

1398

197

7

768

2797

2306

4445

2559

3830

2896

1398

3705

8

168

2797

1350

4445

2559

3830

1324

1398

3705

9

417

2797

678

4445

2559

691

2896

293

490

lightgbmの変数の重要度を取得する関数

1. 概要

モデル構築後に変数の重要度を確認することが多いので関数化しました。
学習済みのestimatorを与えると重要度テーブルがデータフレームで返されます。
utils4mlという自作パッケージを作成中でそこに取り込んでいます。

2. 使用例

Code:
# %%
import pandas as pd
from lightgbm import LGBMClassifier
from utils4ml.lgbwrappers import create_importance_df
from utils4ml.utils import load_bank_classifier

X, y = load_bank_classifier()
clf = LGBMClassifier()
clf.fit(X, y)
importance_df = create_importance_df(clf)
importance_df.to_csv('output/importance_df.csv')
# %%
Table 1. Result:
  feature_name importance

12

duration

4840.519355148077

10

balance

1412.680456519127

11

day

1380.2339130043983

9

age

1188.5334162265062

8

poutcome

1144.403927654028

7

month

720.7538131475449

14

pdays

687.5430861711502

6

contact

555.3039375543594

13

campaign

463.4079278707504

1

marital

300.297524869442

2

education

289.3929640054703

4

housing

204.38219678401947

15

previous

162.35857447981834

5

loan

135.40583151578903

0

job

126.77435421943665

3

default

30.483178555965424

loadbank:検証用データを作成するパッケージを作成しました。

loadbankパッケージを作成しました。

1. 概要

自作のパッケージを作成していると検証用のテストデータが必要になります。
都度テストデータを作成していると非効率なのでパッケージを作成しました。
私が自作しているパッケージはClassifierとRegressorを統一的に扱えることを基本方針としています。
そのため上記2種類用のデータをロード出来るように実装します。

2. 基データ

bank.csvは一般公開されている銀行のマーケティングデータです。
Classifier用のデータですが目的変数を変更することでRegressorにも対応出来るようにします。
このデータは欠損値がなく、カテゴリ型と数値型の変数が混在していてテストに適したデータです。
対象のデータは下記から取得できます。
Bank Marketing Data Set

3. データ作成方針

データはpandasのDataFrameかSeriesとして作成します。
XはDataFrame,yはSeriesとして作成します。
Regressor用の目的変数はamountとします。
カテゴリ変数(文字列)はcategory型に変換します。

4. パッケージの使用例:データ作成

Code:
# %%
from loadbank import load_bank_classifier
from loadbank import load_bank_regressor

Xclf, yclf = load_bank_classifier()
Xreg, yreg = load_bank_regressor()
# %%

5. LGBMClassifierでモデルを作成して精度を見てみる。

yはカテゴリ型なのでbinary型に変換が必要です。

Code:
# %%
import numpy as np
from lightgbm import LGBMClassifier
from sklearn.model_selection import cross_val_score

clfscore = cross_val_score(
    LGBMClassifier(),
    Xclf,
    yclf.cat.codes,
    scoring='roc_auc',
)
print(np.mean(clfscore))
# %%

roc_auc: CV=3:
= 0.9032143788207457

6. LGBMRegressorでモデルを作成して精度を見てみる。

Code:
# %%
from lightgbm import LGBMRegressor

regscore = cross_val_score(
    LGBMRegressor(),
    Xreg,
    yreg,
    scoring='neg_mean_squared_error',
)
print(np.sqrt(np.mean(regscore * -1)))
# %%

RMSE: CV=3:
= 3102.8162007396186

7. パッケージ化

パッケージ化してgithubに公開しています。
https://github.com/kanosuke/loadbank