January 27, 2018

github pagesにブログを引っ越しました

2013年の1月にさくらVPSでブログを運用していましたが、github pagesに引っ越しをしました。ここ暫くはブログの更新が止まってしまっていたので気分転換をしたかったのと、VPSを安いプランに変更するための前準備です。 今回のブログは、 hugo github pages travis を利用しています。 ブログのテーマは、kiss を使っていて、一部に編集を加えています。hugoはmarkdownで記事を書くことが出来るのですが、前のブログもmarkdownで書いていたので、簡単な変換スクリプトを作成して移行しました。具体的には、 ページのurlを英字にするために、記事タイトルにgoogle翻訳をかけて変換 日付の書式をhugoに合わせる 前のブログで記事のurlが変わってしまうため、リダイレクトの設定をする。aliasesで解決 タグの設定方法をhugo形式に合わせる です。 ブログの投稿はgithubのmasterブランチにmarkdownで書いた記事をpushすると、travisの自動ビルドが走り、githubのgh-pagesブランチにpushされます。github pagesには独自ドメインを設定することが出来るので、記事のurlを変えることなく移動できました。 travisの設定 .travis.yml を リポジトリの直下に置く ビルドのslack通知。 図解: Travis CIの結果をSlack通知する方法 deployのfqdnに独自ドメインを指定する。ここでの設定がgithub pagesの設定に反映されます githubのtokenの設定, https://github.com/settings/tokens の Personal access tokens を取得して、travisの https://travis-ci.org/gepuro/gepulog/settings にある Environment Variables に追加 slack通知用にtravisコマンドを入れた時に、ubuntuのaptからインストールしたのですが、バージョンが古いせいか上手く動きませんでした。 ( bash on ubuntu on windowsを使っています。 ) そのため、gemからインストールしました。この時のrubyのバージョンは2.0.0 です。ruby2.0-devとか色々足りなかったのでエラーメッセージを見ながらインストールしました。 language: bash env: global: - HUGO_VERSION=0.32.1 - GIT_URL=https://git@github.com/gepuro/gepulog.git notifications: slack: secure: "TSEF4UkzYqZfzxxv398nzhmU7nP5OnrC6Sc+MJ7DhiWjSX+s846Msgwj6svzyBfp+FspYo7mXYC4faFgd2zod90g8XD9apmPQ9yBeP8+f2psap7PP3FtHney4OB6nFbFRsxo+Ue9YjXyMj6qycAgQ3pe7+ol8L+ZirxFVlYKoQUoE1nNElVtsVQro2D/j2UVWvV0ZttiSXQcO+AoF7+uEZAvGleGMXXR29u0AB7cLN11ASWhN8k4x5XyoBd7+L57GcgGs4OuBiUO1RB4SmoevdY+e5ozLoaoXUcw/n8TH59In4jz9ziVZ/9lMaItTblQMkKx4i9cDPCqfj0x9aKNhkYRM2uLHdL4zTPHTrwVHP/fW1p1sM+IU97cWH4/1RU9cntnUMewu3WDDNLzaapiK+4gV5d/AAVnaEoLzsXySHUfUT//Zi3h/DdcLLM+LTjfhOhxbfo2Hepnc6BYqYzeY8LSjUfL4TJpgV1wM/clnnOE0x/Gh8SNL2YvTaxzCj+2EZFF5uPPHsyWsIFaMG2+6hsnKNeRNrsSUUx5kARUN+rxfSVCJpp5ddb3x98lIrNvJ/oRSUy4iDR0xuTY+WJM142hqp5QPeQqriU9OjKNBCRU8wrfDLEuQEZTqgVjl+KrZTemBVlhk/f3jfNP2PgSnK6sjhgOhyYmG9I1uZTE+9Y=" install: - wget https://github. Read more

May 12, 2017

awscliを使おうとしたらget_environ_proxies() missing 1 required positional argument: no_proxyと怒られた話

