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

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

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

はじめに

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

ある日、取り扱っているデータの量が膨大で使用していないデータセットがあるかもしれないということで、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

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

PythonのMLライブラリ、PyCaretを使ってみた

はじめに

よく、TwitterやLinkedInでデータサイエンスや機械学習の情報収集をしているのですが、こんなものを見つけました。


Announcing PyCaret 1.0.0
https://towardsdatascience.com/announcing-pycaret-an-open-source-low-code-machine-learning-library-in-python-4a1f1aad8d46


とりあえずどんなライブラリなのかサーっと記事を読んでみると、コードを全然書かなくてもモデルを作ることができる、AutoMLみたいなものだと思いました。

私も使用してみたいと思い、ライブラリをインストールしようとしましたがうまくいかなかったため、インストール方法も含めて使い方をメモとして残すことにしました。

私がPyCaretを動かした環境は、WindowsのローカルのJupyter Notebookです。

今回は、Macのパソコンでも同じ方法でできそうな気がします。

と、その前にまずはPyCaretが何かをもう少し詳しくまとめたいと思います。

PyCaretとは?

上記のサイトの記事のハイライト部分をそのまま翻訳すると...

(PyCaretは、)教師あり学習教師なし学習のモデルをローコードで学習とデプロイするための、オープンソースPython機械学習ライブラリ

とのことです。

ローコードという言葉をこのとき初めて見たのですが、最小限のソースコードまたはソースコードなしでソフトウェア開発を高速化するためのITツールのことだそうです。 *1

コードの見本を見てみると、モデルの作成やパラメーターチューニングといった各工程で作成するコードは、たった1行でできます。

公式サイトがあるので、URLのリンクを紹介します。

pycaret.org


インストール方法

Anaconda Promptを開き、以下のコマンドを入力します。

pip install pycaret 

一度このコマンドを実行すると分かると思いますが、たくさんのライブラリをインストールします。

途中でエラーが起きずに全てインストールできたならば問題ないですが、先に書いた通り、私の環境ではうまくいきませんでした。

最初に上記のコマンドを入力すると、私の環境ではいくつかのライブラリで以下のエラーが起きました。

Cannot uninstall '{library name}'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

新しいバージョンをインストールするときに古いバージョンのものを一度消しますが、その時にどのファイルがアンインストールするためのものかの判断がつかないため、アンインストールができないというエラーみたいです。

解決方法を探してみると、以下のブログを見つけました。

!Warning!:
この方法でもできるのかもしれませんが、私の環境ではうまくいかず、Anacondaの環境が死にました笑

なので、エラーが起きた場合は他の方法で解決することを推奨します。

後ほど紹介する方法の方が無難だと思うので、この段落の最後にURLだけ紹介します。

www.smartbowwow.com

いくつかのライブラリは、上記のサイトの方法で解決しましたが、1つ問題が起きました。

tbbのライブラリを消したら自分の環境を破壊させてしまったようで、動かなくなってしまいました。

原因を調べてみると、tbbのライブラリを消したときにpandasのmetadataも消えたようです。

pandasを再インストールしてもKernelに接続できず、結局Anacondaの環境を一から作り直しました...笑

解決した後に他の方法も探したところ、環境によりますが以下の方法で解決できるみたいなので、URLだけ貼ります。

https://github.com/tensorflow/tensorflow/issues/30191

次回、同じエラーが起きたら上記のサイトにある方法で試してみようと思います。

使い方

このライブラリにはサンプルのデータセットがあるので、そのデータを使用しました。

まず、データの読み込みをします。

from pycaret.datasets import get_data

# get_dataの引数が、用意されているデータセット
# ちなみに、diabetesは日本語で糖尿病
diabetes = get_data('diabetes')

このデータはpandas.Dataframeであり、自分が用意したデータフレームももちろん読み込めるとのことです。

データを読み込んだら、次はデータの前処理です。

コードは以下の通りです。

# 今回のタスクは二値分類(分類問題)なので
# こちらのモジュールをインポート
from pycaret.classification import *

# 回帰問題の場合は、代わりに以下の1行をインポート
# from pycaret.regression import *

# クラスタリングをしたい場合はこちらのモジュールを使用
# from pycaret.clustering import *

# setupの第一引数はデータフレーム、第二引数は目的変数
exp1 = setup(diabetes, target = 'Class variable')

コード内のコメントで、何種類かのモジュールを紹介しましたが、公式ドキュメントを読んでみると、自然言語処理用や異常検知用のモジュールもあります。(凄すぎる...!)

