すのふら

すのふら

日々の備忘録

ソフトウェアテスト技法からテストを再勉強する。その1

社会人になってからテスト周り任されることが多く、ただ経験ベースでしかテストを語れなかったので、以下の本を読んで勉強中。

はじめて学ぶソフトウェアのテスト技法

はじめて学ぶソフトウェアのテスト技法

一度通して読んだ上で再度最初から見直しているので、内容をメモ程度に残しておく。


そもそもテストとは

実際どうなっているか、本来はどうあるべきかを比較するプロセスである。
IEEE 610.12-1990 では

ある特定の条件下でシステムまたはコンポーネントを操作するプロセスであり、その結果を観察または記録して、システムまたはコンポーネントのある側面を評価すること

「ある特定の条件下」をテストしたい対象の条件としたものをテストケース。


テストケース

テストケースは3点で構成されている。

  1. INPUT
  2. OUTPUT
  3. 実行順番

INPUTがあって、それに対して実行順に沿って処理をおこなってOUTPUTが出力される。
それを正しく評価することで、要件または実装が正しいのか間違っているのか判断できる。

また、テストケースがまとまったものがテストスイートになる。


テストスイート

テストケースでは単一のチェックしか基本しないので、他にも観点があるのであればテストケースを追加していって、このテストケースの塊実行したら正しいと担保できるぜってなった際のテストケースの塊。

テスト対象のコンポーネント又はシステムのためのいくつかのテストケースのセット。一つのテストの実行事後条件は、次のテストの実行事前条件としてよく利用される。
ソフトウェアテスト標準用語集(日本語版)

 ソフトウェアテスト(動的テスト)の最小単位はテストケースといえるが、実際にテスト作業ではいくつものテストケースを組み合わせることによって不具合をあぶり出したり、確率的に十分なテストを行ったという結論を出したりする。このようなテスト目的やテスト対象に応じて、多数のテストケースを束ねたものをテストスイートという。

テストスイート(てすとすいーと) - ITmedia エンタープライズ


INPUT

INPUTは、キーボードからの入力データや、ファイルやデータベースのデータなど、テストするにあたって事前に用意しておかなきゃいけないもの。
あるテストを行おうとしたとき、結果を得るために事前にやっておく仕込みの作業。


OUTPUT

OUTPUTはそのままある程度の結果のこと。OUTPUTが画面上に表示された結果や、データベースへ書き込まれたデータ、外部機能へのデータ連携、ログなど、「何かをした結果出てくるもの」のことを指す。

その沢山ある結果の中で「何がどうあれば正解」なのかは5パターンで定義できる(らしい)


子供のオラク

単純にプログラムを実行して結果を眺める。
なんとなく正しそうなら正しいっていう、結果が明示できてないやつ。


回帰テストのテストスイート

プログラムを実行して、以前のバージョンのプログラムに適用したテストケースの結果を今回の結果と比較する。

主に保守運用フェイズで用いられるもの、経験上保守している機能に対し、会社の横展開をしたいぜってパターンもそれにあたる。

これをやらないと、今まで出ていた結果がでず本番環境で障害が起こってえらい目に遭う。


正当性が実装されたデータ

プログラムを実行して、テーブル、公式、その他の正当な出力の定義として認められた基準とプログラムを実行した結果の出力を比較する。

これはちょっとよく分からない。


市販のテストスイート

既存の検証済み標準テストスイートに対してプログラムを実行する。

標準でテスト機能を備えているものがあって、それを実行したらいいようなものかな。

市販ではないが、プロジェクトでアーキを作ったときにテスト標準みたいなのを作った。
新規機能を作ってもそのテストを通過すると概ね問題なしみたいなやつ。


既存のプログラム

プログラムを実行して、その結果を異なるバージョンのプログラムでの結果と比較する。

SalesforceとかのSaaSを使用した際のテストに当たるのかなあ。
Salesforceでは年4回のバージョンアップで影響が大きい場合、一時的に有効してテストして、バージョンアップ前と同じ結果になるかどうかを確認する場合があるので。


実行の順番

テストケースを実施するにあたって、前後に依存がある場合、独立できる場合が存在する。

前後に依存がある場合、データの用意→テーブルからRead→テーブルへwrite→テーブルからRead→テーブルからDeleteみたいな一連の流れがある。

上の場合、Readするのにwrite用とdelete用を別に作らなくていいとう利点があるが、Deleteがうまくできないみたいな状況になった際にwriteからやり直しみたいな状況もあり手戻りがでかい。

