まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:google

根がケチなせいか、お金に関する理不尽な請求には泣き寝入りしないようにしています。4年ほど前に Google Wallet 経由で見に覚えのないスマホゲームのアプリ内課金が請求された時は(そもそも日本に窓口がなかったことも問題だと思ってましたが)英語でやりあいました。その時の経緯はこのブログでも紹介していました:
Google Wallet の不正利用?
Google Wallet の不正利用?(続き)
Google Wallet の不正利用?(続き2)
Google Wallet の不正利用?(続き3)
Google Wallet の不正利用?(続き4)
Google Wallet の不正利用?(解決編)

一応 Google の名誉のために言っておくと、この時の Google の対応はとても真摯で協力的でした。むしろその先のクレジット会社の対応がまったく非真摯的というか人の話を聞いていないかのような対応で解決が長引いてしまったという印象でした。


さて、先日お盆に実家に帰った時に団欒が凍り付くような事件がありました。自分が当事者ではないことと、現時点で相手の言いぶんをちゃんと聞いているわけではないので詳しく書くことは避けますが、高齢者である自分の家族の1人が大手携帯キャリアのスマホを契約した際に、明らかに不要な高額オプションを付帯契約させられていた、というものでした。

もともといわゆるガラケーを使っていたその家族がスマホに機種変更しました。ここまでは本人の意志でもあり問題ありません。ところが実際には以下の3回線を追加で(計4回線)契約させられていたのでした:
 ・(メインスマホとは別の、壊れた時の代替機として)スマホ1回線
 ・タブレット1回線
 ・「家に置くだけで家の中で無線LANが使える」ようにする******エアー1回線

ちなみにその家族は新しい回線を契約した認識はなく、「ぜんぶ付属品だと思った」とのこと。その結果の4回線契約です。本体の割賦支払いもあるので毎月の支払額はウン万円、という感じ。24回払いと36回払いが混在していて、全部キレイに解約するのがとても面倒、というあくどいやり方です。

詳しくは自分が明日、店頭を訪ねて先方の説明を聞いてくるつもりですが、それにしてもあまりにもおかしな理論です。まず「代替機」と説明された(らしい)2台目のスマホ。代替機なら回線契約は不要のはずだし、後述の無線LAN機器を契約したなら、代替機として使うまではそちらを使えばいいので、どう考えても回線契約は不要のはず。 また「タブレット」については本人は契約した認識すらありませんでした。思い出しながら書いているだけでイライラが再発しそうだ。。

そして「なんたらエアー」とかいう無線LAN機器、これは自分が家族の部屋に無線LANを設置しているのでそもそも不要なもので、どうもこれが自宅に存在していることを店員に伝えていたにも関わらず、言いくるめて契約させられた模様。なぜこれが要ると思ったのだろう・・・


自分がこの契約のことを知ったのは機種変更の契約から8日目でした。ちょうどクーリングオフができなくなるタイミング。でもこちらからは「これはクーリングオフとかいう問題ではなく、明らかに不要なものを買わせたのだから、再度説明した上でメインの1回線以外は違約金なしで契約を取り消すべき」という主張を伝えています。

詳しくは話しませんが、全く準備せずにいきなり乗り込むわけではありません。ある程度戦う準備はした上で明日店頭に突撃訪問してきます! 言いたいことは山ほどあるのですが、解決してからにしようと思っています。訪問の結果はまたいずれ。


前回は4年くらい前に、上記のような半年以上に渡る気の長い戦いをクレジット会社とやってきて不正請求分を取り戻しました。某携帯キャリアの○○○○○○、You are next!
usflag9sm



Google が提供する機械学習ライブラリ TensorFlow公式にはラズベリーパイ用のモジュールは用意されていませんが、ラズベリーパイ向けのパッケージを作って公開されているものを見つけました:
https://github.com/samjabrahams/tensorflow-on-raspberry-pi


実際に導入してみた手順を紹介します。なお以下の情報は 2017/Jul/19 時点のものであり、実際に試した時の環境は以下のとおりです:
ハードウェア: Raspberry Pi 3 Type B
OS: Raspbian GNU/Linux 8.0(Jessie)
Linux カーネル: 4.9.28
TensorFlow: 1.1.0


【Pythonのインストール】
Python 2.7 または 3.3 以上が必要です。自分の環境では標準で 2.7 がインストールされていたので、これをそのまま使うことにしました。というわけで、以下の手順は Python 2.7 用のものです。


【pip 他のインストール】
TensorFlow 本体のインストール時に必要な pip や開発用依存モジュールをまとめてインストールします:
$ sudo apt-get update
$ sudo apt-get install python-pip python-dev

【TensorFlow のインストール】
ラズパイ用の TensorFlow 1.1.0 をダウンロードし、pip でインストールします:
$ wget https://github.com/samjabrahams/tensorflow-on-raspberry-pi/releases/download/v1.1.0/tensorflow-1.1.0-cp27-none-linux_armv7l.whl
$ sudo pip install tensorflow-1.1.0-cp27-none-linux_armv7l.whl