ある日、いつも通りに $ aws s3 ls と実行したら、 get_environ_proxies() missing 1 required positional argument: 'no_proxy' と怒られました。 手元の環境は、Ubuntu16.04で、 awscliのバージョンは aws-cli/1.11.13 Python/3.5.2 Linux/4.4.0-75-generic botocore/1.4.70 です。 エラーメッセージでググッても何も出てこないので、再起動をしてみたり、awscliをダウングレードしたりしましたが、結果は変わらず。 最終的には、 $ sudo pip3 install --upgrade boto3 と実行して、boto3のバージョンを最新にあげたら直りました。 めでたし、めでたし。

February 16, 2017

AWS AthenaでPartitionの設定をする

AWS re:Invent 2016で発表されたAthenaというサービスを試してみました。このサービスはS3上にあるデータに対してSQLでデータを取得することが出来ます。一言で言えば、AWS版のBigQueryです。 gzで圧縮されたままのデータに対してもクエリを投げることができ、データをスキャンした量に応じて課金されます。2017年2月15日現在では、1TB あたり5USDと非常に安いです。 BigQuery同様に巨大なデータをうっかりスキャンしてしまうとお金が飛んでいくので注意です。参考: BigQueryで150万円溶かした人の顔 というわけで、日付毎にPartitionを切りましょうという話です。 Englishが得意な皆さんは、https://docs.aws.amazon.com/athena/latest/ug/partitions.html見てもらえば一発ですが、備忘録のために書き残します。 データの準備 下にあるデータを仮定します。 $ cat 20170101.tsv a 1 a 2 a 3 $ cat 20170102.tsv b 1 b 2 b 3 $ cat 20170103.tsv c 1 c 2 c 3 S3に保存する こんな感じです。年月日ごとにログを保存してあるような、よく見る形式です。 $ aws s3 ls athenatest.aws.gepuro.net --recursive 2017-02-15 19:27:10 0 20170101/ 2017-02-15 19:27:28 12 20170101/20170101.tsv 2017-02-15 19:27:15 0 20170102/ 2017-02-15 19:27:42 12 20170102/20170102.tsv 2017-02-15 19:27:18 0 20170103/ 2017-02-15 19:27:53 12 20170103/20170103. Read more

October 4, 2016

jupyter notebookをubuntu 16.04にインストールするときにハマった罠