独立できる場合、パラレルでテストできるので、複数人でできる場合もあるのでテストが早く済む。欠点はテストケースが大きくなりがちで、設計・作成・メンテナンスが大変


テストの種類

ブラックボックステストホワイトボックステストが存在する。


ブラックボックステスト

テスト対象ソフトウェアの内部パス、構造、実装に関わる知識が不要であるのが利点。

要件からINPUT情報を用意する形になるので、実装されているコードの知識は必要なし。
ただ、INPUTしたOUTPUTしかわからないので、一旦中で何をしているかが分からない。


ホワイトボックステスト

テスト対象ソフトウェアの内部パス、構造、実装に基づいてテストを実施する。

実装に基づいてテストするということは、実装されているコードの詳細を理解できる力が必要。要件についての知識は不要。


テストのレベル

テストのレベルは通常4つのレベルで実施される。

テストは経験上、Vモデルあることが多い。
基本設計と詳細設計が一緒になっていることがあるので、そのときはシステムテスト結合テスト同じスケジュールに入ったりする。

Vモデル(V-Model)とは、IT製品開発の手法の一種。ドイツ政府と軍関係のプロジェクトで標準として採用されている。また、一般に利用可能であるため、様々な企業でも使われている。プロジェクトマネジメント手法としては、PRINCE2に匹敵する。また、システム開発やソフトウェア開発の手法としても使われている

Vモデル - Wikipedia

f:id:snofra:20180804005404p:plain

設計とテストが紐づいているので、粒度も各設計に合わせる必要がある。
ここで下の粒度のテストがテストコンディションにあると、かなり違和感があるし指摘されるので気を付けたほうがいい。


単体テスト

作成した機能(サブシステム)の最小単位でのテスト。
自分が作った機能のみに閉じたテストを行う。1部品のテスト。

普通、要件を満たす機能を作るとなると自分が作った1機能だけではなく、他機能とのつながり、外部機能とのつながり等あるがそこは一旦考慮しない。

以前新人の子に質問されたことがあるんだが、他の機能から来たデータをINPUTにする場合、そのINPUTデータは自分が要件or設計書で想定されているデータが正として自前で作るなりして実施してよい。
本当に要件or設計書通りのデータ来るよね?なテストは内部結合テストに当たるので、テスト粒度が違う。


統合テスト

いわゆる結合テスト
単体テストでも書いたが、ある要件を満たすために作成した複数のサブシステム(部品)を結合して、ひとつの要件に沿って行うテスト。

内部のサブシステム同士であれば内部結合テスト、外部システムとのデータ連携等が必要であれば、外部結合テストを行う。

ここで発覚するのは大体、連携元のデータがデータ型が違っていたとか、想定外のデータがきたとかそういうパターンのものが多い。


システムテスト

いわゆる総合テスト。

最も高いレベルの統合時に起こる結果に焦点を絞っています。普通、システムテストには様々なタイプのテストが含まれています。それは機能性、ユーザビリティ(使いやすさ)、セキュリティ、国際化、ローカライゼーション、信頼性、可用性、大容量、パフォーマンス、バックアップと復元、その他もろもろのテストです。

ざっくり書きすぎて全然わからないが、経験上ほぼ本番同等の状態で業務に即したテストケースでやられているかと。

パフォーマンステストもここに割り当たるのかな?データ連携されるのであれば、連携されるファイルやデータサイズが想定される最大数か、それよりも少し大きいくらいで連携テストすることが多いかなと。


受け入れテスト

UATとも。
ここのテストのメインはユーザ側。ここも本番想定の環境か本番環境をそのまま使うことが多いのかなー。

ここまでにテストの改修が間に合わない場合、経験上順番に開放するという逃げの戦法もある。というかそういうこともあった。


もっと勉強するならJSTQBの資格を取ったほうがいいなあ。
正直概要は意味がちょっと分からない箇所もあるし。
資格とらなくてもいいからこの本買うかなー。

ソフトウェアテスト教科書 JSTQB Foundation 第3版

ソフトウェアテスト教科書 JSTQB Foundation 第3版

  • 作者: 大西建児,勝亦匡秀,佐々木方規,鈴木三紀夫,中野直樹,町田欣史,湯本剛,吉澤智美
  • 出版社/メーカー: 翔泳社
  • 発売日: 2011/11/12
  • メディア: 単行本(ソフトカバー)
  • 購入: 5人 クリック: 85回
  • この商品を含むブログ (12件) を見る

アイカツフレンズ!の無料放送始まってます!

f:id:snofra:20180125132445j:plain

