タイトルって難しい。

学力も体力もない人間の雑記帳。

改訂2版 データサイエンティスト養成読本 さくっとレビュー

はじめに

これは技術書献本大感謝 Advent Calendar 2016 9日目の記事です。

qiita.com

改訂2版 データサイエンティスト養成読本をご恵贈いただきました。ありがとうございます。保存用、観賞用、布教用のうちの観賞用として使用しています。
今後ともよろしくお願いします。

改訂2版 データサイエンティスト養成読本 [プロになるためのデータ分析力が身につく! ] (Software Design plus)

改訂2版 データサイエンティスト養成読本 [プロになるためのデータ分析力が身につく! ] (Software Design plus)

内容

巻頭企画:データサイエンティストの仕事術
 第1章:データサイエンティストに必要なスキル
 第2章:データサイエンスのプロセス
 第3章:「ビッグデータインフラ」入門

特集1:データ分析実践入門
 第1章:Rで統計解析をはじめよう
 第2章:RStudioでらくらくデータ分析
 第3章:Pythonによる機械学習
 第4章:データマイニングに必要な11のアルゴリズム

特集2:マーケティング分析本格入門
 第1章:Rによるマーケティング分析
 第2章:mixiにおける大規模データマイニング事例
 第3章:ソーシャルメディアネットワーク分析

特別記事:Fluentd入門

特別企画:データ分析のためにこれだけは覚えておきたい基礎知識
 第1章:SQL入門
 第2章:Webスクレイピング入門
 第3章:Tableau実践入門

さくっと評価

良い点

ある程度プログラムを書いたことがある人ならば、データ分析に関連する「〜したい!」という目的を達成する際に良い道標となると思います。
また、本書は比較的「浅く広く」という内容であり、「深く狭く」ということを求めている人には不向きかと思われます。
加えて、ある程度データ分析に携わってらっしゃる方から見ても、新しい発見を得られるのではないかと思います。私自身、データ分析を生業としている人間ではないですが、「なるほど、これに〜が使えるな!」とか思うことが多かったです。さらに、実際にサンプルのコードが記載されていること、そして(実際に運用で使われる際に)必要十分な説明がなされていることも良い点だと思います。
また類書にはない、Tableau入門や、Webスクレイピング入門など幅広く扱っている点も良いところかと思います。幅広いとはこのことを言うのでしょう。

うーんな点

正直、エンジニアだとか、データ分析またはプログラムを書いたことない人には辛すぎるかなという感じがします。
対象読者層の範囲外だから仕方ないといえばそうかもしれませんが、「とりあえず今からデータサイエンティストになるぞ!(宣言)」な方には辛いかなと思います。
それぞれのツールや統計的手法についてもう少し基礎的な面から理解するには別書が必要かと思います。
今後、初心者向けに何かの本があれば、その次に読むべき本として紹介できるかと。(そういう本が出ることを期待して)

おすすめのところ

特集1のデータ分析実践入門です。データマイニングに必要なアルゴリズムを網羅しているだけでなく、本書では珍しくPythonを使った機械学習をしてみたり…(基本的に本書では、Rでのデータ分析がメインだと思います)。
まだ学生ということもありその目線で書きますと、学生でまだデータ分析の理論の一部を習っただけの方、もしくは全く何も知らないという方にぜひ読んで欲しい部分かと思います。もちろん、これだけが全てではないですが、何をすべきか、何を勉強するとよいかのヒントが得られると思います。

最後に

みなさん是非買いましょう。え?まだだって?
下のリンククリックすれば買えますよ!!

改訂2版 データサイエンティスト養成読本 [プロになるためのデータ分析力が身につく! ] (Software Design plus)

改訂2版 データサイエンティスト養成読本 [プロになるためのデータ分析力が身につく! ] (Software Design plus)

今回はさくっと書評しましたが、〜のファッションチェック並の書き方でも良いかななんて思いました。
また献本してくださる優しい方がいらっしゃるといいですね…。

データサイエンスLT祭り 2夜目 にて発表を行いました(報告)