手元の端末にjupyter notebookをインストールしていなかったので、機嫌良くpip3 install jupyterでインストールしてjupyter notebookで起動したところ、 Native kernel (python3) is not available というメッセージが表示された。ブラウザから「New」を見てもPython3の文字は表示されていない。 改めてjupyterを次のようにしてインストールした $ pip3 install --upgrade jupyter すると、 Exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1006, in check_if_exists self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 535, in get_distribution dist = get_provider(dist) File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 415, in get_provider return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] File "/usr/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl/pkg_resources/__init__.py", line 695, in find raise VersionConflict(dist, req) pkg_resources.VersionConflict: (ipython 2.4.1 (/usr/lib/python3/dist-packages), Requirement. Read more

August 4, 2016

SQLite3をPythonから使っていたら、sqlite3.OperationalError database or disk is fullというエラーが出た

タイトルの通りで頭を抱えていました。 Bashで $ df -h を実行してもディスクは溢れていなかったのです。 ググってみるとSQLITE3 VACUUM, “database or disk is full”という人がいたので覗いたら解決しました。 conn = sqlite3.connect("data.db") cur = self.conn.cursor() cur.execute(""" pragma temp_store_directory='/tmp' """) conn.commit() のようにして、一時ディレクトリを指定したら動くようになりました。 デフォルトでは、どこに持ってるのだろうか?そこまでは調べていません。 また、 vacuum; というのも覚えました。 SQLite3でデータを追加したり消したりするとゴミが溜まってくるそうで、それを削除出来るとのことです。 データベースが大きくなった時に活躍しそうなので、ついでにメモしておきます。

July 14, 2016

ATOMで数式を改行する方法

動作環境は、mathjax-warapperを入れて、markdown-preview-plusでプレビューを確認している。 下の方法で改行出来た。 \[ \begin{align} y &= x + x + x \\ &= 3 x \end{align} \]

July 8, 2016

Python3で「if a in b」をするときはsetを使うべし

タイトルの通りです。下のコードで確認しました。 データが増えてくると1万倍は変わるようです。 Python 3.5.1 |Anaconda 2.4.1 (64-bit)| (default, Dec 7 2015, 15:00:12) [MSC v.1900 64 bit (AMD64)] Type "copyright", "credits" or "license" for more information. IPython 4.0.1 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: %cpaste Pasting code; enter '--' alone on the line to stop or use Ctrl-D. Read more

July 7, 2016

numpy上で平均を求める v.s. Pandasで平均を求める

計算の待ち時間が長く感じることが増えたので調べる 結論は、numpyのみで計算した方が早い。 以下で確認した。 Python 3.5.1+ (default, Mar 30 2016, 22:46:26) Type "copyright", "credits" or "license" for more information. IPython 2.4.1 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: %cpaste Pasting code; enter '--' alone on the line to stop or use Ctrl-D. :import numpy as np :import time : :start = time. Read more

July 6, 2016

Pandasのappendが遅くて萎えた話

あまりにも処理に時間がかかるので、下のコードで確認した。 gepruo@ubuntu$ ipython3 Python 3.5.1+ (default, Mar 30 2016, 22:46:26) Type "copyright", "credits" or "license" for more information. IPython 2.4.1 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features.%quickref -> Quick reference.help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: %cpaste Pasting code; enter '--' alone on the line to stop or use Ctrl-D. :import pandas as pd :import time :start = time. Read more

May 11, 2016

『詳解 Apache Spark』出版記念イベントに参加しました

最近はSparkに触れていなかったのですが、日本語の情報も豊富になってきたのを感じました。 自分も書きたい。 ブログネタでやるかなあ。と思った一日でした。 データ分析業界の理想と現実 - Spark普及の歴史を添えて(下田倫大さん) Spark登場時に私は夢とロマンを見ました! 現実は厳しい・・・。 ガンガン使おう 2013年: 大規模データ処理といえばHadoopで集計 2014年: Sparkとの出会い, インドで使ってた 第一印象: Python, Rのインターフェースがある! 2015年: ブレインパッド社としてビジネスモデル的にSparkのメリットが大きくない コンサル/SI は新しい技術導入が遅くなりがち ニーズが必要 DeltaCubeという自社開発プロダクトで導入 案件が効率化からイノベーションに変化 データマネジメントツールDeltaCubeでのSpark利用(師岡一成さん) 2014年に触り始めた 2015年に本格的に DeltaCube: プライベートDMPのログからセグメントを作成ツール 2014年に開発が始まり、リリースまで2年ぐらいかかった 初期 行動ログを手動で検索して、セグメントを作成 データサイズは数TB, presto, impalaを使った 中期(2015年) * 機能的にマニアック路線 広告運用の手間がかからないようにしたい 自動でユーザをクラスタリング(DeltaCube) Rtosterで自動ABテスト ETL, MLlib Read more

January 24, 2016

jqコマンドで正規表現を使う

日常的に利用しているjqコマンドですが、最新バージョンを入れれば正規表現が使えると知ったので、インストールしました。 OSはubuntu 14.04です。 基本的には、 https://stedolan.github.io/jq/download/に従えばよいですが、正規表現を利用するには外部ライブラリのインストールが必要なようです。 下のようにしてインストールした。余分なライブラリが入っているだろうが、調査するのが面倒だったので、apt-cache search onigでヒットしたものを全部突っ込んだ。 sudo apt-get install libjruby-joni-java libonig-dev libonig2 libonig2-dbg lua-rex-onig lua-rex-onig-dev あとは、公式の通りにインストールするだけ。 git clone https://github.com/stedolan/jq.git cd jq autoreconf -i ./configure --disable-maintainer-mode make sudo make install 手元の環境では、./configure –disable-maintainer-mode –prefix=/usr/local/をしておいたり、pacoを使ってインストールしています。

January 24, 2016

Dockerでapacheを使う

忘れそうなので、メモしておく。 ENV APACHE_RUN_USER www-data ENV APACHE_RUN_GROUP www-data ENV APACHE_PID_FILE /var/run/apache2.pid ENV APACHE_RUN_DIR /var/run/apache2 ENV APACHE_LOG_DIR /var/log/apache2 ENV APACHE_LOCK_DIR /var/lock/apache2 CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]