夏休みスペシャル無料配信ということで、4話ずつ無料配信してます(1週間毎に4話ずつ追加)*1

4話ずつの無料配信は3週間限定なので、取り敢えず1~4話を2018年8月2日(木)18:59までに見よ?2時間かからないよ

www.aikatsu.net


アイカツ!」シリーズ見たことないって人、今が見るいい機会なので見よう!

アイカツスターズ!』が『アイカツ!』とちょっと違うなって離れてしまった人、アイカツフレンズ!』はそんな人でもカムバックできます!

アイカツスターズ!』ロスな人、俺もそうだがもうぼちぼち前向いていこ?

アイカツ!」の歌って声優さんが歌ってないよね?な人、アイカツフレンズ!』では声優さんが歌唱担当も兼任しました!田所あずさ大橋彩香の歌を聞こう!エンディングなので毎回聞けます!

アイカツ!」の歌がAIKATSU☆STARS!、STAR☆ANISじゃないと駄目だろな人、俺もそうだがもうぼちぼち前向いていこ?

1話~4話

無料期間:2018年7月19日(木)19:00~2018年8月2日(木)18:59


アイカツフレンズ! 第1話 ハロー フレンズ!


アイカツフレンズ! 第2話 無敵のラブミーティア☆


アイカツフレンズ! 第3話 ビビっとインスピレーション


アイカツフレンズ! 第4話 憧れのマイブランド


5話~8話

無料期間:2018年7月26日(木)19:00~2018年8月9日(木)18:59


アイカツフレンズ! 第5話 蝶のように 舞花!


アイカツフレンズ! 第6話 日向エマージェンシー!?


アイカツフレンズ! 第7話 ミライへ続く道★


アイカツフレンズ! 第8話 みおのCM大作戦!

*1:1話は随時無料配信

RedshiftのVACUUMが実行されていないテーブルがあった

VACUUMで俺の無知が炸裂したのでメモしておく。

Redshiftのデータ更新は追記型のため、Deleteしても見た目上は消えていてもディスク上にデータが残りっぱなしになっているので、その不要な領域を削除・再ソートしてあげる必要がある。

そのためにテーブルをVACUUMしてあげる必要があるんだが、ソート率が3%くらいの比較的ソートされていると言っていいテーブルが、ソートされてなくてあれ何でされていないんだろう?となった。

想定だと以下のようなSQLを実行すると、データベースのテーブルに関する概要情報を表示すシステムテーブル「svv_table_info」のunsortedが0になっているはずだけど、何故か0にならない。
SVV_TABLE_INFO - Amazon Redshift

select unsorted from svv_table_info where "table" = '[テーブル名]'


あれ何でだろうと調べた結果、VACUUMされる条件がソート率が95%以下の場合だったから。
上記のパターンだと3%だったので、処理されないので0にならない。

95 パーセント以上がすでにソートされているテーブルのソートフェーズをスキップします

VACUUM - Amazon Redshift

次の打順が自分に回ってくるための努力『天才はあきらめた』を読んだ

天才はあきらめた (朝日文庫)

天才はあきらめた (朝日文庫)

山里亮太の不毛な議論リスナーであるってこともあり、発売日に買って読んでみた。
大学入学から吉本総合芸能学院NSC)への入所、コンビの結成と解散、南海キャンディーズの結成としずちゃんとの不和を残り超えた今までが書かれた本。

ラジオリスナーであればだいたい聞いたことのあるエピソードが多いのだが、実際本で読むと真摯な気持ちが書いてあってまた違う印象を得たかなと。

努力の天才

本の中で自分は天才ではなので努力を続けるしかなかったという点で、どういう努力したのかということを書いていたりするが、そういう積み重ねを習慣化できているということ自体天才なんじゃないかなと思う。

自分が薄っぺらい人間だと痛感させられる。しかし、その痛みを努力に変換する。駄目だからやらないのではなくて、駄目な自分だからこそ努力量を増やさないといけない。
こうすると、そう思えた自分のことをすごいと褒めてあげられるし、何よりシンプルに人の意見をしっかり聞ける。駄目な時はこれを頭において乗り越えてきた。

マイナスの出来事をフェードアウトさせるのではなくて、反省点として自分にとどめるそして自分を褒めるという考え方ができるのは素直にすごいと思える。

この本のなかで出てくる自信貯金というものにもつながってくる山里亮太の根本の考え方なんだなと。


自信貯金

自信貯金っていうのは以下を貯金という名目で心の中に留めておいて、壁にぶつかったときに使用することで心の安定を保つというもの。

  • 小さな出来事、自画自賛でも構わないので自分の目的に即した行動であれば自らをほめる
  • 人に褒められた

