データサイエンス&サイバーセキュリティ備忘録

Python, Data Science, Kaggle, Cyber Security, CTF, などなど

BigQueryで横持ちのテーブルを縦持ちに変換してみた

はじめに

仕事でデータ集計を行うとき、ほぼBigQueryのクエリを書いて集計しています。

様々な関数を使いこなせるようになりましたが、ときどきPythonだったら楽なのにな~という集計があります。

例えば、横持ちのデータを縦持ちにしたいときです。

DBで横持ちのデータはなかなか無いかもしれませんが、csv形式のファイルでデータが横持ちで入っているということはあるのではないでしょうか?

横持ちのデータは、生データで見る場合には見やすいですが、SQLでの集計やBIツールでの可視化に向いていません。

Pythonでは、melt関数やpivot関数を使えば横持ちから縦持ちに簡単に変換することができますが、今回はSQL(BigQuery)で横持ちのデータを縦持ちに変換する方法を、自分用のメモとして残すと同時に紹介します。

と、その前に、クエリを実行するために使用したデータを簡単に説明します。

使用データ

今回使用したデータは、適当に作成した、とあるスーパーマーケットの部門×州の年間売上データです。

部門と州はSQLで集計しやすいようになっていますが、売上の年が列名となっていて売上金額が入っている状態です。

以下の画像は、使用するデータの一部です。

f:id:a7xche:20201208011938p:plain

今回はこのデータを、左からdepartment、states、year、sales列というように並んだ縦持ちのデータに変換します。

やり方

一発で簡単に横持ちのデータを縦持ちに変換できる関数はないようなので、複数の関数を組み合わせて変換します。

ざっくり流れを説明すると、

 STEP 1. 縦持ちにしたい列をSTRUCT型で1行ずつ格納
 STEP 2. 全てのSTRUCT型を配列で格納
 STEP 3. CROSS JOINとUNNESTによる配列のフラット化

というやり方です。

以下が実際に使用したクエリで、ここにコメントを付け足して解説をします。

-- 上記のSTEP 1とSTEP2 は、サブクエリ内でまとめる
WITH tmp_table AS(
  SELECT
    department,
    states,
    [
      STRUCT(2016 AS year,   -- 2016をyear列へ
             sales_2016 AS sales),  -- sales_2016のデータをsales列へ
      STRUCT(2017 AS year,   -- 2017をyear列へ
             sales_2017 AS sales),  -- sales_2017のデータをsales列へ
      STRUCT(2018 AS year,   -- 2018をyear列へ
             sales_2018 AS sales),  -- sales_2018のデータをsales列へ
      STRUCT(2019 AS year,   -- 2019をyear列へ
             sales_2019 AS sales),  -- sales_2019のデータをsales列へ
      STRUCT(2020 AS year,   -- 2020をyear列へ
             sales_2020 AS sales)   -- sales_2020のデータをsales列へ
    ] AS agg_data_  -- 配列でSTRUCT型を格納
  FROM
    `snappy-sunset-297913.data.ABC Retail`  -- 今回使用したデータ
)
SELECT
  department,
  states,
  agg_data.year,
  agg_data.sales
FROM
  tmp_table
CROSS JOIN
  UNNEST(tmp_table.agg_data_) AS agg_data  -- STEP 3


上記のクエリを実行した結果の一部が、以下の画像です。

f:id:a7xche:20201208013655p:plain

これで、データが扱いやすくなりました!

おわりに

ということで、今回はBigQueryのクエリで、横持ちテーブルを縦持ちにする方法の紹介でした。

冒頭で書いた通り、横持ちの状態でデータがDBに入っているということはないと思いますが、BIツール用にデータを集計した後に縦持ちに変換するときに重宝しています。

完全に余談ですが、適当なデータセットを作成するとき、以下のサイトがオススメです。

www.mockaroo.com

今回使用したデータセットは、上記のサイトを利用して作成しました笑

公式ドキュメントにない方法で、BigQueryにあるデータセット内の全てのテーブル・ビューの情報を取得してみた

はじめに

9月から新しい案件を担当することになり、実務としては初めてGCP(Google Cloud Platform)を使ってます。

これを機に、私用の個人アカウントでもGCPを触って練習し始めるようになりました。

適当にデータセットを作ってテーブルやビュー、永続関数を作ってみたところ、案の定データセット内がごちゃごちゃに。

BigQueryのデータセットにあるデータの情報を楽に取得する方法を知りたいと思うようになりました。

参考:公式ドキュメントに記載してある方法

まず最初に、公式ドキュメント*1に書いてある方法を簡単にまとめます。

以下のクエリを実行すると、指定したデータセット内にある全てのテーブルとビューに関する情報を取得することができます。