January 22, 2016

Python3のFlaskをwsgiで動かす

自分の環境ではdocker上で動かしていましたが、本筋には影響を与えないので省略します。 Flaskのドキュメントであるmod_wsgi (Apache)に書いてあるし、Python2の頃は試したことあるから、余裕だろうと油断していた。 sudo apt-get install -y apache2 \ apache2-mpm-prefork \ apache2-utils \ libexpat1 \ ssl-cert \ libapache2-mod-wsgi-py3 上のようにインストールした。 また、 /etc/apache2/sites-available/000-default.conf を <VirtualHost *:80> ServerName example.com WSGIDaemonProcess app user=www-data group=www-data WSGIScriptAlias / /app/app.wsgi <Directory /app> WSGIProcessGroup app WSGIApplicationGRoup %{GLOBAL} # Order deny,allow # Allow from all Require all granted </Directory> </VirtualHost> にします。dockerで動かすだけなので、ファイルを直に編集しています。 ハマりポイント1 libapache2-mod-wsgi-py3をインストールする。 パッケージ名から想像できるが、wsgiはPython3とPython2系で異なる。 ハマりポイント2 apacheの設定では、 Require all grantedを使う。 Python2系では、 Order deny,allow Allow from all Read more

January 22, 2016

ユーザのアクセス元の街を可視化してみる

当ブログのユーザのアクセス元を可視化しました。 アクセス元のipアドレスからhttps://freegeoip.net/より提供されるAPIを用いて、どの街かを特定しました。 観測期間は適当です。(freegeoipでデータを取得し始めてからで、過去に遡るのは面倒だった) 以下が結果です。パレート図で描きました。 久しぶりにパレート図を見たわけですが、円グラフに比べて見やすいなあと感じます。もっと流行るとイイなあ。 それにしても、mountain viewって何だろうか。 最後にコードです。 cat data/* | jq -r ' select(.site=="blog.gepuro.net") | select(.geo.city != null) | [.cid, .geo.city] | @csv' | sort | uniq | header -a '"cid","city"' | q -H -O -d ',' ' select case city when "" then "unknown" else city end as city , count(1) as count from - group by city order by 2 desc ' | Rio -r -e 'df %>% mutate(crank=1:n())' | Rio -r -e 'rbind(df[df$crank<10,c("city","count")], data. Read more

January 21, 2016

シェルスクリプトでアクセスログを用いてページ間の類似度を求める

協調フィルタリングです。 協調フィルタリングに関しては、「協調フィルタリングについてまとめてみた。」が詳しく書かれており参考になります。 データセットは、いつものようにwebビーコンのログです。 使用したコマンド jq q sed awk mcmd http://datascienceatthecommandline.com/ など 実際のコマンド もう少しクールに書けるような気がします。 cat data/* | # jsonからデータを取り出してcid, urlのデータを得る jq -c -r 'select(.site=="blog.gepuro.net")| [.cid, .url] | @csv' | sed -e 's/\?.*"$/"/' | grep "http://blog.gepuro.net/archives/" | sed -e 's/http\:\/\/blog\.gepuro\.net\/archives\///' | header -a '"cid","url"' | # cidごとにurlのビューをカウントして横持ちにする q -H -O -d ',' " select cid, url, count(1) as view from - group by cid, url " | mcross k=cid f=view s=url v=0 | cat > tmp/cross. Read more