自分が駄目だなって無駄な悩む時間を短縮するために使って、短縮したことを褒める。そして簡単な作業をして自分を褒める。
そういう自分をいかにモチベーションを維持するしていくかってことだと思っている。

普段生活していて基本他人から褒められることがなく、周りの芝の青さを見ることが多いこともあって、以下に自らを褒めていくのかっていうのは大切なのかもしれないなと。

そしてその自信を使って自らの退路を断っていく、自分が逃げないための言い訳を作っている。
今までの自身から多分大丈夫なんじゃないかって、根拠はないがそれで自身を奮い立たせること、それって『SHIROBAKO』でも言っていたなと。

あなたに足りないのは、自信と覚悟だね。失敗も貴重な財産でしょうが。若者が根拠の無い自信持たなくて何を持つんだっつーの!


結果を出した後に来るのはご褒美ではなくチャンス

それでやってくるものがご褒美ではなく、チャンスであるというものもその通りなんだろうなと思う。

新しい道が開けているだけで、それはボーナスゲームでもなんでもなくて打順が回ってくるようになっただけで成果を出さなければ、チャンスは失われてしまう。

その時に凡打でも打てるように準備するのが努力で、努力するためには自信で、自信を逃げない理由にしてチャンスをつかむ。チャンスをつかめないときもある。
そんなループについて経験を交えて語ってくれるいい本だと思う。


おわりに

俺は山ちゃん好きだし、マインドが山ちゃんよりなので俺に歯向かったやつ絶対に許さないとか、嫉妬の化け物感とかそういうヤバい思考含め共感できるところもあるので、まじめな人となりが垣間見えるいい本だったなと思う。

山里亮太に興味ないなっていう人も内容面白いので読んでみてほしい。

めっちゃ売れてんのな。
http://www.yukawanet.com/archives/5391202.htmlwww.yukawanet.com

getnews.jp

フォトカツが終わった日

f:id:snofra:20180712230937j:plain

アイカツ! フォトonステージ!!』が2018年7月11日をもってサービス終了した。

2016年1月28日配信開始なので、サービス期間は2年半くらい。

いろいろなソーシャルゲームをつまんでは止めアンインストールしている俺にとって、フォトカツは最初から最後までお付き合いする初めてのソーシャルゲームだった。

だからか終了のアナウンスが俺のtwitterのタイムラインに流れてきたときに、(歌唱担当も卒業したし)なんとなく予想はしていたけどついに来たかという、そんな気持ちだった。


フォトカツに重課金とはいかないまでも多少課金をしてきていたので、課金した金返せとか思うのかなと思っていたけど、意外にそんな気持ちは沸いてこなかった。

ただただ終わってしまうのか……。そんな気持ち。

その気持ちを持ったまま今終わりを迎えて、フォトカツのアプリを開くと終わりのメッセージがあって、ああ、本当に終わってしまったんだなって。

f:id:snofra:20180712230452j:plain


事実を事実として受け入れるという気持ち。

そこに感情とかはあまり乗ってこなくて、
そういや美月さんのクレーンゲームのシナリオは的確にキャラクターを捉えていたなーとか、
初めて伝説級クリアしたのハローハローだったなー、そこからこの曲好きになったなーとか、
青い苺、アイカツメロディ!はすごい感動したなーとか、
初めてのPRが「[天の川への願い]霧矢 あおい」あおい姐さん推しの俺にふさわしいスタートだとか。
そういうことをふと思い返す。

そういう過去の出来事を思い返すという時点で、フォトカツというひとつの物語は俺の中で終わってしまったんだなって。終わってしまうしかないんだなって。

こういうゲームは、ゲームを思い出の中に置いておくしかなくて、そのときに感じていた気持ちを今の自分の状態でアップデートすることができないのがつらい。


好きだったソーシャルゲームの終焉を見た人は同じ気持ちだったのだろうか。



「フォトカツ」は終わったけど、まだ「アイカツ!」は続いていく。


【アイカツ!フォトonステージ!!】アイカツ!シリーズ5周年 特別楽曲「アイカツメロディ!」プロモーションムービー(フォトカツ!)



またどこかでフォトカツ*1と巡り合えたらと思う。


運営の人お疲れさまでした。
同じ業種なのでつながりにくいとかメンテ時の障害発生時のつらさは分かっているつもり。
閉塞作業が終わったので、しばらく休暇になるのだろうか。

次もいいサービスを配信してもらえればと思う。