-- mydataset:データセット名

SELECT
 *
FROM
 mydataset.INFORMATION_SCHEMA.TABLES

この方法で取得できるのは以下の項目です。

  • TABLE_CATALOG:データセットを含むプロジェクトの名前
  • TABLE_SCHEMA:テーブルまたはビューを含むデータセットの名前
  • TABLE_NAME:テーブルまたはビューの名前
  • TABLE_TYPE:テーブルタイプ(BASE TABLE、VIEW、EXTERNALのいずれか)
  • IS_INSERTABLE_INTO:YES または NO(DML INSERT に対応しているか)
  • IS_TYPED:値は常に NO
  • CREATION_TIME:作成日時

欲しい情報が全て取得できなかった

最終更新日時やテーブルの行数、テーブルのデータサイズの情報も欲しいのですが、上記のクエリでは取得できません。

というわけで、何か別の方法があるばず...!と思い、公式ドキュメントで探したのですが見つからず...

最終更新日時はまだしも、行数とデータサイズが取得できないということはなさそうだと思い、色々試しました。

本題

色々やり方を模索していると、ある1つの方法を発見しました。

SELECT
  *
FROM
  mydataset.__TABLES__

このクエリを実行すると、以下の情報を取得できます。

  • project_id:データセットを含むプロジェクトの名前
  • dataset_id:テーブルまたはビューを含むデータセットの名前
  • table_id:テーブルまたはビューの名前
  • creation_time:作成日時
  • last_modified_time:最終更新日時
  • row_count:行数*2
  • size_bytes:データサイズ(byte)*3
  • type:テーブルタイプ(1、2、3、4のいずれか)

ここで、取得できる情報について補足説明をします。

まず、このクエリで取得できる作成日時と最終更新日時ですが、ミリ秒までを表示しているUnix Timestampで格納されています。

そのため、このまま出力しても日時が分からないので、変換する必要があります。

次に、テーブルタイプについてですが、このクエリで実行すると数値で取得します。

以下が、その数値とテーブルタイプの対応表です。*4

  • 1:BASE TABLE
  • 2:VIEW
  • 3:EXTERNAL
  • 4:OTHER*5

以上の補足説明を踏まえて、分かりやすい状態でテーブル・ビューの情報を取得できるよう、自分なりに改良しました。

size_bytesだとデータサイズが大きいときに分かりづらいと思うので、単位がMBとGBで表示されるsize_mbとsize_gbの列も足してあります。

改良したクエリが以下のものです。

-- mydataset:データセット名

SELECT
  * EXCEPT(type, creation_time, last_modified_time),
  ROUND(SAFE_DIVIDE(size_bytes, (1000*1000)),1) as size_mb,
  ROUND(SAFE_DIVIDE(size_bytes, (1000*1000*1000)),2) as size_gb,
  CASE
    WHEN type = 1 THEN 'BASE TABLE'
    WHEN type = 2 THEN 'VIEW'
    WHEN type = 3 THEN 'EXTERNAL'
    WHEN type = 4 THEN 'OTHER'
  END type,
  TIMESTAMP_MILLIS(creation_time) AS creation_time,
  TIMESTAMP_MILLIS(last_modified_time) AS last_modified_time
FROM
  mydataset.__TABLES__
追記

ブログ公開後に、MBは1024*1024、GBは1024*1024*1024ではないのか、というご質問が複数の方からありましたのでご回答します!

上記のクエリでは、国際電気標準会議(IEC)に則り、MBは1000*1000、GBは1000*1000*1000で計算しています。

今回、MBとGBを採用している理由は、MiBとGiBより多くの方に普及しているためです。

※ MiBが1024*1024、GiBが1024*1024*1024

おわりに

テーブルの情報は、クエリを実行しなくても1つずつ確認することはできます。

しかし、データセット内のテーブル・ビューの数が膨大で一覧表みたいな形で取得したい場合に上記のクエリが使えるかと思います。

__TABLES__は公式ドキュメントには記載されていないので、この記事が私みたいにテーブル・ビューの最終更新日時やデータサイズなどを含めた情報の一覧表を出力したい方の手助けができれば幸いです。

*1:https://cloud.google.com/bigquery/docs/information-schema-tables?hl=ja

*2:データタイプがビューの場合、0が入る

*3:データタイプがビューの場合、0が入る

*4:INFORMATION_SCHEMA.TABLESのクエリを使用して調査済み

*5:INFORMATION_SCHEMA.TABLESで取得できない、ルーティン以外のデータが該当

Twitterでいいねしたtweetを自動でSlackに投げてみた

はじめに

