PlotlyExpressどの程度使えるものなのか?私なりに検証してみた。

この記事の目的

EDA(探索的データ解析)を行う際PlotlyExpressが「どんなケースで使用することができるのか?」について私なりに検証してみました。

PlotlyExpressとは?

plotlyのラッパーになります。 plotlyとはオープンソースインタラクティブなデータ可視化ツールです。 Python, R, javascript言語対応です。 ラインセンスはMIT。

PlotlyExpressとPlotlyの違いはどこ?PlotlyExpressにメリットがあるのか?

散布図と箱ひげ図をそれぞれで出力してみて比較してみた。

import 関係

import plotly.offline as offline
import plotly.graph_objs as go
import pandas as pd

google colabeでplotlyを表示するための処理

import plotly

# google colab内で実行するには以下関数の実行が必要
def configure_plotly_browser_state():
  import IPython
  display(IPython.core.display.HTML('''
        <script src="/static/components/requirejs/require.js"></script>
        <script>
          requirejs.config({
            paths: {
              base: '/static/base',
              plotly: 'https://cdn.plot.ly/plotly-latest.min.js?noext',
            },
          });
        </script>
        '''))

configure_plotly_browser_state()

# jupyter notebookで表示する際に使う
plotly.offline.init_notebook_mode(connected=False)

データセット読み込み

import pybaseball as pb
# MLB Advanced Mediaからデータを抜くためのID
key = pb.playerid_lookup("Syndergaard", "Noah")["key_mlbam"].values[0]

# データがpandas.DataFrameで返ってきます
data = pb.statcast_pitcher("2015-01-01", "2019-12-31", key)

# データ整形
# 投球日・イニング・投球数でソート
data = data.sort_values(["game_date", "inning", "at_bat_number", "pitch_number"])
# 球種データがNaNの場合は行ドロップ
data = data.dropna(subset=['pitch_type'])

data["seq"] = data.reset_index().index

比較1:散布図

plotly_expressの場合=3行

import plotly_express as px
configure_plotly_browser_state()
px.scatter(data, x="seq", y="release_speed", color="pitch_type")

f:id:kobakenkken:20191217235907p:plain

plotlyの場合=だいたい21行

"pitch_type"の種類を把握する

data["pitch_type"][~data["pitch_type"].duplicated()]

11725    FF
11722    CU
11718    SI
11717    CH
11708    IN
11003    SL
10931    FT
8467     PO
Name: pitch_type, dtype: object
FF_df = data[data["pitch_type"] == "FF"]
CU_df = data[data["pitch_type"] == "CU"]
SI_df = data[data["pitch_type"] == "SI"]
CH_df = data[data["pitch_type"] == "CH"]
IN_df = data[data["pitch_type"] == "IN"]
SL_df = data[data["pitch_type"] == "SL"]
FT_df = data[data["pitch_type"] == "FT"]
PO_df = data[data["pitch_type"] == "PO"]
trace = go.Scatter(
        x = FF_df["seq"],
        y = FF_df["release_speed"],
        name='FF',
        mode = "markers"
        )
trace1 = go.Scatter(
        x = SI_df["seq"],
        y = SI_df["release_speed"],
        name='SI',
        mode = "markers"
        )
trace2 = go.Scatter(
        x = CH_df["seq"],
        y = CH_df["release_speed"],
        name='CH',
        mode = "markers"
        )
trace3 = go.Scatter(
        x = IN_df["seq"],
        y = IN_df["release_speed"],
        name='IN',
        mode = "markers"
        )
trace4 = go.Scatter(
        x = SL_df["seq"],
        y = SL_df["release_speed"],
        name='CU',
        mode = "markers"
        )
trace5 = go.Scatter(
        x = FT_df["seq"],
        y = FT_df["release_speed"],
        name='FT',
        mode = "markers"
        )

trace6 = go.Scatter(
        x = PO_df["seq"],
        y = PO_df["release_speed"],
        name='PO',
        mode = "markers"
        )

layout = go.Layout(
        xaxis=dict(title='seq'),
        yaxis=dict(title='release_speed'),
        showlegend=False)

fig = dict(data=[trace, trace1, trace2, trace3, trace4, trace5, trace6], layout=layout)

# グラフを描画
configure_plotly_browser_state()
plotly.offline.iplot(fig)

比較2 箱ひげ図

plotly_expressの場合:約2行

configure_plotly_browser_state()
px.box(data, x="pitch_type", y="release_speed")

f:id:kobakenkken:20191218000305p:plain

plotlyの場合:約9行

