論文の読み方・書き方
グラム先生のチュートリアル資料「国際会議論文の読み方・書き方」
http://www.phontron.com/slides/neubig15nlptutorial.pdf
「論文の読み方・書き方」改め ArXiv時代の論文の読み方 こう書くと落ちる論文の書き方
集計の軸を探す方法
下記資料から抜粋。
speakerdeck.com
仮説と集計結果が異なる場合、取るアプローチ。
因果推論で探す
共変量の影響を除外して目的変数への影響を知りたい。
傾向スコア等を用いて観測できない集団を推定する。
前提に置く仮定が強すぎて実務上使いにくい気がする。
BigQueryでのGA360データ利用
やりたいこと
- GA360と連携されたBigQuery(以下BQ)でカスタムディメンションの集計
- 対象テーブルを動的にする
(平日のみ実行。月曜は金土日を対象、それ以外の平日は前日を対象として抽出)
前提
このエントリで説明しないこと。
- GA360とBQの連携の仕方
- カスタムディメンション設定
- BQは標準SQLに設定
さらにそもそもってレベルだと、
- GCPアカウントの用意
- プロジェクト作成済みであること
- プロジェクトでBQを有効にしていること
。。。とか他にもあるかもしれないけど、BQ使えるのが前提ってことです。
まずカスタムディメンション集計
LondonCycleHelmetのサンプルテーブルを使います。
ネストされたデータであるカスタムディメンションをフラットにして、インデックス1と2の組み合わせをセッション集計したいとき。
SELECT PARSE_DATE('%Y%m%d', date) AS date ,(SELECT MAX(IF(index=1, value, NULL)) FROM UNNEST(hits.customDimensions)) AS dimension1 ,(SELECT MAX(IF(index=2, value, NULL)) FROM UNNEST(hits.customDimensions)) AS dimension2 ,COUNT(DISTINCT CONCAT(fullVisitorId, SAFE_CAST(visitNumber AS STRING))) as sessions FROM `google.com:analytics-bigquery.LondonCycleHelmet.ga_sessions_20130910`, UNNEST(hits) AS hits GROUP BY 1, 2, 3
カスタムディメンションはhitsをUNNESTしたうえで、SELECTでもサブクエリ書くんですね。
BQ使ってなかったから知らんかった。
さらにテーブルを動的に変える場合
このサンプルデータは2013年9月10日テーブルしかないけど、GA360連携していれば日々、日次テーブルが追加されていく。
例えば、クエリ実行の曜日によって対象テーブルを動的に変えたいときなどがある。
- 平日のみ実行
- 月曜は金土日、それ以外は前日を対象にしたい
※下記のクエリはテーブルが1日分しかないので動きません
SELECT PARSE_DATE('%Y%m%d', date) AS date ,(SELECT MAX(IF(index=1, value, NULL)) FROM UNNEST(hits.customDimensions)) AS dimension1 ,(SELECT MAX(IF(index=2, value, NULL)) FROM UNNEST(hits.customDimensions)) AS dimension2 ,COUNT(DISTINCT CONCAT(fullVisitorId, SAFE_CAST(visitNumber AS STRING))) as sessions FROM `google.com:analytics-bigquery.LondonCycleHelmet.ga_sessions_*`, UNNEST(hits) AS hits WHERE _TABLE_SUFFIX BETWEEN REPLACE(CAST(DATE_SUB(CURRENT_DATE, INTERVAL IF(EXTRACT(DAYOFWEEK FROM CURRENT_DATE)=2, 3, 1) day) AS string), '-', '') AND REPLACE(CAST(DATE_SUB(CURRENT_DATE, INTERVAL 1 day) AS string), '-', '') GROUP BY 1, 2, 3 ORDER BY 1
FROMで参照するテーブルの日付を*にして、WHEREでその条件を書く。
参考サイト
エクスチュアのグレートなテックブログ。
エクスチュアCTOの権さん、しゅごい…
https://ex-ture.com/blog/2017/12/13/unnest-ga360-bq-data-with-standardsql/
ex-ture.com
pipとconda
pipとcondaとはなにか?
pipはPython標準のパッケージ管理ツールでPyPIからインストールする。
condaはAnacondaのパッケージ管理ツールでAnaconda社が提供するレポジトリからパッケージをインストールする(だからPyPIにはあるけどAnacondaにはない場合がある)。
pip intallとconda installの違いはなにか?
conda installとpip installではbuildする場所が違う。
- conda installではすでにどこかでbuildされたpackageをfetchするだけ。
- pip installはlocalの実行環境と互換のあるwheel(Python のパッケージング形式。実態はzip形式のアーカイブ。PEP427で定義。)を取得した後、localの実行環境でsetup.pyを実行してbuildしている。
buildするタイミングでlocalの実行環境に合うようライブラリが最適化される。つまり、
- conda installされたライブラリはlocalの実行環境で最適化されているとは言えない。
- pip installされたライブラリはlocalの実行環境で高性能を発揮できるよう最適化されている。
つまりpipのほうが実行時間が短くなる場合がある。
どっち使えばいいの?
どちらでもいい。
ただし、併用は厳禁らしい。
なぜならパッケージの仕組みが全くことなり、condaは複数の仮想環境下でディスクの使用量を節約するため、ハードリンクを駆使している。
これによりcondaパッケージをpipパッケージで上書きした場合に環境まるごと壊れる可能性がでてくる。
onoz000.hatenablog.com
なんでこんなことになったのか?
pipとcondaの経緯はこの記事が詳しい。
ymotongpoo.hatenablog.com
pandas操作⑧:queryに変数を指定する場合
xgboost:エラー編
RandomForestのグリッドサーチと同じようにxgboostでもやろうとした。
下記はmax_depthとmin_child_weightのみを使ったグリッドサーチ。
X_train, X_test, y_train, y_testはpandas。
GridSearchCVのパラメーターは今回の話に関係ないから無視してよい。
from xgboost.sklearn import XGBClassifier from sklearn.grid_search import GridSearchCV from sklearn.cross_validation import train_test_split X_train, X_test, y_train, y_test = train_test_split( variables, targets, random_state=666) param_test2 = { 'max_depth':[5,7,9], 'min_child_weight':[1,3,5] } gsearch2 = GridSearchCV(estimator = XGBClassifier(learning_rate=0.1, n_estimators=1000, max_depth=5, min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test2, scoring='roc_auc',n_jobs=-1,iid=False, cv=5) gsearch2.fit(X_train,y_train)
するとgsearch2.fit(X_train,y_train)部分で下記エラー。
IndexError: too many indices for array
どうもy_trainの次元が多いようだ。
ということはpandasでダメってことだろうから、一次元配列にすればいいのだろうなというのがわかるので、下記のように変えてると動く。
gsearch2.fit(X_train,y_train.as_matrix().reshape(-1,))
というか、なんでRandom Forestで動いてるのにxgboostで動かないのだ。
実装違うのかよ、と思ったが、
from xgboost.sklearn import XGBClassifier
とあるので勘違いしていたが、そもそもxgboostはsklearnではないので当然実装は違う。
tree系はターゲットが一次元配列でなくてもよいようだ。
https://github.com/scikit-learn/scikit-learn/blob/f0ab589f/sklearn/ensemble/forest.py#L230
y : array-like, shape = [n_samples] or [n_samples, n_outputs]
一方、xgboostはソースの記述だけではわからないw
https://github.com/dmlc/xgboost/blob/master/python-package/xgboost/sklearn.py#L500
y : array_like
pandas操作⑦:列表示
列が省略されるときに全表示させたい
デフォルトは20らしいので好きな数値に変更する。
# pandasの表示列数設定 pd.set_option('display.max_columns',65)
レコード毎にmaxの列番号を抽出したい
最大値の列番号をmax列に突っ込む。
# DataFrameでレコード毎に最大値の列番号を抽出 # dfは使いたいデータフレームという前提 df['max'] = df.idxmax(axis = 1)
任意のカラムでカウント(Group byでカウントのイメージ)
# 上記の最大値の列番号をmax列に入れたときのカウント df["max"].value_counts()
列の名前を変更したい
上記で作ったmax列の名前をcluster_idという名称に変更したい。
# 元のデータフレームに変更を反映しない場合 df = df.rename(columns = {'max':'cluster_id'}) # 元のデータフレームに変更を反映する場合 df = df.rename(columns = {'max':'cluster_id'}, inplace = True)