今までSurface Pro 3のメモリ4GBで頑張っていたのですが、流石に限界を感じたので2ヶ月ほど前にMacBook Proを購入しました笑

ちなみに、メモリは16GBにしたのでSurfaceの4倍です。

ただ、macOSの仕様やキーボードに慣れていなかったり、Surfaceタブレットにもなって便利ということで、Surfaceをメインに使っています。

Surfaceは、アメリカで苦楽を共にしたから愛着があるというのもある笑)

MacBookはどういうときに使っているのかというと、Kaggle用にデータ分析したりモデルを構築するなど、データサイエンス用のパソコンと化しています。

といっても、多少はSurfaceでもJupyterなどを使用していていますが...

SurfaceMacBookのどちらを使うにしても、データ分析やモデル構築のtipsは自分でググる or Twitterで情報収集して取り入れています。

Twitterでの情報収集を簡単に紹介すると、良さそうと思った情報にいいねして時間のある時にまとめて見る、という方法です。

Twitterを見るデバイススマホなのですが、実際にコードを書いたりするのはパソコンなので、いいねを見返すときはパソコンから閲覧しています。

しかし、Twitterのいいねのリスト内は検索ができなかったり、ひたすらスクロールしないと過去のものを見ることができないので、Surfaceで見つけたいいねをMacBookでも見つけるということが非常にめんどくさいです。

そこで、Twitterでいいねしたtweetを簡単にどちらのパソコンでも見れるようにしたいと思うようになり、何かいい方法がないか探していました。

前置きが少々長くなりましたが、いい方法を見つけた&実装したので紹介します。

方法

SurfaceMacBookの両方で使っているアプリケーションの1つにSlackがあるので、TwitterでいいねしたtweetをSlackに送るという方法を採用しました。

もともと、Surfaceで見つけた有益な情報をSlackを通してMacBookに送るという方法をとっていたので、いいねしたtweetもSlackにまとめるのはちょうど良さそうだと思い、早速実装しました。

使用したアプリケーション

今回使ったアプリケーションは、以下の3つです。

TwitterとSlackはもともと持っているアカウントを使用しているだけで、両アプリケーションではアカウント連携で使用しただけです。

IFTTTは馴染みがない方もいるかと思うので、簡単に説明します。

IFTTTとは?

IFTTT(If This Then That)は、2つのWebサービス・プラットフォームを連携させることができる、無料のプラットフォームです。

IFTTTで連携させることによって、あるプラットフォームで特定の操作をしたとき、あらかじめ設定しておいた操作を自動的に別のプラットフォームでも実行するということが可能です。

ifttt.com

上記の公式サイトでもあるように、TwitterFacebookなどのSNSだけでなく、iRobotのルンバやAmazonのAlexaといったスマート家電とも連携できるみたいです。

ここでのIFTTTの説明はこのくらいにして、どのように連携させたのかを紹介します。

実装

実装といっても、コーディングをする必要がないので非常に簡単です。

IFTTTのGUI上でポチポチとクリックしてオプションを選択するだけなので、誰でも簡単に好きなプラットフォームを連携させることができます。

では、具体的な方法を説明します。

事前準備

事前準備として、Slack上でどのチャンネルでいいねしたtweetを受け取るかを決めます。

ちなみに、指定のチャンネルではなく自分のDMで受け取ることも可能です。

私の場合、自分のDMではメモ代わりに使うことがあるので、いいねしたtweetを受け取る専用のチャンネルを作成しました。

STEP 1

いいねを受け取るSlackのワークスペースを開き、AppからTwitterとIFTTTを追加します。

Appは、左上にあるワークスペース名の下にあります。

Appをクリックし、TwitterまたはIFTTTと検索して追加をクリックすると、一度ブラウザが開きます。

ブラウザ上でSlackに追加を選択すると、追加完了です。

STEP 2

以下のサイトから、IFTTTのアカウントを作成します。

ifttt.com

リンク先の右上の、Sign upから作成できます。

STEP 3

サイトの右上の、Createからapplet*1を作成します。

Createを選択した後、以下の画面の赤枠内をクリックします。

f:id:a7xche:20200819104306p:plain

ここでは、最終的に実行したい操作を行うためのトリガーとなる動作を選びます。

今回の場合、トリガーとなるアクションはTwittertweetにいいねをするとなります。

なので、まずはChoose a serviceでTwitterを選択します。

次に以下の画面が現れるので、トリガーとなる動作(赤枠内と同じもの)をクリックします。

f:id:a7xche:20200819105653p:plain

※ ここまでの動作で、たしかTwitterのアカウントの連携がどこかのタイミングであった気がするので、トリガーとして使用するアカウントを連携します。

トリガーの設定が完了したら、次はトリガーによって起こすアクションの設定です。