fig = go.Figure()
fig.add_trace(go.Box(
        y = FF_df["release_speed"],
        name='FF'
        ))
fig.add_trace(go.Box(
        y = SI_df["release_speed"],
        name='SI'
        ))
fig.add_trace(go.Box(
        y = CH_df["release_speed"],
        name='CH'
        ))
fig.add_trace(go.Box(
        y = IN_df["release_speed"],
        name='IN'
        ))
fig.add_trace(go.Box(
        y = SL_df["release_speed"],
        name='CU'
        ))
fig.add_trace(go.Box(
        y = FT_df["release_speed"],
        name='FT'
        ))

fig.add_trace(go.Box(
        y = PO_df["release_speed"],
        name='PO'
        ))

# グラフを描画
configure_plotly_browser_state()
plotly.offline.iplot(fig)

f:id:kobakenkken:20191218000423p:plain

まとめと反省

基本的にplotly_expressを中心に用い、plotly_expressで出来ない場合や時間を要する場合はplotlyや他のライブラリを使用するのが楽かなと感じました。

反省:言い訳になるのですが、結婚式や家族での出来事など怒涛の一か月で準備が全然時間とれませんでした。来年はきちんと締め切り守ります。よろしくお願いいたします。

参考

qiita.com

qiita.com

G検定を受けてみて(勉強法,攻略法など)

なぜ受験したのか

私が受験した理由は、

  1. 仕事で持っていると社内の人やお客さんが私について理解しやすいのではないかって思った

  2. 大学院時代の知識を振り返ることや、体系的にしっかり勉強し直しておこうかなと

  3. 年間1つは何か資格のような業務外での目標を立て実行するためとか

  4. 会社から受験料などを出してもらえるから

様々な理由からでした。

勉強内容&方法について

受験日は2019/11/9です。

  1. 2019年のだいたい9月~10月くらいまでに白本を読む https://www.amazon.co.jp/dp/4798157554/ref=cm_sw_r_tw_dp_U_x_0lTXDb4JA29XR

  2. 10月~受験日前日の朝まで、毎日約20~30分 黒本の問題を解く https://www.amazon.co.jp/dp/4295005665/ref=cm_sw_r_tw_dp_U_x_zsTXDbPTBHFSW

  3. 受験までにStudyAiさんの模擬試験を受験し、間違えた箇所を覚えなおす (3周くらい※3周すると、もはや暗記してしまいます...) study-ai.com

  4. 初めまして単語集を作りながら勉強しました。

  5. 畳み込み演算や行列の演算の問題が出題されるらしく、手で解くのは面倒なのでプログラムにして数値だけ入力して計算結果を出すようにしておきました。

受験してみて(この検定に感じた価値)

G検定は結構マイナス的な意見を述べる方もいますが、実際に勉強&受験してみて感じたことはこれまでの知識の振り返りや確認にはとてもなりました。 今後、どのような仕事の場面で活きてくるかは正直はっきり見えないことが多いですが、DLや機械学習を知りたい人にとっては良い指標になると感じました。 具体的な内容として初めましてなものは、時事問題でした。あまりしっかり把握していないことが多かったので、このあたりはしっかり追うべきだったと反省しています。

今後、G検定も受けてみたい気持ちはありますが、私の会社では事前に受ける認定プログラムがまだ実費らしく時間と金額のコスパを考えて今は保留中です。

以上、受験してみての感想などの備忘録でした。

リッジ、ラッソ、SGD回帰をsklearnでやってみた

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from sklearn import model_selection, preprocessing, linear_model
import sklearn
sklearn.__version__

#dataset load
df=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data', header=None, sep='\s+')
df.columns=['CRIM','ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']
X_rm=df[['RM']].values
X=df.iloc[:, 0:13]
#X=df[['AGE']].values
Y=df['MEDV'].values

#整形
sc=preprocessing.StandardScaler()
sc.fit(X)
X=sc.transform(X)

#学習データとテストデータ分割
X_train, X_test, Y_train, Y_test = model_selection.train_test_split(X, Y, test_size=0.2, random_state=0)

#SGD Regressor
clf = linear_model.SGDRegressor(max_iter=1000)
clf.fit(X_train, Y_train)

#Lasso Regressor------------------------------------------
clf_lasso= linear_model.Lasso(alpha=0.5)
clf_lasso.fit(X_train, Y_train)

# Ridge Regressor------------------------------------------
clf_ridge= linear_model.Ridge(alpha=0.5)
clf_ridge.fit(X_train, Y_train)

print("SGDの係数")
print(clf.intercept_) 
print(clf.coef_)

