いっきのblog

技術とか色々

Think Stats(第2版)を読む:2章

前回の続き。

kzkohashi.hatenablog.com

2章: ヒストグラム

分析する上で、データ全体の傾向だったり、方針を決める際には必ずと言ってやると思われるデータの可視化。その中で、データの分布をみるためのヒストグラムについて書かれた章。

ヒストグラムの表現

オリジナルの関数を使って、簡単なヒストグラムを表現している。

f:id:kzkohashi:20180418202317p:plain

コードを読んで見ると、よく使われているmatplotlibで描画されている。

import matplotlib.pyplot as plt

...

plt.bar(xs, ys, **options)

少し味気ないので、最近知り合いが使っていたseabornを使って同じように描画して見る。

import seaborn as sns
import matplotlib
matplotlib.rcParams['font.family'] = 'AppleGothic'
%matplotlib inline
import matplotlib.pyplot as plt

plt.figure(figsize=(20,8))
g = sns.countplot(x=[1,2,2,3,5],order=[1,2,3,4,5])
g.set_xticklabels(g.get_xticklabels(), rotation=90)

こんな感じに綺麗な描画にできる。

f:id:kzkohashi:20180418202328p:plain

外れ値

データと見て行く際に、必ずと言っていいほど外れ値と呼ばれる他の値とは離れているものがある。まずは傾向を見るのが目的の場合は、こういうのを除外したりすることで分析をしやすくしたりする。 例えばこの例で見ると

f:id:kzkohashi:20180418202506j:plain

30週未満や50週以上あたりのデータは少しおかしいデータだったりする。どのように分析するかにもよるけど、基本的には分析しているドメイン領域の専門知識がないと判断しづらいため、自分で知識を深めるか知識がある人にこの値はどういう意味を何しているのかを答えてもらい、その上でそのデータを切るかの判断をするのがいいんじゃないかなと思う。

分布を要約する

何かと何かの値を比べる際に、標本のサイズなどを意識する必要がある。100人のデータと1000人のデータだと、当たり前だけど1000人のデータの方が値が大きくなったりする。
そういった調べたい分布を要約するときによく使われるのが以下である。

  • 中心傾向(central tendency)
    • あたいは特定の周りに集まっているか?
  • 最頻値(modes)
    • 塊は複数あるか?
  • 散らばり(spred)
    • あたいの変動はどの程度か?
  • 裾(tails)
    • 最頻値から離れると確率がどれくらい下がるか?
  • 外れ値(outliers)
    • 最頻値から離れた極値があるか?

これらの答える統計量は、要約統計量(記述統計量)と言われる。
一番よく使われるのは算術平均で、分布の中心傾向の記述をして用いられる。
meanaverageは日本語だと同じ意味だけど、わけて使われるのでメモっておく。

  • 標本の算術平均(mean)
  • 代表値(average)は中心傾向の記述に選ばれるようやく統計量のうちの一つ

参考

bellcurve.jp

分散

カボチャはばらつきが多いため算術平均に加え、分散を利用する。(カボチャの例は有名らしい) n-1で割るのは、標本を使って母集団の分散を推定する時に使う。 分散はある種の計算には使えるけど、要約統計量としては不敵な場合が多いため標準偏差を利用する。(平方週とかいう単位になってしまうため)

効果量

効果の大きさを記述する要約統計量。
例えば2グループの違いを記述するために平均の差を使うとか、そういうの。
ただ、グループ間の差をグループ全体の変動性と比較するやり方がある。それはコーエンのdと呼ばれる統計量だ。

わかったようなわかってないようなと思いつつ調べたら、みんな大好きTJO先生の記事。参考にしましょう。

tjo.hatenablog.com

結果のレポート

レポートする内容は、相手や目的にそってかわるよねという話。また、効果の重要さを強調するなら、差を強調する要約統計量を選んだり、ストーリーを明確に伝えるような統計報告と可視化を設計する。

要約統計量の選定やストーリーに関しては経験積まないとなぁと思う。以下の記事をトレースするのはよさそう。