今回の場合のアクションは、メッセージ(いいねしたtweet)を投稿するです。

まずは、以下の赤枠内をクリックして、Choose action serviceでSlackを選択します。

f:id:a7xche:20200819111701p:plain

次は、どのようなアクションをするかを設定するために、以下の赤枠内をクリックします。

f:id:a7xche:20200819112043p:plain

アクションを決めたら、どのチャンネル(または自分のDM)でどのようなメッセージを送るか決めます。

と、その前にここのタイミングでSlackと連携する操作が入ります。

ここで、いいねを投稿したいSlackのワークスペースを選択する必要があります。

連携後、以下の画面に遷移したらフィールドに設定を記載しますが、とりあえずいいねしたツイートがSlackに投稿されればいいという方は、どのチャンネル(または自分のDM)に投稿するかを決めるだけでOKです。

※ 青い太線は、自分のチャンネル名を隠しているだけです

f:id:a7xche:20200819114045p:plain

設定完了したら、フォームの一番下にあるCreate actionをクリックします。

以下の画面になり、appletが実行されたら通知を受け取るかの選択をし、Finishをクリックしたら完了です。

f:id:a7xche:20200819115002p:plain

実際に動かしてみた

早速、試しにフォロワーさんのtweetをいいねしました。

すると、いいねした数秒後に指定したSlackのチャンネルにtweetが投稿されました。

というわけで、無事に実装は完了です!

投稿されたSlackのチャンネル内では、tweetを探すための検索ができるので、実現させたかったことができて満足です。

めでたしめでたし。

*1:あるアプリケーションの中にある、小さなプログラムのこと。今回の場合、IFTTTというアプリケーションの中にある、連携させるためのプログラムのことを指す。

第10回 意思決定のためのデータ分析勉強会 onlineに参加しました

2020年6月20日、第10回 意思決定のためのデータ分析勉強会 onlineというイベントに参加しました。

ishikettei.connpass.com

データ分析や機械学習に関する勉強会には、今までもよく参加していたのですが、意思決定に重点を置いた勉強会は久しぶりでした。

この勉強会では、主に意思決定をするためのデータ分析をどのように行えばよいのかのツールの紹介と手法を学ぶことができました。

また、このイベントタイトルのサブタイトルが、"リモート環境でも使える意思決定術!"ということで、発表者のLTの前に現在のリモートワークの実情を主催者の方がまとめてくださいました。

リモートワークにおける悩みと工夫

・悩み
  ハンコ決済の遅延
  意思決定のスピード低下
  話がなかなか進まない
  ミーティングができない
  コミュニケーション不足

・工夫
  共有できるタスクボードの使用
  些細な情報もグループチャットで共有
  オンライン会議の開催

リモートワークにおいてこれから求められること

・情報収集能力
  自分で情報を収集し、必要な情報の選別

・情報伝達能力
  意思決定に必要な情報を過不足なく伝える能力
  誤解されずに伝える能力

・意思決定をするためのツールの導入と社内環境の整備
  SlackやMicrosoft Teamsなど、チャットツールの導入
  クラウドなど、データ分析をするための新しいツールの導入

参加者に向けたアンケート結果では、新型コロナウイルスの影響でリモートワークになった方が多数で、私自身もリモートワーク中です。

上記でまとめたように、リモートワークではコミュニケーション不足に陥ってしまうので、情報伝達能力が求められることに関しては、確かに...と頷きながら聞いていました。

ここからは、各発表者ごとにLTの内容を簡単にまとめたいと思います。

田中丸 祐治 さん

タイトル

DataFrameをPython数行でEDA(探索的データ解析)

内容
  • EDA(探索的データ解析)

  ・分析する前に、どのようなデータがあるのかを確認すること
  ・データの集計、要約、可視化が含まれる

  • アヤメのデータセットを使用してEDAのデモ
  • EDAをするときに便利な関数&ライブラリの紹介

  ・DataFrame.describe()
  ・pandas_profiling.ProfileReport
  ・pixiedust diplay
  ・plotly.express

github.com

小川 英幸さん (はんなりPython オーガナイザー)

タイトル

衛星画像のAPIをたたいて可視化するダッシュボードを作った

内容
  • 経度と緯度を入力すると、センチネルという衛星のセンサデータを取得
  • 取得したデータを可視化&テーブルを出力
  • Dashというフレームワークを使用し、Pythonで作成
  • データを見たい全ての人がコーディングできるわけではないから、Webアプリケーションを作成してデータの共有を行うのが良い

scrapbox.io

杉山 阿聖さん

タイトル

因果推論入門

