paiza開発日誌

IT/Webエンジニア向け総合求人・学習サービス「paiza」(https://paiza.jp ギノ株式会社)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

データ分析初心者向け、Pythonでデータ取得&グラフ描画する方法

f:id:paiza:20170227111741p:plain
秋山です。

サービスを運営していると、いろいろなデータから必要な情報だけを取得して分析するような機会もたくさんあるかと思います。

分析に使えるツールは世の中にたくさんあるので、どれが使いやすいかは人それぞれですが、今回は「分析を始めたばかりで何をどうすればいいのかわからない…!」という方のために、Pythonを使って初心者向けのデータ分析のやり方を紹介します。

■使用する環境

paizaでは、Pythonを使ってスキルチェック問題の回答データや、ユーザーの情報等の分析をしています。(R言語を使っていたときもありましたが、私がPythonのライブラリにある便利機能を使いたかったのと、R言語があまり得意ではなかったので移行しました)

今回は、Python3がインストール済みの環境を想定しています。これから出てくるコードもPython3を推奨しています。

下記のライブラリを使用します。

  • Jupyter:ブラウザベースでコードを書いたり実行したり結果を表示したりできるツールです。
  • Numpy:数値計算ライブラリです。どちらかと言うと、分析よりも高度な計算や重たい計算に向いています。
  • Pandas:データ解析ライブラリです。データフレームを作ったり操作したりできる、R言語に近い位置づけのライブラリです。
  • Matplotlib:図の描画をするときのライブラリです。
  • Pymysql:SQLからデータを参照するためのクライアントライブラリです。

■Jupyterの起動

まず、前述のライブラリたちを入れるために、Pythonをインストール済みの環境で以下のコマンドを実行します。

pip install jupyter numpy pandas matplotlib pymysql

これで、必要なものが全てインストールされます。(Numpyは結構時間かかる場合もありますので、のんびり待ちましょう)

各ライブラリの特徴は前述のとおりですが、Jupyterはライブラリというよりも、ツールに近い位置づけなので少し解説します。「IPython」と呼ばれるインタラクティブPythonを書けるツールをブラウザで操作できるようにして、さらに便利機能を追加して拡張されたものがJupyterです。
f:id:paiza:20170227111741p:plain

まずはJupyterを起動させて、画面を見たいと思います。ターミナルを立ち上げて、Jupyter用のディレクトリを作ってその下に移動してから

jupyter notebook

とコマンドを入力してください。

ターミナル上にいろいろ流れた後、すぐにブラウザが起動するかと思います。簡単に説明すると、ターミナル上でPythonモードのJupyterが動作し、そこにブラウザが繋がった状態となります。

終了したいときは、ターミナル上で" ctrl + c "と入力し、本当に終了するのかの確認が出るので" y "を入力すれば終了します。

Jupyterをブラウザで立ち上げた時のデフォルトでは、" http://localhost:8888 "というアドレスが指定されています。同じブラウザで複数のタブを使いたい場合は、複数開いても問題ありません。(※8888というポートに関しては場合によっては別の番号になる可能性もあります)

hello world

まずはHome画面で、右上の" New ▼ "をクリックして、Notebooks の下に出てくる Python 3 (python2で実行されていればPython 2) をクリックしてください。
f:id:paiza:20170227113352p:plain

新たなブラウザが開いて、このような画面が表示されます。
f:id:paiza:20170227113543p:plain
上のUntitled をクリックすると、タイトルを変更することができます。ここではjupyter_testというタイトルにしておきます。(※もちろん好きなようにつけて大丈夫です)

ではコードを書いてみます。

In [] : の右側に出ている欄に

print("hello world")

と入力し、 control + enter もしくは、上のバーの再生ボタンをクリックしてください。入力欄の下に hello world と表示されます。

また、このとき先に開いていたアドレス( http://localhost:8888 )を見ると、 jupyter_test.ipynd という名前のファイルが表示されているかと思います。
f:id:paiza:20170227113829p:plain

このファイルは、jupyter notebookコマンドを入力したディレクトリ以下に作られています。このipynbファイルは、jupyterで扱うpythonのコードやグラフの設定などを含めた独自の形式になっています。

jupyterのipynbファイルは、セルという単位でコードやそのほかの要素の保存や実行をします。例えば、前述のhello worldを表示したセルは、Pythonとして実行するセルとなっています。ほかにも、markdownを記述するセルなどを作ることもできます。

セルを新しく挿入したい場合、例えば下に挿入する場合は、 shift + enter か、メニューにある + ボタンを押すか、InsertメニューのInsert cell Below をクリックする、上に挿入する場合は、 Insertメニューの Insert cell Above をクリックすると挿入することができます。

セルにPython以外のmarkdownなどを記述したい場合は、メニューにあるCell→Cell type→Markdownを選択してください。そこでmarkdownを入力して実行することができるようになります。


基本事項は以上となります。

pipなどを使ってインストールしたライブラリは自由に使えますので、先にインストールしたライブラリ以外にもいろいろと使いたい場合は、好きにimportして使えます。

また終了する際は、ファイル保存を忘れていると、最後の保存まで巻き戻ってしまうので、必ず保存をしてください。セルを実行したときに随時保存はされていますが、適宜メニューバーの左端にある保存ボタンをクリックしておくと安心です。

■データ分析のためのグラフ作成

では、paizaのユーザーがでスキルチェック問題を解くのにかかった時間などについての分析例を使って、実用的な使い方を解説します。(※これ以降それっぽいデータが出てきますが、記事用のダミーデータです)

ここではanswersというテーブル内に、回答時間datetimeとrank(S,A,B,C,D)がある…という形でSQL文を書いてデータを取得しています。

```
import pymysql
from pandas.io import sql
sql_str = "select rank datetime from answers"
connection = pymysql.connect(host=db_host, db=db_name, user=db_user, password=db_password, cursorclass=pymysql.cursors.DictCursor)
df = sql.read_sql(sql_str, connection)
df
```

上記のコードでは、sql_strのSQL文をconnectionで繋げたDBで実行し、結果をpandasのデータに変換して取得しています。datetimeなどは適宜変換されています。

最後の行に df とだけ記述されていますが、これがあると、jupyter上でpandasのデータをいい感じのテーブルみたいに表示してくれます。
f:id:paiza:20170227115030p:plain

例えば10万件結果が返ってきたりしても、大量に表示されすぎて重くならないように、こんな感じで中間を省いて表示してくれます。
f:id:paiza:20170227115115p:plain

※ちなみに前述のコードは、既にデータベースがある前提のものになっています。サンプルコードを試すためだけに大量のデータを用意するのは大変かと思いますが、下記のコードを実行すればランダムデータを100件生成できます。テストできるデータがない場合は前述のコードと差し替えて試してみてください。

```
import pandas
from random import choice,randint
from datetime import datetime
list_data = [(choice(['S','A','B','C','D']), datetime.fromtimestamp(randint(1485874800, 1487754616))) for i in range(100)]
df = pandas.DataFrame(list_data, columns=['rank', 'datetime'])
df
```


では、シンプルに全体のグラフを作ってみます。

まず、時間を1時間単位に分割したい場合は、pandasの機能として、datetime型であれば

df.datetime.dt.hour

というように、" dt.hour "などとすると時間の部分だけが取得できます。日単位の集計をしたい場合は" dt.day "となります。

pandasについてもっと詳しく知りたい方は、公式ドキュメントを参考にして、いろいろ書いてみてください。
pandas: powerful Python data analysis toolkit — pandas 0.19.2 documentation


さらに、ヒストグラムを生成してみましょう。シンプルにヒストグラムを作りたい場合は

df.datetime.dt.hour.hist()

とするだけで可能です。

いくつかオプションをつけるとすると、

bins= 

ビンサイズを指定します。ここでは24時間を1時間ごとにわけるので、24とします。

normed=1 

正規化されて、出現率を見ることができるようになります。

margins(x=0) 

時間単位で表示したいので両端に空白領域があるとわかりづらくなってしまいますが、詰めるためにつけています。

この辺のオプションもつけて表示させるとこんな感じです。
f:id:paiza:20170227120732p:plain
上下にmarkdownで何のグラフかなどをメモっておくと、後で見返すときわかりやすくなります。


これだけではシンプルで面白みに欠けるので、次はスキルランクごとに見てみましょう。

まずは、Sランクに絞ったグラフを作ってみます。

dfからSランクを絞り込みたい場合は

df[df['rank'] == 'S']

とするだけです。

先程のヒストグラムを作るコードを繋げて

df[df['rank'] == 'S'].datetime.dt.hour.hist(normed=1, bins=24).margins(x=0)

とすれば、以下のようなグラフが作れます。
f:id:paiza:20170227121102p:plain

ここではいろいろな絞り込み方ができます。

例えば、" | "はor演算子、" & "はand演算子として使えますので

df[df['rank'] == 'S' | df['rank'] == 'A']

とすれば、SランクとAランクのユーザーに絞り込むことができます。

また、 == 以外にも >、< などの演算子も使えますので、SQL上で絞り込んでいない要素やグラフを出し分けたい場合に活用すると便利かと思います。


では、次にS・Aと、B・Cと、Dランクの回答時間の傾向を見たい場合を考えてみましょう。

先ほど説明した絞り込みor条件を使いランクごとにわけます。

グラフを重ねて描きたい場合は、histなどを並べて書いてもよいのですが、塗りつぶしになっているものを重ねてしまうと見づらいですよね。そんなときはalphaオプションをつけて半透明にすることもありますし、半透明でも色が重なって何色かわかりづらい場合は、histtypeをstepとして線だけ表示させることもできます。

colorで色を設定して、他は先のグラフと同じオプションなどをつけるとこのようなコードになります。

df[(df['rank'] == 'S') | (df['rank'] == 'A')].datetime.dt.hour.hist(histtype='step', normed=1, color="#ff0000", bins=24).margins(x=0)
df[(df['rank'] == 'B') | (df['rank'] == 'C')].datetime.dt.hour.hist(histtype='step', normed=1, color="#00ff00", bins=24).margins(x=0)
df[df['rank'] == 'D'].datetime.dt.hour.hist(histtype='step', normed=1, color="#0000ff", bins=24).margins(x=0)

実行すると、以下のような結果が得られます。
f:id:paiza:20170227121501p:plain

食事の時間帯は受験者数が減っているとか、S・Aは仕事や食事が終わるころのタイミングで受けている人の数が他のランクより突出しているとかいった傾向が出ていますね。

このような結果が出れば、例えば仕事や食事が終わったタイミングでスキルチェック問題を解くとS・Aランクが取りやすくなるのか?という分析ができたりしますね。(※先ほども言いましたが、これはダミーデータになりますので実際にそのような傾向があるわけではありません)

■まとめ

データ分析やグラフ表示というとR言語を使っている方も多いと思いますが、「R言語難しい……」という方や、私のようにPythonが好きな方はぜひ試してみてください。

これまでにもPythonについていくつか記事を書いております。あわせて勉強したい方はぜひご一読ください。
paiza.hatenablog.com
paiza.hatenablog.com

ちなみに、「やっぱりR言語を勉強したい」という方は、過去にこんな記事もありますので参考にしてみてください。
paiza.hatenablog.com


「データ分析どころかプログラミング自体が初心者なので、Pythonを基礎から学びたい!」という方は、プログラミングが動画で学べる「paizaラーニングPython入門編から始めてみると、無理なく基礎を習得できると思います。
paiza.jp

Pythonの講座も公開中!プログラミングが動画で学べるレッスン


paizaは、プログラミング未経験者・初心者向け学習サービス「paizaラーニングを、新サービスとして独立オープンいたしました。

今回記事の中で使用しているPythonの入門講座も好評公開中です。ぜひごらんください!

↓詳しくはこちら
paiza.jp




paizaは、技術を追い続けることが仕事につながり、スキルのある人がきちんと評価される場を作ることで、日本のITエンジニアの地位向上を目指したいと考えています。

自分のスキルを磨いていきたいという方におすすめなのが「paizaラーニング」。オンラインでプログラミングしながらスキルアップできる入門学習コンテンツです。初心者でも楽しくプログラミングの基本を学ぶことができます。
paiza.jp
そして、paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
paiza.jp
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

ITプログラマ・エンジニア向け転職・就活・学習サービスのpaiza