January 18, 2016

トップページからページングして2ページ目へのアクセスはあるのか

サイトの顔になるトップページですが、過去の記事へと遡ってくれる人は、どれほどいるのでしょうか。 蓄積しているログを集計しました。 集計期間は、2015/9/14から2016/1/18です。 トップページのPV数482のうち、2ページ目への遷移は16でした。 また、遷移した合計数は123でした。 意外にもサイト内を巡回してくれるのですね。 遷移先を上位から |URL|PV数| |-|-| |http://blog.gepuro.net/page/2 | 16 | |http://blog.gepuro.net/archives/118 | 9 | |http://blog.gepuro.net/category/統計/ | 8 | |http://blog.gepuro.net/archives/131 | 7 | |http://blog.gepuro.net/archives/129 | 6 | |http://blog.gepuro.net/archives/133 | 6 | |http://blog.gepuro.net/archives/136 | 6 | |http://blog.gepuro.net/archives/134 | 5 | |http://blog.gepuro.net/archives/135 | 5 | |http://blog.gepuro.net/archives/119 | 4 | となっていました。 集計期間から推測すると、右側にある「最近の投稿一覧」もクリックされているようです。 他の記事へアクセスして貰いやすくするためには、自動ロードも必要なのかもしれないです。 http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/ こういうのも使ってみたいなあ。 集計用のコマンド cat data/* | jq -r ' select(.url == "http://blog.gepuro.net/") | [.sid, .date, .url] | @csv' | q -H -O -d ',' ' select count(1) as pv_toppage from - ' echo cat data/* | jq -r ' select(. Read more

January 8, 2016

サイトのロゴ画像はクリックされるのか

一般的なwebサイトでは、タイトルのロゴ画像にトップページへのリンクを張っています。とは言え、これをクリックしてくれる人って、一体何人いるのだろうかと疑問に感じたので、調べてみました。 計測方法 ロゴ画像のリンクを「http://blog.gepuro.net/?from=logo」として、webビーコンを確認する。 JSONで保存しているので、jqコマンドやqコマンドを下のように使う。 cat data/* | jq -r ' select(.site=="blog.gepuro.net") | select(.unixtime >= 1450334421 and .unixtime <= 1452177993) | [.sid, .url] | @csv' | header -a '"sid","url"' | q -H -O -d ',' ' select sid, max( case when url = "http://blog.gepuro.net/?from=logo" then 1 else 0 end ) as logo_flag from - group by sid ' | q -H -O -d ',' ' select count(1) as session_cnt, sum(logo_flag) as click_logo_cnt, 1. Read more

January 7, 2016

ABテスト#1 - (似ている|似てない)記事一覧の表示数を変える

ABテストを実装&実施してみる で試してみたABテストの結果です。 個別の記事を開いた時、下部に表示させていた”似ている記事”、”似ていない記事”の表示数を変えてみました。 パターンA: それぞれ5件 パターンB: それぞれ3件 結果は、 |パターン|pv数|session数|pv数/session数| |-|-|-|-| | A | 333 | 230 | 1.45 | | B | 297 | 226 | 1.31 | ウィルコクソンの順位和検定を使いました。 Asymptotic Wilcoxon rank sum test data: df[df$ab == 0, ]$pv and df[df$ab == 1, ]$pv W = 25835, p-value = 0.02378 alternative hypothesis: true mu is not equal to 0 パターンAとパターンBのpv数は、有意水準5%で中央値が等しいという帰無仮説を棄却する。 パターンAの勝ちですね。

© gepuro 2013