お久しぶりです。最近は研究室にてずっと作業をしています。
さて、データサイエンスLT祭りというイベントがありまして、そちらで発表しました。
発表内容は、マッチングアルゴリズムについてで、この内容に興味を持ったのは、たまたま実験を回しているときに適当に読んでいた論文の1つに、今から紹介するマッチングアルゴリズムをとある着眼点から応用したもので、面白かったためです。
そちらの論文の内容については今回の話とは無関係なので割愛しますが、実際に手を動かしながら理解するのはやっぱり楽しいなあと思った次第です。

スライドは↓です。ネタ要素が強いですが、実際のアルゴリズムの流れあたりは(僕の割には)頑張った方(?)なので、ぜひ。

【C++】配列とVectorとArrayで比較

きっかけ

以前、C++で実装した際に、コードを読まれた方からなんでVectorにしないの?と聞かれたことがありました。
機能面での違いはたしかにありますが、固定サイズならば別に配列でもOKではと思っていたのですが、ふと気になったので調べてみました。

比較対象

比較した方法は次の4通りです。

  • 配列(一番最初に習うであろうもの)
  • Vector(配列っぽく)
  • Vector(push_back)
  • Array(C++11から追加されたもの)

Vector同士で比較しているのは、配列っぽく使うパターンと、push_backで代入させた場合のものの2種類です。
push_backは遅いと書いていらっしゃる方もいたので、比較として入れてみようと思い、含めました。

コード

ダメダメながらも書いたコードは次に続きます。
やったことはすごく単純で、10万のデータを作って、そのデータから総和を求めるという操作です。
もっと良いベンチマークがあるかもしれませんが…。

配列(一番最初に習うであろうもの)

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <chrono>