wheel パッケージが展開され、各種ライブラリ含めたビルドが行われます。実際には結構な時間がかかる作業です。


【mock ライブラリの再インストール】
最後に mock ライブラリの再インストール(一度削除して、もう一度インストール)が必要とのことで、その作業を行っておきます:
$ sudo pip uninstall mock
$ sudo pip install mock

【動作確認】
クラスメソッド様のサイトに「TensorFlow 版ハローワールド」的なサンプルプログラムがあったので、これをそのまま動かしてみます:
TensorFlowで Hello Worldを動かしてみた&その解説

テキストエディタで以下の内容を編集し、hello-tf.py という名前で保存します:
# hello-tf.py
import tensorflow as tf
import multiprocessing as mp
 
core_num = mp.cpu_count()
config = tf.ConfigProto(
    inter_op_parallelism_threads=core_num,
    intra_op_parallelism_threads=core_num )
sess = tf.Session(config=config)
 
hello = tf.constant('hello, tensorflow!')
print sess.run(hello)
 
a = tf.constant(10)
b = tf.constant(32)
print sess.run(a+b)

これを Python で実行します:
$ python hello-tf.py
hello, tensorflow!
42

青字のような結果が出力されれば、とりあえず動作していることが確認できました。


 

Google ドライブのファイルシステム(?)を fuse を使って Linux にマウントする、というためのツールを使ってみました。今回は Google Drive ocamlfuse というツールを使って、Ubuntu 14.04 環境にマウントしてみました:
https://github.com/astrada/google-drive-ocamlfuse


なお、今回紹介する手順では途中でウェブブラウザを使った OAuth 認証を行うため、GUI 環境が必要です(コマンドライン環境だけでは最後までマウントできません)。GUI アクセスできる Ubuntu とウェブブラウザをご用意ください。

まずはターミナルを開き、Google Drive ocamlfuse を apt-get でインストールできるようにするため、リポジトリを追加します:
$ sudo add-apt-repository ppa:alessandro-strada/ppa
$ sudo apt-get update

そして apt-get install を実行します:
$ sudo apt-get install google-drive-ocamlfuse

準備の最後に Google Drive をマウントする先のマウントポイントとなるディレクトリ(以下の例では ~/googledrive)を用意しておきます:
$ mkdir ~/googledrive

では Goodle Drive ocamlfuse を使って実際にマウントしてみます。初回のみコマンドラインから引数なしで実行します:
$ google-drive-ocamlfuse

するとウェブブラウザが起動し、Google の OAuth 認証が行われます。Google ドライブを使うためのユーザーおよびパスワードでログインします:
2017032201


オフラインアクセスのための許可が求められるので「許可」をクリック:
2017032202


以下のようなメッセージが表示されれば OAuth 認証完了です:
2017032203


再びターミナル画面に戻り、今度はマウントポイントを指定して google-drive-ocamlfuse を実行します。これで OAuth 認証時に使ったユーザーの Google ドライブが指定ディレクトリにマウントされます:
$ google-drive-ocamlfuse ~/googledrive


この状態で df -h コマンドを実行すると、指定したディレクトリに Google Drive がマウントされていることが確認できます:
2017032204


ls コマンドなどでこのディレクトリ内を確認すると、Google Drive 内のドキュメントが odt 等のフォーマットで存在していることを確認できます:
2017032205


アンマウントする場合は fusermount コマンドを -u オプションを付けて(アンマウントポイントを指定して)実行します:
$ fusermount -u ~/googledrive


Google ドライブがマウントできると Boostnote のドキュメント共有が異なるシステム間でも可能になったりできて、ますます便利です。



(参考)
http://o2t.hatenablog.com/entry/2014/09/08/143621
 

IBM LinuxONE(メインフレーム上の Linux)ネタシリーズ、今回は Go 言語を動かしてみます。
http://golang-jp.org/


前提として、IBM LinuxONE の環境が必要になります。今回は 120 日間無料で使える IBM LinuxONE コミュニティクラウド上の RHEL 6.x 環境を使うことにします。この IBM LinuxONE コミュニティクラウドの導入方法についてはこちらを参照してください:

さて、s390x 向けの Go 言語をどうやってインストールするかというと・・・ なんとグーグルから同環境を含めた各種プラットフォーム向けのバイナリが主要バージョン毎に提供されているのでした:
https://storage.googleapis.com/golang/

Windows や Linux, OS X 向けはもちろん、ARM デバイス向けのバイナリも提供されています。そしてメインフレーム Linux である s390x アーキテクチャのバイナリも提供されていることが分かります:
2017012001


2017/Jan/20 現在、正式リリースされている中では 1.7.4 が Go 言語の最新バージョンだったので、これをダウンロードして利用することにします:
# cd /tmp
# wget https://storage.googleapis.com/golang/go1.7.4.linux-s390x.tar.gz
# tar -C /usr/local -xzf go1.7.4.linux-s390x.tar.gz

上記のコマンドで /usr/local/go 以下に Go を展開しました。環境変数 GOPATH と合わせて PATH を設定しておきます:
# vi /etc/bashrc

    :