内容
  • データから意思決定を行うときに注意すべき選択バイアスと、正しい意思決定をするためのアルゴリズムの紹介
  • 統計的因果推論では、介入を行ったときのアウトカムと行わなかったときの差である介入効果を扱う
  • 統計的因果推論で扱う問題の例

  1. マーケターの業務における仮説立案
   ・ライトユーザーはヘビーユーザーになってほしい
   ・2ユーザの過去の行動履歴を収集、行動の差を特定
   ・ユーザーの行動に関する仮説立案を行う
   ・ライトユーザーにその行動を促すような施策の検討
   ・A/Bテストで検証を行うことによって、仮説が正しいかが分かる

  2. メール施策の効果測定
   ・メール施策の効果があるのかA/Bテストで確かめたい
   ・ただし、会員登録をするときのメールアドレスの登録は任意
   ・ライトユーザーはメールアドレスの登録していなさそう
   ・ヘビーユーザーだけがアドレスの登録をしている模様
   ・メール施策の効果検証をA/Bテストで行いたい
   ・選択バイアスがあり、全ユーザーに対して効果があるのかが分からない
   ・ヘビーユーザーの傾向を見ているだけなのかもしれない
   ・1ユーザーのメールを送った/送らなかった結果は、同時に取得できない

  • 選択バイアスの例

  1. 新型コロナウイルスの抗体検査の結果の比較
    ・東京と大阪で比較
    ・大阪の方が抗体検査での陽性率が高かった
    ・しかし、大阪では抗体検査の被験者を無作為抽出していない
    ・大阪府が抗体検査の希望者を募っていた
    ・自分が抗体を持っているかもしれないという人の抗体検査を行っていた

  • A/Bテストを行うためには、標本を無作為抽出しなければいけない
  • 因果関係は、どのような問題でも分かるわけではない
  • 統計的因果推論では、ATE(Average Treatment Effect)やCATE(Conditional ATE)を推定する
  • 機械学習で統計的因果推論を行いたい場合

 ・アップリフトモデリング

※ LTの時間配分の関係により、ここで終了

speakerdeck.com

スマホで見ている方はこちらからどうぞ↓
https://speakerdeck.com/asei/introduction-to-causal-inference

森 正和さん

タイトル

D2C時代に突入して変革したデータ分析

内容
  • D2C = Direct to Customer
  • D2Cとは、自社製品を小売業者に介さずに、自社のECやSNSを使って直接消費者に販売すること
  • D2Cでは、顧客に関するデータで意思決定をする
  • なので、お客さんは製品開発の一員

※ 資料の公開なし (2020年6月22日 時点)

案浦 浩二さん

タイトル

Neo4jを使った日本のCOVID-19データの可視化と解析

内容
  • Neo4jの紹介
  • Neo4jはグラフデータベースであり、NoSQLに分類される
  • テーブル構造ではない、シンプルな構造
  • Cypherでコードを書く
  • SQLより少ない行で書くことができる
  • Neo4jでMDM(マスターデータ管理)をさせることによって、データを名寄せ*1することができる

※ 資料の公開なし (2020年6月22日 時点)

まとめ

今回のLTでは、意思決定をするための手法や、データ分析を行うときのオススメのツールを知ることができました。

田中丸さんが紹介してくださったPythonのライブラリが特に気になったので、今度試してみたいと思います。

また、杉山さんの因果推論の説明が分かりやすかったので、続きはスライドを読むなどをして、深堀していきたいです。

Webアプリケーションの脆弱性を突くゲームをやってみた

はじめに

知り合いから、サイバーセキュリティに関する面白いサイトを教えてもらいました。

ちなみに、サイトは英語です。

xss-game.appspot.com

このサイトでは、クロスサイトスクリプティングという攻撃手法を学びながら、Webアプリケーションの脆弱性を見つけて攻撃することができます。

※ 実際にサイバー攻撃をするのは犯罪なのでやめましょう!

クロスサイトスクリプティングによる攻撃は深刻なものであり、結果的にサイトのユーザーの情報を盗み取られたり、ユーザーのパソコン・スマートフォンマルウェアに感染してしまうという被害に遭ってしまいます。

ちなみに、Googleは自社製品においてクロスサイトスクリプティング脆弱性を見つけた人には、最大 $7,500の報酬を払うとのことです。

www.google.com

クロスサイトスクリプティングによる攻撃を防ぐことは、サイトを攻撃されないようにするためだけでなく、ユーザーが安心してサイトを使用できるようにするためにも重要なことです。

このサイトのゲームを詳しく紹介する前に、そもそもクロスサイトスクリプティングとは何なのかを説明したいと思います。

クロスサイトスクリプティングとは?