*1:アイカツ!の新しいソーシャルゲームサービス

AWS認定ソリューションアーキテクト アソシエイト(2018年2月リリース版)の試験メモ

AWS 認定ソリューションアーキテクト – アソシエイト」の(2018 年 2 月リリース版)(SAA)を受けた!


そして落ちた!

f:id:snofra:20180710190424j:plain

合格ボーダー72%の51%なので全然足りてなかったっすね……。

言い訳ではないがSAAは旧版に比べて難易度が高くなったと言われている。
問題構成も旧版と異なっている。

f:id:snofra:20180710190548p:plain
AWS 認定ソリューションアーキテクト – アソシエイト | AWS

現在移行期間中(2018年8月12日くらいまで?)のため、SAAを受けるのであればネットに知見がかなりある旧版を素直に受けておいたほうがいいのかなと思う。

旧版の模擬テストも受けてみたけど、内容が全然違うように思った。旧版だと7割くらいとれていたので、旧版だったら受かってた説まである。

肌感覚ベースだけど、新版と旧版でどう違うのかっていう点をメモしておく。

SAA新旧での違い

まず、新版の模擬試験と本試験を受けてみた感想だと、旧版のような1つの機能について細かく知っておけばOKという問題はほぼないと言っていい。

新版の問題(というか問題文)は要件であり、ネットワーク構成を文字で記載される。
また、回答は要件を満たす機能や、その要件を採用した場合の影響を選択していくことになる。

ということもあり、AWSの試験で調べたときによく出てくる以下のようなサイトをとりあえずやっておけば的な考えは捨てたほうが良い。
ひとつの参考情報として腕試すのは全然やっていいと思う。

aws.koiwaclub.com


SAA新版のよく出てきた印象のある問題