(最後に以下の2行を追加して保存) : export GOPATH=/usr/local/go/ export PATH=$PATH:/usr/local/go/bin

改めてログインし直し(或いは source /etc/bashrc を実行し)、Go 言語のバージョンを確認してみます(青字が出力結果):
# go version
go version go1.7.4 linux/s390x

正しくインストールできたと同時に、s390x 環境で Go 言語を導入できたことが確認できました。

マンホールマップを Google の Search Console に登録して、どんなキーワードで検索された結果としてマンホールマップが使われているのか? を解析してみました。

使ったサービスはこれです:
Google Search Console

2016122700



ここにログインし、「検索アナリティクス」メニューから対象期間を選びます。また「クエリ」を選択して、検索キーワードごとに統計を出せるようにしました:
2016122705


ここで得られる結果はこのままだと取り扱いが難しいので CSV 形式でダウンロードしました:
2016122706



これで UTF-8 で書かれたクエリーごとの検索データを CSV で取得することができました。このファイル名を searchs.csv とします。

CSV のままだと取り扱いが不便なので、MySQL データベースに入れちゃいましょう。適当な(笑)MySQL データベースに、こんなスキーマのテーブルを作りました(CSV が UTF-8 なので、テーブルも UTF-8 指定しています):
mysql> create table searchs( id int primary key auto_increment, query varchar(100), clicks int, shows int, ctr float, rank float ) default character set utf8;

mysql> desc searchs
+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| id     | int(11)      | NO   | PRI | NULL    | auto_increment |
| query  | varchar(100) | YES  |     | NULL    |                |←クエリー
| clicks | int(11)      | YES  |     | NULL    |                |←検索結果からクリックされた回数
| shows  | int(11)      | YES  |     | NULL    |                |←検索結果に表示された回数
| ctr    | float        | YES  |     | NULL    |                |←クリック率
| rank   | float        | YES  |     | NULL    |                |←平均掲載順位
+--------+--------------+------+-----+---------+----------------+

先程の CSV をロードします:
mysql> load data local infile 'searchs.csv' into table searchs fields terminated by ',' (query,clicks,shows,ctr,rank);

これでサーチコンソールから取得した情報が MySQL データベースに入りました。こうなると色々楽ちんです。とりあえず phpMyAdmin あたりを使って、項目ごとに上位クエリーを調べてみましょう。

まずは検索表示回数。要は「マンホールマップが検索結果に表示された時、どのキーワードで検索されていたことが多いか?」です:
2016122702


ある意味想定通りですが、圧倒的一位は「マンホール」でした。マンホールマップを知らない人も含めた多くの人が「マンホール」を検索した結果だと思います。2位が「マンホールマップ」、知名度上がってると解釈していいでしょうか。3位は「豊井 スライド」(間にスペース)でした。これは何??ここからクリックされた形跡はなさそうだけど・・・いきなり深い謎に出会ってしまいました。。

面白いですね。では次はクリック回数。つまり検索結果に表示された回数ではなく、「検索結果に表示され、かつクリックしてマンホールマップに移動した回数」順です:
2016122701


これは「マンホールマップ」で検索した結果、マンホールマップに多く誘導できている、という当然の結果でした。そして「マンホール」で検索した人が「マンホールマップ」にたどり着いている、というパターンが2位でした。これも理想的で、いい結果です。その他地名との組み合わせで検索した結果が多くなっています。驚いたのは「さめがめ」で検索してマンホールマップにたどり着いた人がこの3ヶ月で3人いらっしゃったんですね。。。


次はクリック率(CTR=Click Through Ratio)、検索結果として表示されたうちの何%がクリックされたか、という数字です:
2016122703


いくつか 100% の例もありますが、嬉しいのは「マンホールマップ」で検索した人の 80%、「マンホール マップ」で検索した人の 60% が実際にクリックして訪れている、という結果です。マンホールファンはいい人が多いです(笑)。


最後に平均掲載順位。これは「検索結果の何番目にマンホールマップが表示されたか」の数字で小さいほど目立つ位置に表示されていることになります。そして 10 以下であれば検索結果の1ページ目に表示されていることになりますが・・・
2016122704


実はこの見方が僕もまだよく分かってなくて、例えば上記結果だけを見ると「ゆるキャラ」という検索結果に12回登場していて、その平均順位は 4.7 位(つまり最初のページに出ている)と読み取れます。マンホールマップがそんなに高い位置にいていいんだっけ?さすがにちょっと高すぎるような・・・

おそらくなんですが、実は検索時に "site:*****" とかの特殊なパラメータが付与された上での検索結果ではないかと想像しています。ただこの結果にそこまでの情報はないので、まあそのまま判断するしかないのかな、と。


ちなみにマンホールマップ全体としての平均 CTR は 8.07%、平均掲載順位は 14.3 でした。マニア向けのニッチな情報サイトから、より一般的なコミュニティサイトとして認知されるにはもう少し掲載順位を上げたい所ではあります。


こういう話は DeNA が詳しいのかな(苦笑)。

このページのトップヘ