クロスサイトスクリプティングとは、Webアプリケーションに用意された入力フィールド(TwitterのツイートやFacebookの投稿など)に、入力データとして悪意のあるスクリプトを埋め込むという攻撃手法です。

上記で述べたように、直接的な被害者はサイトのユーザーであり、攻撃者が仕掛けた不正なスクリプトをユーザーが気づかずに実行することによって、脆弱性のあるサイトを経由(クロスサイト)し、攻撃が行われます。

以下のサイトにて、攻撃の流れを詳しく説明してあるのでバトンタッチします。
cybersecurity-jp.com

クロスサイトスクリプティングは、英語で表記するとCross-Site Scriptingであり、XSSとよく表記されます。

名前の通り、スクリプトを使用した攻撃なので、攻撃に使用する主なプログラミング言語はHTMLとJavaScriptです。

クロスサイトスクリプティングの攻撃を防ぐためには、ユーザー自身が使用しているブラウザを常に最新版にすることや、セキュリティソフトを導入することが大事とのことです。

ゲームについて

このゲームではHTML、JavaScriptPythonの知識が必要ですが、そこまで高度な知識は問われないです。

と言っても、私はもともと3つのプログラミング言語全て使用したことがあるので、上記の文はあくまでも参考程度にしてください...(^_^;)

個人的には、簡単なフロントエンドの知識があれば解きやすい、という印象です。

まず、冒頭で紹介したURLを開くと、以下のような画面になります。

f:id:a7xche:20200618154633p:plain

私は既にLevel 2までクリアしているので、初めてこのゲームをする方はLevel 1だけが表示されている状態かと思います。

各Levelの問題タイトルを選択すると、ゲームが始まります。

以下はLevel 1を選択したあとの画面です。

f:id:a7xche:20200618162400p:plain

Mission Descriptionには問題の概要、Mission Objectiveにはどのようなことをしたらクリアとなるのかが書かれています。

この問題の場合、JavaScriptのalertのポップアップを表示させるスクリプトを、Your Targetの下に表示されているwindowに埋め込むとクリアとなります。

Target Codeの横にあるtoggleをクリックすると、windowに表示されているサイトのサーバーサイドのPythonコードを見ることができます。

また、Hintの横にあるshowをクリックすると、この問題をクリアするためのヒントが表示されます。

Level 1をクリアするとLevel 2に進むことができ、Level 6まであります。

以上がゲームの説明です。

まとめ

今回は久しぶりにサイバーセキュリティに関する記事を書き、クロスサイトスクリプティングを体験できるサイトを紹介しました。

こちらのゲームを通して、攻撃手法を学べるだけでなく、Webアプリケーションを作成するときに気を付けるべきことも学べます。

なので、個人的にはサイバーセキュリティに興味がある方だけでなく、フロントエンドエンジニアとサーバーサイドエンジニアの方もゲームに挑戦するのもいいと思います。

私の本業はデータサイエンティストであり、フロントエンドとサーバーサイドは大学の授業や趣味でいじったことがある程度なので、実務において参考になるか分かりませんが...

あと、大事なことなのでもう一度言います。

実際にサイバー攻撃をするのは犯罪なのでやめましょう!

おすすめ書籍: データ分析のための数理モデル入門 本質をとらえた分析のために

Twitterで、この本の著者である、江崎貴裕さんのツイートで本のことを知りました。


数理モデルに関しては、前から大学時代の知識と合わせてネットで勉強していましたが、ここ最近になって辞書代わりとして何か1冊購入したいと思うように。

この本の帯にある、"本当にそのモデルでいいんですか?"という、ドキッとさせるようなキャッチコピーに特に惹かれて、発売されたら本を購入しようと決めていました笑

ある日、本の情報を収集しているときに江崎さんのツイートでサイン本のプレゼントの企画を見つけ、応募したらまさかの当選。(当たると思わなかった)

本が届いて早速読もうと最初に目次を見てみると、そもそも数理モデルとは何かという説明から、時系列モデルや機械学習モデルの解説、また、目的別に数理モデルの設計のポイントまで盛りだくさん。

簡単な例を挙げての説明や、より細かいことは補足として注釈で丁寧に書いてあるので、理解をより深めることのできる入門書としてまとめてあると思います。

個人的にはこの本を読めて満足しているので、ここからはもう少し詳しい本の紹介と、読んだ後の所感をまとめます。

所感に関しては、あくまでもブログ筆者自身の意見なので悪しからず。

一応、私のバックグラウンドを簡単に説明すると、アメリカのCSの学士号を持っている、新卒2年目データサイエンティストです。

また、本の詳しい内容は目次を見ればだいたい分かるので、このブログでは目次だけ載せておきます。

目次

本の目次は以下の通りです。