www.analyze-world.com

感想

第一章よりは本格的に統計についての勉強に入り込んできたと思う。
演習問題も実践ぽくて、答えに困るけど面白い。別途自分なりに選んだデータで分析して見たい。

Laravelでメール送信する際にSendGridを使う

f:id:kzkohashi:20180730231315j:plain自社のサービス(Laravel)では、メールを送信する際にはSMTPの仕組みを利用している。
グーグルのメールアドレスなどもっていればLaravelのデフォルトの機能でサクッと作れるのだが、送信する際に毎回認証を挟んでいるので、処理に時間がかかったり、大量に捌くには別の仕組みが必要となってくる。

そんな時、前職でSendGridを利用していたのを思い出したので今回利用してみたという話。

SendGridとは?

メールの配信に特化したSaaS
12000通/月までは無料で使えるので、試したい人はサクッと試せていいね。

sendgrid.kke.co.jp

また、メール配信の仕組み上サードパーティを通すと信憑性にかけてしまうため、SendGridでは SPFDKIM の機能を提供している。
詳細に関しては、以下を参照

簡単にいうと、SPFは送信元のIPアドレスがそのドメインからから許可されていて、DKIMドメインが署名していることと改ざんがされていないことを保証することらしい。

ここら辺の記事も参考になりそう。

milestone-of-se.nesuke.com

SPF/DKIMの設定方法

Whitelabel機能にドメインを設定する

SendGridではWhitelabelという名前でSPFDKIMなどの機能を提供している。
ただし、最低プランの課金は必要なので注意。 f:id:kzkohashi:20180411201441j:plain

DNSでの設定

次に先ほど取得したドメイン名とデータをDNSのレコードに追加する。
(画像はRoute53)

f:id:kzkohashi:20180411201454j:plain

結果

Laravelの設定の前に結果だけいってしまうと、画像の通り設定したドメインから署名されたことになっている。

f:id:kzkohashi:20180411201508j:plain

Laravelでの設定

SendGridでは色々な言語でライブラリを提供している。実際にPHPで実装している例もある。

sendgrid.kke.co.jp

Laravelにはすでにメール機能があるので、それに乗っかりたいなーと思っていたら、ありました。公式の実装とは少し異なっていて、Guzzleで通信周りを実装しているみたい。

github.com

READMEにもあるように、数カ所設定したら実装完了で、ブログで説明することがなかったというくらい簡単に使えた。あまりにも寂しいので、メールを送信してる箇所を一部見せる。

<?php

public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('登録お申し込み受け付け')
                ->greeting($this->client_name .'')
                ->line('この度は、FIXAへお申し込みいただき誠にありがとうございます。')
                ...
                ->cc(env('OFFER_MAIL_ADDRESS'))
                ->view('mail.regist');
}
    

感想

SendGridではメールの開封有無や送信の失敗とかも取得できるので、近々そこらへんも取得してみたいと思う。

LaravelにSentryを導入してアプリのエラー監視を楽にする

サーバーの監視をするためにMackerelを導入をして1ヶ月くらいたった。時折なるアラートになんだか嬉しさを感じつつ(ダメだけど)、そろそろアプリのエラー監視もしっかりやらないとと思ってSentryを導入した話。

kzkohashi.hatenablog.com

Sentryとは?

オープンソースにもなっているイベント監視ツール。
主にエラー監視に使ってる例をよくみる。

sentry.io

ただ、自前のサーバーの用意や設定などを考えるとSaaSとしても提供しているため、今回はそちらを利用する。

ライブラリの導入

インストールは5.5以上だとすごく簡単。

github.com

app/Exceptions/Handler.phpに関数を追加するのと、.envSentry側で発行されたキーを入力するだけで準備完了。

エラーを起こして使ってみる

Slackにエラーを飛ばすことができるので、設定しておく。

sentry.io

実際にエラーを起こった場合このように、エラー(イベント)単位でIssueとしてみれる。 f:id:kzkohashi:20180407152454j:plain