print("\nLassoの係数")
print(clf_lasso.intercept_) 
print(clf_lasso.coef_) 

print("\nRidgeの係数")
print(clf_ridge.intercept_) 
print(clf_ridge.coef_) 

#テストデータでの誤差比較
Y_pred=clf.predict(X_test)
Y_lasso_pred=clf_lasso.predict(X_test)
Y_ridge_pred=clf_ridge.predict(X_test)

RMS = np.mean((Y_pred - Y_test) ** 2)
RMS_lasso=np.mean((Y_lasso_pred - Y_test) ** 2)
RMS_ridge = np.mean((Y_ridge_pred - Y_test) ** 2)

print("SGD RMSE", RMS)
print("Lasso RMSE", RMS_lasso)
print("Ridge RMSE", RMS_ridge)
SGDの係数
[22.50529262]
[-0.96926518  0.94949489 -0.14527762  0.63794958 -1.6346609   2.68994304
 -0.14346678 -2.84697474  1.62848272 -1.29629315 -2.19507166  0.72119816
 -3.44826026]

Lassoの係数
22.551646497220098
[-0.2022351   0.         -0.          0.34586306 -0.          2.85095977
 -0.         -0.         -0.         -0.24202672 -1.99201487  0.41276179
 -3.49325645]

Ridgeの係数
22.480943943558106
[-1.02136951  1.03522818  0.02450249  0.59611373 -1.84847657  2.6082378
 -0.0912668  -2.89943172  2.08520461 -1.815872   -2.25741944  0.73956343
 -3.5082977 ]

SGD RMSE 33.38872967589145
Lasso RMSE 39.80131790956071
Ridge RMSE 33.49305020158983

pythonで、時系列データを用いて教師あり学習を行うための学習データ作成方法

時系列データを用いて教師あり学習を行うための学習データの作成のための考え方

多変量の時系列データを用いて、教師あり学習によって、ある目的変数のt分後の値の推測したい場合の学習データの作成方法をまとめたいと思います。

この一般的な方法としては、時刻tを基準とし、目的変数の値のみを時刻t +1とシフトさせる方法がとられています。

具体的なpythonを用いた手順を以下に示します。 目的変数:TARGET, 説明変数:A,B,C の乱数時系列データを作成します。

import numpy as np
import pandas as pd
data = np.random.randn(10, 4)# 10x4 の乱数データを生成
indices = pd.date_range('2010-01-01', periods=10)  # インデックス名は日付
columns = ('A', 'B', 'C', 'TARGET')  # カラム名

my_dataframe = pd.DataFrame(data, index=indices, columns=columns)
print(my_dataframe)

out>>
                   A         B         C    TARGET
2010-01-01 -1.874536  0.044969  0.077942  0.089603
2010-01-02 -0.922576 -0.778048  0.883617 -0.709655
2010-01-03 -0.481583  0.987507  1.120371 -0.466234
2010-01-04  0.055468 -2.080869 -0.558581 -0.235064
2010-01-05  1.033512 -0.750830 -0.754168  1.090878
2010-01-06 -0.566832  0.201503 -0.264602 -0.003537
2010-01-07  1.890769  1.358429 -1.041281  0.438978
2010-01-08 -0.175302 -1.191327 -0.457195 -0.287566
2010-01-09  1.672760  0.094620  1.225835 -0.147332
2010-01-10  2.042621 -2.651269 -1.356004 -0.066129

次に目的変数(TARGET)の値を一日ずらします。 例えば2010-01-02の値は、2010-01-01へずらされます。

my_dataframe['TARGET'] = my_dataframe['TARGET'].shift(-1)
my_dataframe

out>>
    A   B   C   TARGET
2010-01-01   -1.874536  0.044969   0.077942   -0.709655
2010-01-02   -0.922576  -0.778048  0.883617   -0.466234
2010-01-03   -0.481583  0.987507   1.120371   -0.235064
2010-01-04   0.055468   -2.080869  -0.558581  1.090878
2010-01-05   1.033512   -0.750830  -0.754168  -0.003537
2010-01-06   -0.566832  0.201503   -0.264602  0.438978
2010-01-07   1.890769   1.358429   -1.041281  -0.287566
2010-01-08    -0.175302  -1.191327  -0.457195  -0.147332
2010-01-09    1.672760   0.094620   1.225835   -0.066129
2010-01-10   2.042621   -2.651269  -1.356004  NaN

このように目的変数の値を推測したい時刻の値へずらすことで教師あり学習のための学習データを作成します。