新版の問題で多いなと思ったのが、以下6つ。

  1. Amazon VPC(というかNATゲートウェイとNATインスタンス
  2. Amazon SQS
  3. 各ストレージサービスの違い
  4. 各データベースサービスの違い
  5. Amazon EBSの各ボリュームタイプの違い
  6. Amazon EC2の各インスタンスファミリーの違い


Amazon VPC(というかNATゲートウェイとNATインスタンス

上にも書いた通り、問題文はネットワーク構成を文字で表現されるので、構成図を想像できないと何の話しているのかさっぱりだと思う。

VPCを使用しているセキュアな構成図は、想像できるようにしておいたほうがいい。

クロスアカウントの接続もあって、direct connectでいいよな?みたいな不安が残る回答もあったので、マイナーなところもきっちり抑えておくことが重要。

qiita.com

qiita.com

qiita.com


Amazon SQS

アプリケーションからDBに対してデータ送るけど、リクエスト数の課題があるみたいな問題が出されていたような気がするので、SQSはしっかり押さえたほうがいい。

正直これもSQSじゃね?みたいに思ってたところが間違っている可能性があるので、似たようなサービス(SNS)との違い等もしっかり押さえたほうがいい。*1


各ストレージサービスの違い

問題にどのストレージがいいのかみたいな問題が多かったので、それぞれの特徴(できることできないこと)はメモしておいたほうがいい。

回答にデータベース機能もあったんだがストレージ=データベースではないよな?さすがに


各データベースサービスの違い

ストレージと同じ。
サイズを自動で変更できるものは?とかKeyValue構成のものは?とかあったので、違いを一覧化していけばよいかなと。


Amazon EBSの各ボリュームタイプの違い

どちらかというと旧版よりの問題。汎用とIOPSの違いを訊かれる。というかほぼそのまんまな問題だった気がする。ボーナス問題。


Amazon EC2の各インスタンスファミリーの違い

EBSと同じ。これも比較的ボーナス問題。


その他

模擬試験を受けたときは、VPCのネットワーク構成よりもサーバーレスアーキテクチャ(というかLambda)について問われる問題が多く、新版はサーバレスアーキテクチャ重視になったのかなーと思ったら全然違った。

本試験はたまたまネットワークな問題が多かっただけなのかもしれない。
サーバーレスアーキテクチャな構成も確認したほうがいいと思う。


テスト勉強について

試験落ちているヤツのテスト勉強について聞いてもしょうがないと思うけど書いておく。

テスト勉強は以下3点を重点的に実施した。

  1. AWS Black Beltセミナー資料を読む
  2. 各機能のAWS ドキュメントを読む
  3. 書籍を読む

今考えるとこれにプラスして実機を触るっていうところはやっておいたほうがよかったなーって思う。
ただ、ネットワーク構成ちゃんとつくるの結構ハードル高いと思うのでそこは資料読むなりするしかないよなーと。

aws.amazon.com

AWS ドキュメント | AWS


書籍は以下3冊。
まずは「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版」を読んだほうがいいのかなと思う。

合格対策 AWS認定ソリューションアーキテクト -アソシエイト

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

実際、この書籍だけでは合格対策にはならない。この本は機能単位での説明であって、ネットワーク構成は語っていない書籍のため。
メジャー機能で知らないものがあれば、目を通しておけばふわっとした全体像がつかめるかなというレベル。


Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

「合格対策 AWS認定ソリューションアーキテクト -アソシエイト」よりもまずはこの本を読んでいくことをお薦めする。

改訂版でNATゲートウェイを使用しているので、そこを踏まえて何をやっているのかを一緒に組みながら見ていくのが良いかもしれない。


Amazon Web Servicesクラウドデザインパターン設計ガイド 改訂版

Amazon Web Services クラウドデザインパターン設計ガイド 改訂版

Amazon Web Services クラウドデザインパターン設計ガイド 改訂版

クラウドパターンとして各パターンごとのネットワーク構成が記載されているが、SAAを突破するという目標のみであればスコープ外なネットワーク構成が多いので、特筆して読む必要はない書籍かなと。

*1:さすがにSNSとの違いはわかった

【技術編】アイカツ!シリーズのCD売上から見えてくるもの

先週書いたアイカツ!のCD売上分析で使用したpytonコードをメモとして記載しておく。 分析自体については以下を参照ください。
snofra.hatenablog.com

今回のデータ分析について


f:id:snofra:20180611001537p:plain
今回はデータ量も大したことなかったので手動でデータをcsvに加工して作業をしていた。
JINの投稿データは収集に1時間かかってマジクソと思ったんだけど、クローラ作るほど何度もJINは利用しないので頑張った。

データの加工はpandasで簡単にやりつつ、描画はbokehにしてpandasのdataframeをそのまま取り込むことにした。

実装量はかなり少ない。変に自前でサマリする処理加えるよりも楽だったというのが正直なところ。


実装


ロード部

import pandas as pd
import numpy as np
import math
# bokeh系のライブラリ
from bokeh.plotting import figure, output_file, show
from bokeh.io import output_notebook
from bokeh.models import ColumnDataSource,  Range1d, LinearAxis
output_notebook()

# csvファイルのロード
# アイカツ!のCD売上
df_aikatsu_cd = pd.read_csv('C:/xxxx/cd_sales.csv', parse_dates=[2], engine='python', encoding="utf-8")
# googleTrends
df_trend = pd.read_csv('C:/xxxx/multiTimeline.csv', parse_dates=[0], engine='python', encoding="utf-8")
# JINのアイカツでヒットした投稿数
df_jin = pd.read_csv('C:/xxxx/jin.csv', parse_dates=[0], engine='python', encoding="utf-8")

sales_day_all = df_aikatsu_cd.fillna('0')


加工部

# 発売月単位でサマリする
df = pd.DataFrame({'発売月' : sales_day_all["発売日"].dt.strftime('%Y-%m'),
                   '初動枚数' : sales_day_all.fillna('0')["初動枚数"].str.replace(',','').astype('int'),
                   '累計枚数' : sales_day_all.fillna('0')["累計枚数"].str.replace(',','').astype('int'),
                   '売上高' : (sales_day_all.fillna('0')["セールス(円)"].str.replace(',','').astype('int') /10000).round(0) # 売上高(万円)単位で出すため除算
                  })

df_groupby = df.groupby("発売月",as_index=False).sum()

# 発売年単位でサマリする
df_groupby_year = pd.DataFrame({'発売年' : sales_day_all["発売日"].dt.strftime('%Y'),
                                '初動枚数' : sales_day_all.fillna('0')["初動枚数"].str.replace(',','').astype('int'),
                                '累計枚数' : sales_day_all.fillna('0')["累計枚数"].str.replace(',','').astype('int'),
                                '売上高' : (sales_day_all.fillna('0')["セールス(円)"].str.replace(',','').astype('int')/100000000).round(4) # 売上高(億円)単位で出すため除算 
                               })

df_groupby_year = df_groupby_year.groupby("発売年",as_index=False).sum()

# googleTrendsを月単位でサマリ
df_trend_month = pd.DataFrame({'月' : df_trend["週"].dt.strftime('%Y-%m'),
                               'トレンド数' : df_trend.fillna('0')["トレンド数"].astype('int')
                             })

df_groupby_trend = df_trend_month.groupby("月",as_index=False).sum()

# googleTrendsを年単位でサマリ
df_trend_year = pd.DataFrame({'年' : df_trend["週"].dt.strftime('%Y'),
                             'トレンド数' : df_trend.fillna('0')["トレンド数"].astype('int')
                             })

df_groupby_trend_year = df_trend_year.groupby("年",as_index=False).sum()


# JINのアイカツでヒットした投稿数のサマリ
df_jin = pd.DataFrame({'投稿月' : df_jin["投稿日"].dt.strftime('%Y-%m'),
                       'count' : df_jin.fillna('0')["count"].astype('int')
                      })

df_groupby_jin = df_jin.groupby("投稿月",as_index=False).sum()

年単位、月単位のサマリはDataframeでやるのが一番簡単かなということで、Pandasのdataframeのgroupbyとsum()で一気に集計している。

bokehの表示上の都合で、売上高の桁調整をここでやる。 0が多すぎるとうまく表示されない。

pandasのdataframeの一部カラムだけ表示したいなーと思って調べたので、今回は特に使うことないがメモだけしておく。

# pandasのdataframeの一部のカラムだけ表示する
print(df.loc[:,['発売月','初動枚数','累計枚数']])

f:id:snofra:20180610015241p:plain
こんな感じで表示される。


曲線近似の算出

# 曲線近似の算出
# 累計枚数
regression = np.polyfit(df_groupby.index, df_groupby['累計枚数'], 1)

print(df_groupby.index*regression[0] + regression[1])

# 売上高
regression_sales_amount = np.polyfit(df_groupby.index, df_groupby['売上高'], 1)

print(df_groupby.index*regression_sales_amount[0] + regression_sales_amount[1])

曲線近似の算出はnumpyとscipyがあるようだけど、今回はnumpyで実装。
ailaby.com
qiita.com

正直、曲線にする必要は全然なかった。
グラフのプロットはprint文のとおり、CD売上月とCDの累計売上数or売上高で1次関数で算出している。


グラフのplot

時系列データを使ったCD売上推移

# CD売上推移のグラフplot
df_groupby["発売月"] = pd.to_datetime(df_groupby["発売月"])

# CD売上のplot
p = figure(plot_width=800, plot_height=400, x_axis_type="datetime", title="CD売上推移")
p.line(df_groupby["発売月"], df_groupby['累計枚数'], line_width=3.5, color="red", alpha=0.5)
p.circle(df_groupby["発売月"], df_groupby['累計枚数'], fill_color="white", line_color="red", size=10)

# 曲線近似のplot
p.extra_y_ranges = {"graph2": Range1d(start=0, end=11200)}
p.line(df_groupby["発売月"], df_groupby.index*regression[0] + regression[1], line_width=1,color="blue", alpha=0.5, y_range_name="graph2")

show(p)

グラフのX軸と、y軸の説明、グラフの凡例は多少加工しているが以下のような感じで出力される。
f:id:snofra:20180529000900p:plain

かなりシンプルに実装できる。 Dataframeをそのままグラフにplotできるbokehだからこそのシンプルさだと思う。

苦戦したのはX軸をうまく読んでくれないというのがあった。
というのも時系列データにする場合、型をちゃんと日付型にする必要があったんだけど、daraframeでは文字列型だったから。
日付型にto_datetimeしてから再度入れなおすという対応をした。

盛り上がっていた時期を調べるグラフ

df_groupby_trend["月"] = pd.to_datetime(df_groupby_trend["月"])
p = figure(plot_width=800, plot_height=400, x_axis_type="datetime", title="盛り上がっていた時期は?")

# CD売上のplot
p.line(df_groupby["発売月"], df_groupby['累計枚数'], line_width=3.5, color="red", alpha=0.5)
p.circle(df_groupby["発売月"], df_groupby['累計枚数'], fill_color="white", line_color="red", size=10)

# googletrendsのplot
p.extra_y_ranges = {"graph2": Range1d(start=1, end=500)}
p.line(df_groupby_trend["月"], df_groupby_trend['トレンド数'], line_width=3.5, color="green", alpha=0.5, y_range_name="graph2")

show(p)

これもグラフのX軸と、y軸の説明、グラフの凡例は多少加工しているが以下のような感じで出力される。
f:id:snofra:20180530002546p:plain

JINとの比較グラフ

df_groupby_jin["投稿月"] = pd.to_datetime(df_groupby_jin["投稿月"])
p = figure(plot_width=800, plot_height=400, x_axis_type="datetime", title="GoogleTrendsの検索数vsJINの記事数")

# googletrendsのplot
df_groupby_trend["月"] = pd.to_datetime(df_groupby_trend["月"])
p.line(df_groupby_trend["月"], df_groupby_trend['トレンド数'], line_width=3.5, color="green", alpha=0.5)

# JINの投稿数のplot
p.extra_y_ranges = {"graph2": Range1d(start=0, end=20)}
p.line(df_groupby_jin["投稿月"], df_groupby_jin['count'], line_width=3.5, color="blue", alpha=0.5, y_range_name="graph2")
p.add_layout(LinearAxis(y_range_name="graph2"), 'right')

show(p)

基本は前のものと同じなんだけど、このグラフはグラフの右側にメモリを表示するようにした。メモリがあったほうが分かりやすいかなという判断。
p.add_layout(LinearAxis(y_range_name="graph2"), 'right')


折れ線グラフを棒グラフにしたパターンも試してみているので、メモしておく

df_groupby_trend["月"] = pd.to_datetime(df_groupby_trend["月"])
df_groupby_jin["投稿月"] = pd.to_datetime(df_groupby_jin["投稿月"])
p = figure(plot_width=800, plot_height=400, x_axis_type="datetime", title="GoogleTrendsの検索数vsJINの記事数")

# googletrendsのplot
p.line(df_groupby_trend["月"], df_groupby_trend['トレンド数'], line_width=3.5, color="green", alpha=0.5)

# JINの投稿数のplot
p.extra_y_ranges = {"graph2": Range1d(start=0, end=20)}
p.vbar(x=df_groupby_jin["投稿月"], width=1, bottom=0,
       top=df_groupby_jin['count'], color="blue", y_range_name="graph2")

show(p)

その場合はこのようにplotされる。
f:id:snofra:20180610024701p:plain

相関係数の算出

# 相関係数の算出
correlation = np.corrcoef(df_groupby_trend_year["トレンド数"].values.tolist(), df_groupby_year["累計枚数"].values.tolist())
print(correlation[0,1])

相関係数を出すために各dataframeをarrayにしている。 月単位も年単位も同じやろってことで年単位にしてる。

numpy.corrcoef — NumPy v1.14 Manual

f:id:snofra:20180610233329p:plain
相関係数0.75はまあまあ相関しているのかなーっと。

売上高の算出

p = figure(plot_width=800, plot_height=400, x_axis_type="datetime", title="CD売上高推移")

# 売上高のplot
p.line(df_groupby["発売月"], df_groupby['売上高'], line_width=3.5, color="red", alpha=0.5)
p.circle(df_groupby["発売月"], df_groupby['売上高'], fill_color="white", line_color="red", size=10)

# 曲線近似のplot
p.extra_y_ranges = {"graph2": Range1d(start=1000, end=2000)}
p.line(df_groupby["発売月"], df_groupby.index*regression_sales_amount[0] + regression_sales_amount[1], line_width=1,color="graph2", alpha=0.5, y_range_name="foo")

show(p)

グラフの実装は前と同じなので、言うことは特にない。
f:id:snofra:20180605001140p:plain


売上高の算出

# 年別売上高
#売上高でソートしてdataframeのindex振り直し
df_groupby_year_tmp = df_groupby_year.sort_values('売上高').reset_index(drop=True)

# 売上高のplot
p = figure(plot_width=400, plot_height=500, title="年別売上高")

p.hbar(y=df_groupby_year_tmp.index, height=0.5, left=0,
       right=df_groupby_year_tmp['売上高'], color="firebrick")

show(p)

plotするときにソートができそうになかったので、事前にソートを実施。
その時にdataframeのindexを振りなおさないと、結局plotしたときにソートが意味なくなってしまうので、dataframeのindexを振りなおして、y軸にindexを設定している。

ただこれをやるとy軸のメモリの凡例が0~6になるという問題があって、俺は結局グラフの加工でカバーすることにした。
うまい方法ないのかなー。
f:id:snofra:20180605004057p:plain


実装

簡単なplotなのでそんなに実装に時間はかかっていないけど、加工するのめんどい。
けど、加工したほうが見やすいっていうのをここのブログ見て理解した。

speakerdeck.com

shinyorke.hatenablog.com

今まではplotしてはいできたって、実装視点でしか見てなかったんだけど、実際はあれじゃわかりにくかったよなーと。
グラフ中に分かりやすく書いてあげるってのが必要だと思ってた。
気づかせてくれてありがとうございますっていう気持ち。