詳細はこのようになっている。 f:id:kzkohashi:20180407152512j:plain

良い点としては

  • エラーの内容がWeb上で確認できる
  • 過去に起きたエラーかがわかる
  • 過去に対応した場合はその対応内容がわかる

まだローカルでしか試してないため、本番で運用したらここに追記しておく。

その他サービス

Mackerelもログ監視をできるみたいだが、どっちかっていうとミドルウェアとかのログチェックに使いそう。

mackerel.io

Datadogもログ監視の対応してるみたいで、こちらもインフラよりな使い方の紹介が多い。
ログの時間とサーバーのメトリクスの時間が連動するようになったっぽい・・・これは良さげなので別の機会にやってみたい。

www.datadoghq.com

終わりに

アプリのエラー検知はCloud Watch Logsなどで軽くやっていたけど、Sentryを使うと便利すぎて戻れなさそうだなと思った。
今回はサーバーサイド側をやってみたが、フロント(React.js)にも対応してるみたいなので、そちらも近々導入してみる。

React – Sentry Documentation

Think Stats(第2版)を読む:1章

最近、統計処理について詳しくなろうと考えていたところThink Stasをオススメされたので、メモがてら勉強した事を書いていこうと思う。(今回は1章のみ内容)

Think Stats 第2版 ―プログラマのための統計入門 | Allen B. Downey, 黒川 利明, 黒川 洋 |本 | 通販 | Amazon

2015年ごろに第2版が出版されて内容が多少変わっているので買う人は気をつけておこう。

1章: 探索的データ解析

統計処理をして行く上での流れだったり、Pythonなどの使い方がメインの話になっている。
内容としては、「第一子の出産は予定日よりも遅れることが多いか」についての議題。

事例証拠(anecdotal evidence)

雑談で出てくるような、「私たちはこうだから、絶対こうなる」や「友達たちはこうだったからこうである」のような個人的な経験のデータに基づいている、未公表の報告のことを言う。以下の理由から説得力がないため失格とのこと。

  • 小さすぎる標本数
    • 調べる人数が少ないとダメ
  • 選択バイアス
    • あることに関心を持ちすぎて、データの選択方法が結果を歪める
  • 確証バイアス
    • ある説を信じしてる人はその例ばかり提供してしまう(逆も然り)
  • 不正確さ
    • 人は忘れるものだ

統計的なアプローチ

事例証拠がだめならじゃあどうすればいいのか?
そんな時こそ統計を使おう!!ということで以下のようなやり方がある。

  • データ収集
    • ある程度のデータを集める(全米データとか)
  • 記述統計学
    • データの特性を簡潔に示すような統計値を求める
  • 探索的データ解析
    • 問題に対して、有用なデータのパターンや差やその他の特徴を探す
  • 推定
    • 標本から得られたデータを使用して、母集団の特徴を推定
  • 仮説検証
    • 偶然の結果じゃないのかを確認する

調査方法

調査方法には主に2種類ある。

  • 横断的調査
    • ある時点における母集団のデータを調査する方法
  • 縦断的調査
    • ある母集団を長期的に、繰り返して行う調査方法

ある問題に対して、どちらの調査が適切かを見極めるのが大切になる。

メリットデメリットについてはここら辺参考になる。

psycologystudy.blog.fc2.com

DataFrameを扱う

Pythonには、データをRDBcsvのように扱いやすくするためのPandasというライブラリがある。
この章では、データをインポートしたあたりからは黙々とデータフレームの表示とか加工をしていくことになるので、軽く他のサイトとかで勉強してもいいと思う。

参考になったサイト。

dev.classmethod.jp

qiita.com

終わりに

  • 最初の知識以外はほとんどPandasをいじってるだけだった
  • Pandas自体は、色々な機械学習ライブラリであまり対応していないため最近下火?(事例証拠です笑)
  • 色々な用語が出てくるため、この章でしっかり覚えておくと進めやすそう

リモートワークのMTGでペンタブ + RealtimeBoardを使ったら捗った