第一部 数理モデルとは
第1章 データ分析と数理モデル
第2章 数理モデルの構成要素・種類

第二部 基礎的な数理モデル
第3章 少数の方程式によるモデル
第4章 少数の微分方程式によるモデル
第5章 確率モデル
第6章 統計モデル

第三部 高度な数理モデル
第7章 時系列モデル
第8章 機械学習モデル
第9章 強化学習モデル
第10章 多体系モデル・エージェントベースモデル

第四部 数理モデルを作る
第11章 モデルを決めるための要素
第12章 モデルを設計する
第13章 パラメータを推定する
第14章 モデルを評価する

対象読者

この本はタイトルにある通り、数理モデル入門書です。

なので、本にはたくさんの数式が出てきます。

しかし、それぞれの数式の意味や変数が何を指しているのかを丁寧に説明しているので、文系・理系問わず誰でも簡単に読み進めることができると思います。

この本のポイント

本を読んでいて、読者が読みやすいように工夫されていると感じたので、ポイントごとにまとめます。

図・グラフが盛りだくさん

数理モデルを初めて勉強する方にとっては、いきなり数式だけが出てきてもイメージが沸かずに難しいと感じてしまうかもしれません。

しかし、この本では方程式とグラフで説明しているページもあり、数理モデルの専門用語を図で説明している箇所もあるので、非常に分かりやすいです。

このような工夫は初学者にとって理解の助けになり、最初から躓いてしまうことがなくなると思います。

フルカラーである

人によるかと思いますが、私はモノクロよりはカラーの方がやはり読みやすいです笑

また、1つ目のポイントでも書いた通り、図やグラフで説明している箇所が多く、複合グラフは色別でそれぞれのグラフが書かれているので分かりやすいです。

文章を読んで理解するだけでなく、視覚的にも理解できるかと思います。

まずは基礎をしっかり固めてからモデル設計

この本は、先ほどの目次でも紹介したように大きく4部に分かれています。

第一部 数理モデルとは
第二部 基礎的な数理モデル
第三部 高度な数理モデル
第四部 数理モデルを作る

この本1冊では、数理モデルとは何かの説明から始まり、モデルの設計まで学べます。

しかし、第二部と第三部にあるようにしっかり段階を踏みつつ、様々な種類のモデルを学ぶようになっています。

なので、順番に最後まで読めば、実際に設計をするときにモデルを使い分けることができるようになる構成だと感じました。

本文で幅広く扱い、注釈でより細かく説明

各部・各章の説明はしっかり説明はしているが深く説明しすぎていない、丁度よい量だと思いました。

しかし、著者がより細かく説明したい箇所については注釈で説明がしてあったり、さらに理解を深めたい人向けに別の参考書の紹介がされています。

注釈の数は今まで私が読んだ本の中で多い方かと思いますが、ただ追加の説明をするのではなく、実践に向けてしっかり補足するという役割を持っていると思います。

最後に

これからデータ分析の仕事に関わる方や、データサイエンスの勉強をしたいけど最初に何を学べかいいか分からないという方にお勧めです。

個人的に、データサイエンスの初学者はこの本で基礎を固めながらPython(またはR)を学び、Kaggleで少しづつ力をつけるという流れがいいかと思いました。

Pandasのread_csvは、ただ単にデータが読み込めるだけではない

Pythonのライブラリの一つ、Pandasはデータサイエンスに欠かせないものです。

Pandasの中でも、read_csvはデータサイエンスの勉強をしている方やデータサイエンティストの方にとって、特に馴染みのある関数かと思います。

read_csvを初めて聞いた人向けに説明すると、この関数はcsv形式のファイルをPandasのDataFrameに読み込むという役割を持っています。*1

基本的な使い方は、以下の通りです。

import pandas as pd

df = pd.read_csv("fileName.csv")

もし、csvファイルに日本語が含まれている場合はエンコーディングを引数で指定します。

import pandas as pd

# cp932 が日本語用のコード
df = pd.read_csv("ファイル名.csv", encoding="cp932")

ロシア語やアラビア語など、他の言語でもエンコーディングを指定する必要があります。

その場合は、以下のサイトからコードを探して引数で指定すると読み込めます。

docs.python.org

以上が基本的な使い方ですが、read_csv()のドキュメントを見てみると、たくさんの引数が用意されています。

そこで、今まで業務で使用してきたものと、新しく知って便利だと思ったものをまとめたいと思います。

使用するデータ

適当に自作した、NameList.csvというファイルを使います。

中身は全て英語のため、エンコーディングの指定はしていません。

以下のコードで読込み、出力した結果は画像の通りです。

import pandas as pd

df = pd.read_csv("NameList.csv")