上記のコードを入力してしばらく経つと、以下のアウトプットが出てきます。

f:id:a7xche:20200429164631p:plain

ここで一度、各カラムのデータ型が正しく読み込めているかを確認します。

問題がなければエンターキーを押し、データ型を変えたい場合は画像の一番下にあるテキストボックスにquitと入力します。

エンターキーを押すと、前処理の結果が表示されます。

f:id:a7xche:20200429171540p:plain

実際は、40くらいの項目で表示されますが、上から15の項目を抜粋しました。

画像の通り、最初の項目はデータフレームに関する情報で、欠損値の有無、数値型データの種類数などがあります。

その下の別の項目には、数値型データの欠損の補完方法、正規化したかが表示されています。

全ての項目を紹介しきれないので、ぜひ一度触って確認してみてください。

前処理が終わったら、どのモデルで予測するか決めます。

このとき、とても便利な関数を使用します。

compare_models()

この関数を使うと、各モデルで出したそれぞれの評価指数のスコアを、Accuracyが高い順に表示されます。

f:id:a7xche:20200429203406p:plain

これらのスコアはK-foldで交差検証を行ったスコアで、デフォルトのfoldの数は10です。

関数の中に引数を入力することによって、foldの数を変えたり、優先して見る評価指数を指定することができます。

例えば、K-foldの数を5にして、優先して見たい評価指数をAUCとしたい場合は以下のようになります。

compare_models(fold=5, sort="AUC")

スコアを見比べて使用するモデルが決まったら、次はモデルの作成です。

今回は、LightGBMを使用してモデルを作成しました。

コードは以下の通りで、実行するとcompare_model()のときと同様に各評価指数のスコアが表示されます。

# 引数で使用するモデルを指定する
lgbm = create_model('lightgbm')

もちろん他のモデルでも作成できるので、作成方法を一部まとめます。

# Logistic Regression
logistic = create_model('lr')

# Naives Bayes
bayes = create_model('nb')

# CatBoost
catboost = create_model('catboost')

モデルを作成したら、以下のコードでモデルのチューニングを行います。

tuned_lgbm = tune_model('lightgbm')

モデルをチューニングした後にアウトプットとして評価指数の表が表示され、モデルを作成したときより精度が良くなっているのを確認することができます。

作成したモデルをアンサンブルしたり、スタッキングすることもできます。

# まずはモデルの作成
lgbm = create_model('lightgbm')
catboost = create_model('catboost')

# アンサンブル
ensemble_models = blend_models(estimator_list = [lgbm, catboost])

# スタッキング
# メタモデルを引数で指定しない場合、ロジスティック回帰モデルになる
stacked_models = stack_models(estimator_list= lgbm, meta_model = catboost)

モデルが完成したら、モデルの評価を行います。

先ほどチューニングしたLGBMの評価をしたいと思います。

evaluate_model(tuned_lgbm)

上記のコードを実行すると画像のように15のボタンが表示され、見たい項目をクリックすると画面が切り替わります。

f:id:a7xche:20200429224801p:plain

また、モデルの解釈をまとめたサマリーもプロットすることができます。

# こちらも先ほどチューニングしたモデルを使用
interpret_model(tuned_lgbm)

モデルの評価を確認したら、いよいよ予測です。

長々とブログの文章が続いていますが、ここまで書いた実行するのに必要なコードは10行未満です...!

では、モデルを使用して予測したいと思います。

# チューニングしたモデルを使用
# データは指定しなくても、setup()で前処理したものを使用
predictions = predict_model(tuned_lgbm)

# 結果を出力
predictions

コードを実行すると、LabelとScoreという列が右側に増えたデータフレームが出力されます。

f:id:a7xche:20200429235435p:plain

Labelは予測したラベルで、Scoreは予測値です。

以上で、基本的な使い方の説明は終わりですが、作成したモデルをクラウド上にデプロイしたり、モデルの保存もできるようです。

まとめ

データの読込みから予測まで、10行前後のコードでできました(恐るべし、PyCaret...!)

簡単に予測できるだけでなく、UIのデザインも良くて使いやすいです。

ただし、使用するモデルや評価指数の選択は知識が問われるので、なぜそのモデルを使用したのか、なぜその評価指数を採用したのかが重要になります。

また、最後に出力したデータフレームを見てみると、どうやらそんなに特徴量エンジニアリングはしていないようです。

なので、データサイエンティストという職はまだまだ必要とされそうです(安堵の表情)