最近、実験的に週1~2でリモートワーク開発を行なっている。
その中で、どうしてもMTGの質がなかなか上げれずにいたけどかなり改善したので書こうと思う。

そもそもの課題

ビデオチャットでただ話すだけの会議については問題なかったけど、アーキテクチャの話や文字だけじゃ説明が難しい事柄についてはホワイトボードが欲しくなってくる。
なので、要件としてはホワイトボードみたくお互いが図とかかけたり共有できるものがほしかった。

RealtimeBoardを使う

とある記事で紹介されてたのがきっかけだったと思う。
名前の通り、リアルタイムでボードを共有するのがコンセプトのサービス

realtimeboard.com

実際使った内容

f:id:kzkohashi:20180401225802j:plain

コードや画像が貼り付けられたりするので、過去にリアルで行われたMTG内容の画像を貼り付けたりすることができるため、実は質が上がってるんじゃないかと思うくらいだ。
(ペンタブで書くのに慣れてないから色々下手。笑い)

豊富なテンプレート

うちではあんまり使えてないけど、ビジネスのアイディアだしや、デザイナーが情報の整理をするためのテンプレートみたいなのが豊富に用意してある。

f:id:kzkohashi:20180401225846p:plain

選んだペンタブ

RealtimeBoardは非常に使いやすいのだが、ペンタブがないとかなりつらいので選んだペンタブについて紹介する。
(リモートする人には原則、貸し出す)

ワコム製Mサイズモデル

ペンタブと言えばワコム
以前自宅用でSサイズを買った経験からすると、小さいとほんと使いづらいのでMサイズを購入。 ザラザラしているので、ピタッとは止まるけどなんか描きづらいというか、ザラザラ感が嫌いなだけかも。

Amazon | ワコム ペンタブレット One by Wacom ペン入力専用モデル Mサイズ CTL-672/K0-C | ワコム | ペンタブレット 通販

HUION製Mサイズモデル

中国の会社のペンタブ。
知らない会社だったのでレビューを入念にチェックしたところ、悪くなさそうだったので購入。
ワコム製とほぼ同じ値段で、スルスル描ける。自分的にはこっちのほうが描きやすい。
また、ペンタブにたくさんついてるボタンが地味にショートカット使うときに便利。

Amazon | HUIONペンタブ H950P 8192レベル筆圧感知 充電不要ペン、OSU用超薄型ペンタブレット | HUION | ペンタブレット 通販

やって見た感想

  • 1on1のMTGなら今のところリアルのホワイトボード並みに使えそう
  • ブラウザオンリーだけあって、少しもっさりする時がある
  • ペンタブ自体の慣れには時間がかかる
  • 複数人で試した時どうなるかを次はやってみたい

React + GoogleAnayticsでページトラッキングする

React+ GoogleAanayticsでトラッキングをするにはライブラリがあるのでそれを使う。

github.com

スター数も1000超えてるし、React + GAでなら一番人気かと思う。

インストールする際のバージョンに注意

react-gaには2.3.4において、初回のイベント以外は送信できないという致命的なバグが存在してる。
(だいぶ困ってた)

github.com

少なくともうちで使っている2.3.5ではすでに修正されているので、それ以降のバージョンをいれるようにしたほうがいい。

遷移するたびにトラッキングする

一つ一つのページに設置するのはめんどくさいので、ページの状態がかわったら送信するようにする。

まず、トラッキングするための親コンポーネントを作成する。

import React, {Component} from "react";
import {Route, withRouter} from "react-router-dom";
import * as titleUtil from "./util/Title";
import * as GaUtil from "./util/GA";

GaUtil.initialize();

class TrackPageView extends Component {

  componentWillMount() {
    this.track();
  }

  componentDidUpdate() {
    this.track();
  }

  track() {
    const currentPath = this.props.location.pathname;
    
    // タイトルが動的なパスはここでは送信しない
    if (GaUtil.isCustomTrackingPath(currentPath)) {
      return;
    }
    
    // パスに紐づくタイトルを設定する(固定)
    document.title = titleUtil.getTitleByPathName(currentPath);
    GaUtil.sendPageView();
  }