f:id:a7xche:20200503005410p:plain

使用する列を絞りたいとき

csvファイルのデータサイズが非常に大きいが、分析で使いたい列は全部ではない、ということが実務ではあるかと思います。

ファイルを読み込んだ後に、Pandasのdrop関数で削除するという手もありますが、データを読み込む時間がもったいないと感じることもあるのではないでしょうか。

そこで、usecolsという引数を使えばデータを読み込む時点で使用する列を絞ることができ、読み込む時間も短縮することができます。

以下がコードと出力結果です。

import pandas as pd

# 使用したい列を"FirstName", "LastName", "BirthDate"とする
df1 = pd.read_csv("NameList.csv", usecols=["FirstName", "LastName", "BirthDate"])

f:id:a7xche:20200503013035p:plain

読み込むファイルの列のデータ型を指定したいとき

read_csvは、元のファイルのデータから自動的にデータ型を認識して読み込んでくれます。

しかし、例えば数値で書かれている”型番”や"コード"の列をstring型で読み込みたいとします。

読み込んだ後にastypeで変換できますが、読み込むときにdtypeという引数を使用すれば、列ごとにデータ型を指定して読み込むことができるので、わざわざ変換するコードを書く必要がありません。

この例では、"Age"の列をint型ではなくstring型で読み込みたいとします。

以下がコードと出力結果です。

import pandas as pd

# "Age"をstring型で読み込みたいとき
df2 = pd.read_csv("NameList.csv", dtype= {"Age": str})

f:id:a7xche:20200503020805p:plain

読み込むときに飛ばしたい行があるとき

read_csvは、ファイルにある全ての行と列を読み込みます。

基本的には、全てのデータを読み込むことで不便になることはないですが、仮に1行目にデータの説明が書いてあるとします。

データを読み込むときには、その1行目が邪魔かと思います。

そこで、skiprowsという引数を使うと指定した行を飛ばして読み込むことができます。

今回は、1行目を飛ばしたいとして、コードと出力結果を載せます。

import pandas as pd

# 1行目(indexが0の行)を飛ばしたいとき
df3 = pd.read_csv("NameList.csv", skiprows=[0])

f:id:a7xche:20200503220328p:plain

先頭の何行かだけ試しに見てみたいとき

csvファイルのデータサイズが大きくて読み込みに凄く時間がかかりそうだけど、データの中身を確認したいというときがあるかと思います。

csvファイルを直接開いて確認するという手ももちろんありますが、データサイズが大きいと開くのにも時間がかかります。

そんな時に便利なのが、nrowsという引数です。

nrowsで行数を指定すると、先頭から指定した行数だけ読み込むことができます。

以下がコードと出力結果です。

import pandas as pd

# 最初の3行だけ読み込みたいとき
df4 = pd.read_csv("NameList.csv", nrows=3)

f:id:a7xche:20200503225451p:plain

日付データを読み込みたいとき

最後は、最近知った便利な引数です。

日付のデータが入っているcsvファイルを読み込むと、string型(ただの文字列)で読み込まれます。

日付データを使用して計算したい場合、pd.to_datetimeでTimestamp型(datetime64[ns]型)に変換する必要があります。

pd.to_datetimeを使うとき、引数で日付データのフォーマットを指定しないと上手く読み込めないかと思います。

しかし、ファイルを読み込むときにどの列が日付データなのかをparse_datesという引数で書いておくと、わざわざフォーマットを指定しなくてもTimestamp型で読み込んでくれます。

以下がコードと出力結果です。

import pandas as pd

# "BirthDate"は日付データ
df5 = pd.read_csv("NameList.csv", parse_dates=["BirthDate"])

f:id:a7xche:20200503231115p:plain

parse_datesで変換されたデータは、pd.to_datetimeで変換したものと同じなので、日付データを問題なく計算できます。

まとめ

以上がread_csvの便利な引数です。

pandasやnumpyなどの使い方はKaggleで学べますが、データがきれいな状態で用意されています。

しかし、実務の場合は必ずしもすぐに使えるような状態のデータが使えるわけではありません。

読み込むときにあらかじめ引数で設定しておけば楽な上に、データ型の違いでmergeができない、などの大したことがないエラーを防ぐことができるのでおすすめです。

ちなみに...

最後に1つ。

read_csvはその名の通り、csv形式のファイルを読み込むものです。

しかし、csvファイルが圧縮された状態のzipファイルでもread_csvで読み込めます。

import pandas as pd

# NameList.csvを圧縮したもの
df = pd.read_csv("NameList.zip")

f:id:a7xche:20200503234420p:plain

入社したばかりのときに知ったのですが、わざわざファイルを展開しなくても読み込めるので地味に便利です笑