int main(int argc, char const *argv[]) {
  std::chrono::system_clock::time_point start, end;
  double elapsed;
  const long int MAX = 100000;
  long int a[MAX+1];
  // Array
  start = std::chrono::system_clock::now();
  for (long int i = 0; i <= MAX; i++) {
    a[i] = i;
  }
  long int sum1 = 0;
  for (long int i = 0; i <= MAX; i++) {
    sum1 += a[i];
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cout << elapsed << "μs" << std::endl;
  return 0;
}

↑の修正版

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <chrono>

int main(int argc, char const *argv[]) {
  std::chrono::system_clock::time_point start, end;
  double elapsed;
  const long int MAX = 100000;
  long int a[MAX+1] ={};
  // Array
  start = std::chrono::system_clock::now();
  for (long int i = 0; i <= MAX; i++) {
    a[i] = i;
  }
  long int sum1 = 0;
  for (long int i = 0; i <= MAX; i++) {
    sum1 += a[i];
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cout << elapsed << "μs" << std::endl;
  return 0;
}

Vector(配列っぽく)

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <chrono>

int main(int argc, char const *argv[]) {
  std::chrono::system_clock::time_point start, end;
  double elapsed;
  const long int MAX = 100000;
  std::vector<long int> b1(MAX);

  // vector(like Array)
  start = std::chrono::system_clock::now();
  for (long int i = 0; i <= MAX; i++) {
    b1[i] = i;
  }
  long int sum2 = 0;
  for (long int i = 0; i <= MAX; i++) {
    sum2 += b1[i];
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cout << elapsed << "μs" << std::endl;
  return 0;
}

Vector(push_back)

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <chrono>

int main(int argc, char const *argv[]) {
  std::chrono::system_clock::time_point start, end;
  double elapsed;
  const long int MAX = 100000;
  std::vector<long int> b2;
  // vector(push_back)
  start = std::chrono::system_clock::now();
  for (long int i = 0; i <= MAX; i++) {
    b2.push_back(i);
  }
  long int sum3 = 0;
  for (long int i = 0; i <= MAX; i++) {
    sum3 += b2[i];
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cout << elapsed << "μs" << std::endl;
  return 0;
}

Array(C++11から追加されたもの)

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <chrono>

int main(int argc, char const *argv[]) {
  std::chrono::system_clock::time_point start, end;
  double elapsed;
  const long int MAX = 100000;
  std::array<long int, MAX> c;
  // C++11's Array
  start = std::chrono::system_clock::now();
  for (long int i = 0; i <= MAX; i++) {
    c[i] = i;
  }
  long int sum4 = 0;
  for (long int i = 0; i <= MAX; i++) {
    sum4 += c[i];
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cout << elapsed << "μs" << std::endl;
  return 0;
}

↑の修正版

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <chrono>

int main(int argc, char const *argv[]) {
  std::chrono::system_clock::time_point start, end;
  double elapsed;
  const long int MAX = 100000;
  std::array<long int, MAX> c = {};
  // C++11's Array
  start = std::chrono::system_clock::now();
  for (long int i = 0; i <= MAX; i++) {
    c[i] = i;
  }
  long int sum4 = 0;
  for (long int i = 0; i <= MAX; i++) {
    sum4 += c[i];
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cout << elapsed << "μs" << std::endl;
  return 0;
}

結果

単位はすべて、μsことマイクロ秒(100万分の1秒)
rev2とついてるものは修正版です。

Ruby@Kotori-no-MacBook-Pro ~/Desktop $ ./array.out
792μs
Ruby@Kotori-no-MacBook-Pro ~/Desktop $ ./array_rev2.out
489μs
Ruby@Kotori-no-MacBook-Pro ~/Desktop $ ./vector_like_array.out
603μs
Ruby@Kotori-no-MacBook-Pro ~/Desktop $ ./vector_push_back.out
2962μs
Ruby@Kotori-no-MacBook-Pro ~/Desktop $ ./array_cpp11.out
827μs
Ruby@Kotori-no-MacBook-Pro ~/Desktop $ ./array_cpp11_rev2.out
528μs

やっぱりpush_backは遅いですね。
Vectorを配列っぽく使うと配列と変わらない速度みたいです。
あと意外にもC++11から追加されたArrayはわずかながら配列より遅いみたいです。なぜでしょうか。
と思っていましたが、初期化を行ったうえで再実験行ってみたら配列が一番高速でした。次に、Array(C++11以降)が速いという結果となりました。

まとめ

今後はVectorを配列っぽく使います。
いや、修正した結果、配列が速かったのでやっぱり配列が一番ですね。

追記1(2016.07.09 0:27 UTC+9)

一部のコードを修正前のものを記載していました。修正しました。
なお、結果は修正後のものを記載しているため、変化ありません。

追記2(2016.07.09 0:52 UTC+9)

研究室の先輩(id:togatogah)から、「配列とArray(C++11以降)の初期化されていない可能性があるのに対し、Vectorは構築時に必ず初期化を行うので、配列とArrayを初期化してみてはどうか」という提案がありました。
そこで試してみたところ、大きく結果が変わりました。 id:togatogahさんありがとうございました。

プログラミング言語C++第4版

プログラミング言語C++第4版

【ネットワーク分析】 #1 グラフってなんぞや

最近真面目な投稿をしていないので、ネットワーク分析とかグラフ理論とかその周辺のアルゴリズムとかについてシリーズっぽくゆるゆると記述していこうと思います。
本シリーズでは、「ネットワークだぁ?グラフだぁ?全く知らないよ!」って方を対象に書いていくつもりです。

ネットワーク分析とは

ネットワーク分析とは、グラフ理論におけるグラフで表現したものに対する分析方法です。
対象となるデータは幅広く、SNSの繋がりとか感染症の伝搬だとか色々あります。

そもそもグラフとは

グラフ理論のグラフとかドヤ顔で言われてもわかんないですよね。いやそれが普通だと思います。
グラフとは、頂点(またはノード、V: Vertex)と辺(または枝、E: Edge)で表されるものと定義されています。
それらの集合を数学っぽく記述すると、
 V = \left\{v_1, v_2, \ldots , v_{N-1}, v_N \right\}
 E = \left\{e_1, e_2, \ldots , e_{M-1}, e_M \right\}
となります。これは、頂点N個と、枝M本の集合を表すという具合です。
頂点は、何か物(?)を示し、枝はその物々の繋がりを示します。
身近な例で言うと、高速道路の出入り口が頂点、高速道路そのものが枝だと考えたらわかりやすいかと思います。

f:id:cancolle:20160217213532p:plain
図1: 簡単な例・首都高のサイトより 引用元: http://search.shutoko.jp/

有向グラフと無向グラフと次数

グラフと言っても2種類あります。有向グラフと無向グラフです。
何が違うのかといいますと、有向グラフは向き(方向)が指定されており、無向グラフは向きが指定されていません。
また、頂点に接続している枝の数のことを次数といいます。
有向グラフにおいては、出次数(でじすう)と入次数(いりじすう)の2つが存在します。

無向グラフ

無向グラフとは、簡単に言うと、頂点間を結ぶ枝向きが指定されていないグラフです。
データセットとかのサイトに行くと、undirectedと記述されているものがそれです。
簡単な図で示しますと、以下の図2です。
f:id:cancolle:20160217211927p:plain
図2: 私が描いた無向グラフ

この図1では、
 \{v_1, v_2\}, \{v_1, v_3\}, \{v_1, v_4\}, \{v_2, v_3\}, \{v_2, v_4\},\{v_2, v_5\}, \{v_3, v_4\}, \{v_4, v_5\}
という枝があることが分かります。
次数ですが、 v_1から順に
3, 4, 3, 4, 2
となっており、最大次数は頂点 v_2 v_4における4となります。

てか、図汚いですね。はてなフォトライフめ・・・。

有向グラフ

有向グラフとは、簡単に言うと、頂点間を結ぶ枝向きが指定されているグラフです。つまり、どこからどこに向かって、枝があるのか…というのが表現できます。
データセットとかのサイトに行くと、directedと記述されているものがそれです。
簡単な図で示しますと、以下の図3です。
f:id:cancolle:20160217211937p:plain
図3: 私が頑張って描いた有向グラフ

このグラフですと、 v_1がモテモテですね。

出次数ですが、 v_1から順に
0, 4, 2, 2, 0
となります。
これは、点から出て行く枝の数を表します。わかりやすく言うと、何人に向けてラブレターを書いたかみたいな感じですね。

一方、入次数は v_1から順に
3, 0, 1, 2, 2
となります。
これは、店に入ってくる枝の数を表します。わかりやすく言うと、何人からラブレターをもらったかという感じですね。

隣接行列

グラフには、その隣接関係を示す隣接行列というものがあります。
簡単に言うと、どことどこがつながっとんねんって話です。
行、列ともに頂点集合に対応しています。
ちなみに、蛇足ながら書くと領域計算量は O(n^2)です(頂点の数をnとした場合)。

無向グラフにおける隣接行列

図2の例を元に隣接行列を書くと、

 
\begin{pmatrix}
0 & 1 & 1 & 1 & 0 \\
1 & 0 & 1 & 1 & 1 \\
1 & 1 & 0 & 1 & 0 \\
1 & 1 & 1 & 0 & 1 \\
0 & 1 & 0 & 1 & 0 \\
\end{pmatrix}

となります。
無向グラフの場合、双方の向きを考慮しないため、行列は対称となります。

有向グラフにおける隣接行列

図3の例を元に隣接行列を書くと、

 
\begin{pmatrix}
0 & 0 & 0 & 0 & 0 \\
1 & 0 & 1 & 1 & 1 \\
1 & 0 & 0 & 1 & 0 \\
1 & 0 & 0 & 0 & 1 \\
0 & 0 & 0 & 0 & 0 \\
\end{pmatrix}

となります。
有向グラフの場合、向きを考慮し、それを隣接行列でも表現するため、行列は非対称となります。
行方向に攻め、列方向に受け、と考えると簡単だと思います。

今回のまとめ

簡単な事項について取り扱いました。
ループとか、重みとか、接続行列とか色々すっとばしていますが、今回はここまで…。

RかPythonで業界地図を作る(作りたい)

世間では就職活動というものが行われています。
かくいう私も就活生。来月から説明会ラッシュになりそうで、今からスタミナが切れそうな予感しかしてません。

就活生必須アイテム(?)とやらの1つに業界地図という本があります。
それぞれの業界について、資金の流れだったり、株の保持の数値だったりで、相関図を描いてるという本です。
自分自身で買いたいとは思わないのですが、本屋で立ち読みして「へえ〜」と思うことも多いです。
ここで、ふと、私の研究分野について思い出してみました。
私の研究分野はいわゆるネットワーク分析(グラフ理論)です。
そう、こんなことを思いつきました。

「まてよ?株の保持数とかをデータとして落としこめば、グラフ理論におけるグラフでそれって表現できるのでは?」

早速データ探しの旅へ。

・・・見つからない・・・・・・

一応、ページをスクレイピングすればできそうですが、できればスクレイピングは避けたいところ。

いやでも避けられないか。

ということで今後の構想としては、

  1. APIを見つける(絶望的)
  2. rvest/Beautiful Soupでスクレイピングを行う
  3. igraph/networkxで頑張る

という感じです。

「次回、なにかやる。」お楽しみに。

日経業界地図 2016年版

日経業界地図 2016年版

新詳高等地図 (Teikoku’s Atlas)

新詳高等地図 (Teikoku’s Atlas)

音楽から見たこの1年 改め 音楽から見た去年の1年

あけましておめでとうございます。
去年せっかく書き起こしていたのに公開するのを忘れていましたので一部修正した上で公開します。

去年1年間で再生した回数が多かったもの、単純に衝撃をうけたものなどを振り返るだけの記事です。

修羅場 by 東京事変

東京事変はもともと椎名林檎が好きなので聞いていたのですが、何故かこの修羅場という曲はずっとスルーしてたのに急に惹かれたという感じです。


東京事変 - 修羅場

水星(instrumental) by tofubeats

本来ならば歌詞ありの方を推すんですが、僕自身はトラックの良さに惹かれたのであえてinstを。


tofubeats - 水星 (suisei) instrumental

Luv(Sic) pt.3 by Nujabes Feat. Shing02

ほぼ毎年上位に入ってる曲です。たぶん高校2年からずっと聴き続けてる気がします。
シリーズ物なんですが、僕としてはpart3の方がJazzyな感じがして好きです。


Nujabes - luv (sic.) pt 3 [ft.shing02]

キラーボール by ゲスの極み乙女。

Amazon Musicでたまたまみつけてきいてみたら、イントロで即ヤラれました。
そういえば紅白に出るんですね --> 出てました。


ゲスの極み乙女。 キラーボール

トレンチコートマフィア by DJ 松永 Feat. R-指定

たぶん2015年で唯一iTunes Music Storeで購入した曲です。
曲としては、高校生とかの頃にある、おもろいやつとか目立つ奴がパッとしててそうじゃない人間側はパッとしないということへの不満と生き残りをテーマにした曲です。
ちょうどこの曲を知ったのは、自分があることですごく不満を持っていて、どうしてって思うことが常にあった時期でした。
分かる人には共感が得られる・・・といった具合でしょうか。


トレンチコートマフィア feat.R指定 / DJ松永

そう、2015年にリリースされた曲がない…。いや聞いてたんですけどなんか何も来なかったというか。
来年はたぶん書かないだろうなあ --> 今年はたぶん書かないだろうなあ。

恋のアクセス解析

恋のアクセス解析

人は音・音楽をどのように聴いているのか

人は音・音楽をどのように聴いているのか

2015年を振り返ってみる

2015年も残り僅か。
今年もツイートと共に振り返っていきたいと思います。

昨年は簡単に振り返りましたが、今年はイベントが多かったのでもっと細かく書きたいと思います。
can.hatenadiary.com

1月

卒論の提出と、卒研の発表練習で追われてた毎日でした。
プライベートでのトラブルが立て続けに起きたこともあって結構疲れてました。
あと、初めてTokyo.Rで発表したのもこの時でしたね。

2月

現在所属している大学院の冬入試があり、翌週に合格しました。
そこから、進学予定だった大学院の辞退届提出とか色々手続きでバタバタしていました。

3月

ハッカソンとかサークルの春合宿とか追いコンとかありましたが、やはり卒業式が印象深かったです。
学部の4年間、本当に色々やってきたので楽しかったですね。

4月

入院しました(大学院に入学しました)。

5月

Mac買ったり、プロ生でLTしたり五月祭に行ったり。

6月

インターンのESを書き始めたり、面接に行ったりしました。

7月

77円のUSBメモリを買いました。 https://twitter.com/wonder_zone/status/618295861496295424

8月

インターンシップに行ってました。

9月

インターンシップに行ってました。
あとTokyo.RでLTをしたりしました。また、某合宿に行きました。

10月

このくらいの時期からJapan.Rを宣伝するようになりました。

11月

サークルOBとして学祭に行ったりしました。

12月

Japan.Rをしました
ブシロードライブに行きました(今年行ったイベントはこれだけ)。
実家に帰省して、高校の同窓会行きました。

今年は、色々充実した1年間でした。
生活基盤が変わったこともあり、色々大変でしたがその分楽しめました。

それではみなさん良いお年を。