  render() {
    // 子コンポーネントを呼び出す
    return <Route children={this.props.children}/>
  }
}

// withRouterを使うことで、色々な遷移に対応できる
export default withRouter(TrackPageView);

次にRouteにあるコンポーネントたちをTrackPageViewの子要素する。

<BrowserRouter>
  // 囲う
  <TrackPageView>
    <Switch>
      <Route exact path="/" component={Lp}/>
      <Route exact path={ROUTE.Client.Login} component={ClientLogin}/>
      <Auth>
        <Switch>
          <Route exact path={ROUTE.Client.Item.Index} component={Items}/>
          <Route component={NotFound}/>
        </Switch>
      </Auth>
    </Switch>
  </TrackPageView>
</BrowserRouter>

こうすることで、子要素のコンポーネントcomponentWillMountが呼ばれる際に毎回トラッキングすることが可能になる。

タイトルが動的に変わるパスの設定

現状は子コンポーネントでデータを取得した際に、以下のように呼んでいる。

document.title = v.name + 'の詳細';
GaUtil.sendPageView();

ここら辺何かクールなやり方があれば知りたい・・。

LaravelでJSON Web Tokenを使った認証方法

Laravel + Reactでサービスを構築した場合に、APIによる認証方法としてJSON Web Token(JWT)を使った例を紹介しようと思う。

JSON Web Tokenとは?

ネットわかりやすく書いてあったので引用させていただくと

JWT(ジョット)とは JSON Web Token の略で、電子署名付きの URL-safe(URLとして利用出来る文字だけ構成される)な JSONのことです。 電子署名により、JSON の改ざんをチェックできるようになっています。 ざっくり言うと、改ざんできない JSON ということになります。 引用:https://qiita.com/gctoyo/items/8d0ffb265845ab8cc87c#jwt-%E3%81%A8%E3%81%AF

というセキュアで便利なものである。

認証として利用する

認証として利用するためには、とても便利なライブラリがあるのでそちらを使う。

github.com

インストールに関しては、公式の方を参考にする。

Laravel Installation - jwt-auth

モデルの設定

設定自体もとても楽で、Laravelにすでにある認証方法の一部変更するだけでいい。
実際の設定しているconfig/auth.phpはこのようになる。

<?php

return [


    'defaults' => [
        'guard' => 'api',
    ],


    'guards' => [
        'api' => [
            'driver' => 'jwt', # ここをjwtにする
            'provider' => 'client',
        ],

    ],


    'providers' => [
        'client' => [
            'driver' => 'eloquent',
            'model' => App\Models\ClientAccount::class,
        ],
    ],

];

ログイン

ログイン時にはいくつかバリデーションを行い、レスポンスにはトークンを返している。

<?php
public function login(Request $request){
    config(['jwt.user' => Client::class]);

    $account = $this->clientAccount->getLoginUserByEmail($request->email);

    // Emailまたはstatusがマッチしない場合
    if(!$account){
        throw new AuthenticationException;
    }

    // passwordがマッチしない場合
    if (!Hash::check($request->password, $account->password))
    {
        throw new AuthenticationException;
    }
    
    // ログイン情報を保存するにチェックを入れた場合
    if($request->remember){
        if (! $token = Auth::guard('api')->setTTL(config('jwt.ttl_r'))->login($account)) {
            throw new AuthenticationException;
        }
    }else{
        if (! $token = Auth::guard('api')->login($account)) {
            throw new AuthenticationException;
        }
    }

    return compact('token');
}

ユーザー側からの利用

トークンの利用については、API利用時にAuthorizationヘッダーにBearer: {取得したtoken}を付与すればできる。以下の記事が参考になる。

qiita.com

感想

  • JWTを使った認証もライブラリのおかげで楽に実装
  • ただ、JWTに関しては色々言われてるので利用する場合はちゃんと勉強しとかないとなとおもった