GAミント至上主義

Web Monomaniacal Developer.

データ解析インターンの予定を立ててみる

以前の記事でインターン募集をしていましたが、1件応募があり、採用の方向で進んでいるので、ざっくり今後のスケジュールを立ててみる


前提条件いろいろ

対象

大学2年生

マーケティングに興味があり、データ分析、プログラミングのインターンを探していた。

プログラミング未経験

期間

週2で6ヶ月以上

就活が本格化するまで。

目的

大学生

就職活動のため

自社側

会社の知名度アップ

社員(自分)の教育能力を付けるため

採用のため

前提条件以上。




まずゴールを設定。

ゴール

ざっくりだけど

仕事ができる人にする(なる)

bizocean自体も書式で仕事を効率よくできるようにするサービスだし、インターン生を仕事ができる人にできるのであれば、採用にも、教育スキル的にも良いと判断できそう。


求めること

自社社員との世代ギャップを活かした視点、発見。


評価軸

面談はよくやるけど、ただ「データ解析のインターンしてました」だけだと就活の時に弱い気がする。

実際にその過程と成果がネット上で見られるようになっていれば、履歴書にURL書くことでかなりアピールできそう。

そのため、成果物として3つを設定。

- bizoceanの技術ブログを執筆
- データ分析を行いグラフ、レポートの作成
- 企画、提案資料を作成

この3つをメンターが質的に、アクセス数などを量的に判断して評価する。

スケジュール

当たり前だけど途中のサポートや進捗確認はメンターがする。

入門 ~2、3ヶ月

bizoceanとは

まず、データはうちのbizoceanのアクセスデータ、行動データ、会員データなどを使うので、うちのビジネスはなにか、そのデータが何を意味しているのか、どうやって記録しているのかを知ってもらう。

www.bizocean.jp

社員にインタビューして、先入観などを知るのもいいかも。

途中成果として、「bizoceanとは○○○である」みたいなのを100個書くとかもいいかな。大学生の視点で出すと既存の社員には意外かもしれない。

データ分析とは

まだ簡単なところしか手を付けられてないけど、どういった手順でデータを可視化していくのかを見てもらう

Pythonと環境について

データ解析にはJupyterのGoogleカスタマイズである、Google Cloud Datalab上でPythonを書き、BigQueryからデータを取って使ってもらう。

アプリ開発よりはPythonで覚える必要がある範囲が狭いので(Pythonで使うライブラリが限られているという意味)、実際に動かしながら基本的な文法、エラー対処に慣れてもらう。

実践 ~2、3ヶ月

テーマを考える

bizoceanと、データについて理解してもらったら、自身の興味や、会社の課題に合わせて、データを使って何をするのかのテーマを決めてもらう。

一つだけだと視野が狭くなるので、2、3個以上とする。

できれば既存の社員の思い込みを打破し、新しい発見となるようなものがいい。


- bizocean会員は実は○○だった!
- bizocean会員が辞める本当の理由
- こういうコンテンツがあれば、会員は○○万人増やせる!

さっき拾った記事だけどこういうフレームワーク使うのもありかも
medium.com

資料作り

データを使って、テーマについて資料を作成する

発表

月一の全体会議にて発表


絶対内定2018 インターンシップ

絶対内定2018 インターンシップ

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

CeleryでWokerとbeatを同時起動する

タスクキューイングができるCeleryを使っているけど、一部認証が1時間で切れる箇所があり、期限切れの前に定期的に再認証を行う処理が必要になった。

そのため、Celeryでcron的なことができるbeat機能を使った。

Periodic Tasks
Periodic Tasks — Celery 4.0.2 documentation

ドキュメントから下記部分を参考に再認証処理を追加

from celery import Celery
from celery.schedules import crontab

app = Celery()

@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    # Calls test('hello') every 10 seconds.
    sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')

    # Calls test('world') every 30 seconds
    sender.add_periodic_task(30.0, test.s('world'), expires=10)

    # Executes every Monday morning at 7:30 a.m.
    sender.add_periodic_task(
        crontab(hour=7, minute=30, day_of_week=1),
        test.s('Happy Mondays!'),
    )

@app.task
def test(arg):
    print(arg)
Setting these up from w


最初はworkerの他にbeatの起動が必要なのを知らずに、全然動かんと思ってしまった。

しかし、今回の再認証処理は、同一インスタンス内で再認証するので、別プロセス、別コンテナ(Docker)になってしまうと、全く意味がない。

なんとか一プロセスでworkerとbeatを起動できないかと思ってたら簡単にできるよう。

stackoverflow.com

python manage.py celery worker --beat

 ※--beatの代わりに-Bでも同じ


が、ドキュメントを見てみると
Periodic Tasks — Celery 4.0.2 documentation

this is convenient if you’ll never run more than one worker node, but it’s not commonly used and for that reason isn’t recommended for production use:

あまり一般的ではなく、本番環境ではおすすめしないとのこと。

Worker内で行う再認証などは、素直にWorker内で完結させたほうが良さそう。



Celery、リトライ、時間制限(1秒に1回だけとか)、cronのような定期実行までできて便利すぎてやばい。

RedisのlistとpubsubとRabbitMQを使い分けを考える

2017年1月現在、ビッグデータ処理プロジェクトoceanusは下記のようなデータの流れをしています。


f:id:uyamazak:20170120102719p:plain


GEK上でDockerを使ってアプリケーションを構成していますが、Redisのリスト型、pubsub型に加えて、最近RabbitMQも使い始めたので、どう使い分けしているかを整理してみる。

Redis list型

順番を持ったリストで、左から入れたり、右から入れたり、逆に取り出したりすることができる。

リスト型 — redis 2.0.3 documentation

用途

データを失いたくない1対1のデータ処理。

oceanusでは、armsでHTTPリスエストをバリデーション等をした後にlistに保存し、r2bq(Redis to BigQueryの略)が取り出して、BigQueryに保存している。

BigQueryに保存したらもう必要がなくなり消えるので、基本的にRedisに保存されているデータは少ない。

BigQueryが落ちているなど保存できない場合は、再度listに戻す処理を行っている。


Redis PubSub

情報発信側publisherに対して、複数の受信側subcriberが登録することができる。

Sub側は登録以前のものや接続が遮断されてる間のデータは失われる。送受信が失敗してもリトライは無い。

GoogleのCloud PubSub
Google Cloud Pub/Sub Documentation  |  Cloud Pub/Sub  |  Google Cloud Platform
は、データの再送、保持などもしており信頼性は高いけど、実際に使ってみた所、認証や通信でレスポンスが悪くWEBサーバーが遅くなるため、自分でRedis立てて使いました。

用途

1対多のデータ処理。一つのデータをいろいろな所で使いたい時、かつ多少データがなくなっても問題がないもの。

流れてきたデータにフィルターをかけて、条件Aに合致したらメール、条件Bに合致したらスプレッドシートに保存するとか。

oceanusでは、データはBigQueryにすべて保存されるので、データが失われてもいいような通知用途などに使っています。

RabbitMQ

メッセージキューイングのミドルウェア

メッセージといってもメールやチャットのような人が読むものではなく、シリアライズ化したコードなど機械同士のやりとりが基本です。

銀行などでも実績があり、貯めたタスクを処理するワーカーを別プロセスで走らせることができ、耐障害、非同期、分散、スケールなどを用意に実現できます。

AWSでは、似たようなSQSがあります。
aws.amazon.com

GoogleでもApp Engine用にTask Queue

Task Queue Overview  |  App Engine standard environment for Python  |  Google Cloud Platform

があるけど、App Engine以外から使いにくそうなので使いませんでした。

用途

タスクの非同期処理。リクエストに対して処理時間が長い時、リクエストの数分後など時間差で実行したい時など。


PythonCeleryから使っており、送りたいタスクを関数にし、デコレータを付けるだけで使用できます。

CeleryはブローカーとしてRedisも使うことができますが信頼性、対応する機能などからRabbitMQが推奨されてるようです。

公式Dockerイメージを使えば、特に難しい設定もなく使うことができました。


現在は、特定の条件(エラーを意味するものとか)で、Googleスプレッドシートに保存したり、コンバージョン通知からそのユーザーの履歴をBigQueryから取ってきてメールに付けて送るなどのタスクをどんどん投げて処理させています。

ワーカーはデフォルトでは10と多くなっており、スプレッドシートにアクセスしすぎて、繋がらなくなるなどもあるので、1秒に1回などリミットを掛ける必要がありました。

リトライ、オートスケーリングなど多数の機能がありまだ使いこなせていない感。

逆にこれを使っておけばあとで困ることはなさそう。


昔はDBに保存してcronで処理などもあったと思いますが、そのロジックを自分で書くのは大変だし、スケーリングや多重起動の防止などいろいろ面倒なので、こういうミドルウェアを積極的に使った方が昔の自分に勝てます。

まとめ

最初はRedisとBigQueryだけでしたが、間にPubSub、RabbitMQを入れることにより、リアルタイム処理や、重い処理の非同期処理などさまざまな形でデータを利用することができるようになりました。

また疎結合を保てるので、listを使う部分の開発、pubsubを使う部分の開発をお互いにあまり影響せずに進めることで出来て安心して、本番テスト等も行えます。

プログラマとして、使える道具はどんどん増やしていくべき。


Redis入門 インメモリKVSによる高速データ管理

Redis入門 インメモリKVSによる高速データ管理

Mastering RabbitMQ

Mastering RabbitMQ