ysaz (ImanazaS) blog

最近はデータ分析や機械学習が中心。たまに音楽や書評。

Chromebookを導入して

Chromebookを手に入れて3ヶ月近く経ったが、重宝しておりとても良い買い物をしたと感じている。

 

購入した機種はこれ。

ちなみに実際に購入したのは日本ではなくアメリカのAmazon.comであり、ネイビーが欲しかったが、なぜかアメリカ国外への配送は対応していないとのことでホワイトにすることに。 

 

購入にあたっての経緯は、

・持ち運びが楽で、Macbook Proよりも軽く、電池持ちの長いセカンドマシンがほしい。
iPad miniも所有しているが、タブレット端末は文字入力するには物足りない。やはり物理的なキーボードを備えていたほうがいい。

Macbook AirSurfaceもちらっと頭をよぎったが、10万近くもお金をつぎ込むほどではない。

Chromebookはインターネット環境下でないと使い物にならないという声も聞くが、そもそもiPadMac, PCをオフラインで使う機会は少ないし、その部分がディスアドバンテージになるとは思えない。

といったところで、2万円ほどで手に入るなら多少失敗してもいいや、と割り切りって、以下のブログやAmazonのレビューを参考にASUSのC201にした。

 

www.migiyoko.com

 

決め手となったのは980gという軽量さと、13時間もつという長時間バッテリー。

日本への移動だけでなく、ちょっとした外出時に持ち歩くにはもってこいのスペックという判断。

 

実際に届いてから使い始めて、このスペックは期待通りだったし、起動の早さや設定のシンプルさもとても気に入っている。

さらにデベロッパーモードに入ればLinux環境を構築することができ、pythonを走らせられるので、メールやウェブブラウジング以外でもやれることが増えて嬉しい。

ただ、自分にとって使い勝手のいい状態にまで持っていくのが少し面倒で、何度かやり直すこともあったため、主にデータサイエンス向けのpython環境構築については、いずれこのブログの中でもまとめておきたいと思う。

諦める力

Amazonの「Kindle Unlimited」というサービス(所定の本、コミック、雑誌、洋書が読み放題)を無料体験中で、いろいろと漁っていたところ、元陸上選手の為末大さんが書いた「諦める力」という本に出会い、読んでみた。

 

 

納得できる部分も多く、読んでみてよかったと思うし、もっと若い頃、願わくば10代後半に出会っていたかったとも思う。

僕自身、決して器用な人間ではなく、何か秀でた才能があるわけではないため、昔から、「諦めずに努力を続けていればきっと報われる」と信じ込み、がむしゃらに頑張るフシがあった。

そのために、いくら努力しても敵わない相手や、どう頑張っても変えられないような状況に出くわすと、圧倒的な力の差を感じて挫折を味わう、ということが何度かあった。

その度に、「このままではダメだ」と自分の現状を見つめ、時には努力が足りないからだ、と自分を責め、またある時には他人とは違うやり方を取らなければ自分の存在意義はないのではないか、と苦悩してきた。

本書の『「オンリーワン」の落とし穴』という節の中で、「人間に優劣はないが、能力に優劣はある」という記述がある。この部分が特に響いたのだが、それは上記のような過去の経験の中でこのような割り切りが出来ていなかったために、自分と他人を比べ(優劣をつけ)、自分より優れていると思った人を羨ましがり、自身を卑下して悩んでいたからだと気付いたためである。

こうした理由から、自分らしさを見つけなければならないと自分を追い込んでいた10代後半〜20代前半(主に大学生の頃)の自分がこの本に出会い、決して逃げではない、前向きに諦めるという選択があるということに気付いていれば、もう少し楽に生きてこられたのかもしれない。

 

一方で、諦めるという選択肢が与えられたからといって、簡単に夢を追いかけることをやめてしまったり、やるべき努力を怠ってしまうことが奨励されるわけではない。

才能には優劣はあるが、あくまで相対的な尺度であり、絶対な指標というものはありえない。そのため、たまたま目の前に巨大な才能が現れたからといってすぐに諦める必要はなく、いろんな角度から自分を客観視し、どういう立ち居振る舞いをするのがベターか、よく考えるべきである。

また、別の見方をすると、成功するのはバカか天才のどちらかと言われるように、周囲からいくら反対されても信念を貫きやり遂げるバカが一定数いないことには、世の中は面白くならないんじゃないか、とも思う。そう考えると、本書が与えてくれた諦めるという考え方・選択肢は、天才ともバカとも分類できない僕のような人間が、のびのびと楽しい人生を送るためのきっかけとなるものなのかもしれない。

日本への一時帰国 その2

年末年始の一時滞在中に感じたことのまとめ。

・電車とホームの間に段差があり、小さな車輪のベビーカーでは乗り降りがしにくい。

・マスク率の高さ。電車乗客の1割くらいがマスクしてる風景は少し異様。

・外で「すみません」を使う頻度が高い。とりあえず困ったときにすみませんと言っておけばなんとかなる。

・高齢者(お年寄り)の定義が難しい。公共機関でどの人に優先して席を譲ればよいか、判断しかねる場面も。席を譲られれば老若男女問わず喜ぶ人はきっと多いと思うけれど、それは一旦置いておいて。

・路線バス車内の幅が狭く感じる。天井が低いから全体的に狭く感じるだけ?

・1年半〜1年前に衝撃を受けた、爆買いしている中国人観光客が少なくなった。

・以前も書いたが、クレジットカード決済のやり辛さには少々ストレスを感じる。衣料品店なんかでカードリーダーが客側に置かれているケースも見受けられるが、アメリカやオーストラリアのように目線の高さにマウントされているのではなく、レジ台の上に置かれているため、少し腰を屈ませる必要があり辛い。

七月二十六日のこと(アイスランド)

2年前(2014年)の旅行記で、ほとんど記憶が薄れてしまっているけれど、せっかく途中まで下書きをしていたので、記事として形にしておこうというのが趣旨。

 

=============================================

この日は朝からゴールデン・サークルツアーに出かけた。要はレイキャビク近郊の有名観光スポットを一日でいいとこ取りできるツアー。乗り込んだのは比較的小ぶりのバスで、同じバスに乗っていた参加者は全部で15名程度。

 

最初に立ち寄ったのはHveragerði(クヴェラゲルジ)という温室栽培が有名な小さな町。2008年に大きな地震がこの町を襲ったそうで、そのときの様子を展示している案内所を見学した。

 

その後、ゲイシール(間欠泉)を一旦素通りし、先にグトルフォスの滝(通称、黄金の滝)へ向かった。45分ほどの時間が与えられ、自由に滝を楽しんだ。滝の落差は二段合わせて45m程とそれほど高いものではないが、とにかく流量とその爆音、水しぶきに圧倒された。写真にその凄みをうまく抑えられない、そんな感じのスポットだった。

 

f:id:nami3373:20140726065419j:plain

 

次に向かったのは、先に素通りしたGeyser(間欠泉)。Strokkur(ストロックル)という名前の間欠泉で、吹き上がる高さは20mほど。5〜10分に1度吹き上がるさまは圧巻で、カメラ片手にシャッターチャンスを見逃さまいと地表を見守っていた。いたるところで蒸気が立ち込めている様子はなんとも不思議で、日本の温泉街のそれとも違うし、異国での旅情をただ楽しむことができた。

 

ゴールデンサークルツアーの最後に訪れたのはシンクヴェトリル国立公園世界遺産に登録されているものの、ダイナミックに「大地が生きている」様子が実感できた先2つのポイントに比べるとやや印象の薄い場所ではあるが、ユーラシアプレートと北アメリカプレートがぶつかり合っているところと聞くと、特別な印象を抱かざるをえない。

後で知ったことだが、この公園は世界遺産でいうところの自然遺産ではなく文化遺産であり、その所以はアルシングと呼ばれる民主的な全島集会が開催されていた場所であるから、とのこと。

 

かくしてアイスランドの自然名所を巡り終え、首都レイキャビクへと戻った。アイスランドの雄大だがどこか陰のある景色を目の当たりにしたことで、良質な音楽を届けてくれるアーティストたちが影響を受けているであろう環境や文化の側面について知ることができ、本当に有意義な旅であった。

日本への一時帰国

久しぶりに日本へ一時帰国して感じたこと。


・エレベーターに乗ったとき、Ground Floorがなくてちょっと戸惑う。
・エレベーターのドアが開くときに、「こちらのドアが開きます」というアナウンスが流れると、どっちやねんと突っ込みたくなる。
・通勤ラッシュは異常。靴音をカッカッと鳴らしながらみんな無言で同じ方向を向かって進んでいる光景はなんとも言えない。
・クレジットカード決済がやりづらい。電子マネーリーダーだけじゃなくて、PINパッド付きのクレジットカードのリーダーも客側に置いてくれればいいのにと思う。
・無料wifiの使える場所が少ない。
・コンビニがそこらじゅうにある。文字通り便利。

Pythonを使ったRFM分析

今回はこれまでと趣向を変えて、サンプルデータを使った分析手法(RFM分析)について取り上げる。

RFM分析は、Recency(直近)、Frequency(頻度)、Monetary(購入額)の略であり、マーケティングの分野において、顧客をグループ化した上で優良顧客を抽出し、確度の高い施策を講じる際に用いられる。

今回サンプルデータとして、以下にアップされているものを利用した。
RFM-analysis/sample-orders.csv at master · joaolcorreia/RFM-analysis · GitHub

import pandas as pd
import matplotlib.pyplot
import datetime as dt

# ファイルの読み込み
df = pd.read_csv('sample-orders.csv',sep=',')
df['order_date'] = pd.to_datetime(df['order_date'])
df.head()

#   order_date        order_id          customer  grand_total
# 0 2011-09-07  CA-2011-100006       Dennis Kane          378
# 1 2011-07-08  CA-2011-100090        Ed Braxton          699
# 2 2011-03-14  CA-2011-100293  Neil Franz�sisch           91
# 3 2011-01-29  CA-2011-100328   Jasper Cacioppo            4
# 4 2011-04-08  CA-2011-100363       Jim Mitchum           21

NOW = dt.datetime(2014,12,31)

# 顧客名を軸にデータをグループ化し、R、F、Mの3つの列を作成
rfmTable = df.groupby('customer').agg({'order_date': lambda x: (NOW - x.max()).days, # Recency
                                        'order_id': lambda x: len(x),      # Frequency
                                        'grand_total': lambda x: x.sum()}) # Monetary Value

rfmTable['order_date'] = rfmTable['order_date'].astype(int)
rfmTable.rename(columns={'order_date': 'recency', 
              'order_id': 'frequency', 
              'grand_total': 'monetary_value'}, inplace=True)
rfmTable.head()

#                  frequency  recency  monetary_value
# customer                                           
# Aaron Bergman            3      415             887
# Aaron Hawkins            7       12            1744
# Aaron Smayling           7       88            3050
# Adam Bellavance          8       54            7756
# Adam Hart               10       34            3249

# R、F、Mのそれぞれについて4段階でスコア付けをする関数を定義
def pct_rank_qcut(series, n):
    edges = pd.Series([float(i) / n for i in range(n + 1)])
    f = lambda x: (edges >= x).argmax()
    return series.rank(pct=1).apply(f)

# Recency
rfmTable['rec_dec'] = pct_rank_qcut(rfmTable['recency'], 4)

# Frequency(数が大きなものを1、小さなものを4とランク付け)
freq_dec = pct_rank_qcut(rfmTable['frequency'], 4)
rfmTable['freq_dec'] = 5 - freq_dec

# Monetary(数が大きなものを1、小さなものを4とランク付け)
mv_dec = pct_rank_qcut(rfmTable['monetary_value'], 4)
rfmTable['mv_dec'] = 5 - mv_dec

# R、F、Mの3つを組合せて、RFMスコアを作成
rfmTable['RFMClass'] = rfmTable.rec_dec.map(str) + rfmTable.freq_dec.map(str) + rfmTable.mv_dec.map(str)
rfmTable.head()

#                  frequency  recency  monetary_value  rec_dec  freq_dec  \
# customer                                                                 
# Aaron Bergman            3      415             887        4         4   
# Aaron Hawkins            7       12            1744        1         2   
# Aaron Smayling           7       88            3050        3         2   
# Adam Bellavance          8       54            7756        2         2   
# Adam Hart               10       34            3249        2         1   

#                  mv_dec RFMClass  
# customer                          
# Aaron Bergman         4      444  
# Aaron Hawkins         3      123  
# Aaron Smayling        2      322  
# Adam Bellavance       1      221  
# Adam Hart             2      212  

# Recencyの4つのグループにつき、購入金額の平均を比較
rec_dec_m = rfmTable.groupby(['rec_dec'])['monetary_value'].mean()
rec_dec_m.plot(kind='bar')

# Frequencyの4つのグループにつき、購入金額の平均を比較
freq_dec_m = rfmTable.groupby(['freq_dec'])['monetary_value'].mean()
freq_dec_m.plot(kind='bar')

Recencyに対するチャート(縦軸:購入金額の平均)
f:id:nami3373:20160919233951p:plain

Frequencyに対するチャート(縦軸:購入金額の平均)
f:id:nami3373:20160919233956p:plain

Pandasを使った行列のセレクティングについて

pandasでのiloc[行, 列]を使った操作に関する備忘録。
特定のデータを行あるいは列から抜き出して表示したり、違う数値へ置き換えたりする方法について記す。

import numpy as np
import pandas as pd

# データフレームの作成
df = pd.DataFrame(data=
[('2016-04-01', 10.2, 60.3), 
('2016-04-02', 16.4, 71.7), 
('2016-04-03', 11.1, 65.6), 
('2016-04-04', 15.1, 73.2)])
df.columns = ['date', 'temp', 'humidity']
df
#          date  temp  humidity
# 0  2016-04-01  10.2      60.3
# 1  2016-04-02  16.4      71.7
# 2  2016-04-03  11.1      65.6
# 3  2016-04-04  15.1      73.2

# データフレームから2行目のデータを抜き出し
df.iloc[1, :]
# date        2016-04-02
# temp              16.4
# humidity          71.7
# Name: 1, dtype: object

# データフレームから上2行のデータのみを抜き出し
df.iloc[:2]
#          date  temp  humidity
# 0  2016-04-01  10.2      60.3
# 1  2016-04-02  16.4      71.7

# データフレームから2列目のデータ(気温)を抜き出し
df.iloc[:, 1]
# 0    10.2
# 1    16.4
# 2    11.1
# 3    15.1
# Name: temp, dtype: float64

# 指定した位置にあるデータを別のものに置き換える。
df.loc[df['date'] == '2016-04-01', 'temp'] = 12.3
df
#          date  temp  humidity
# 0  2016-04-01  12.3      60.3
# 1  2016-04-02  16.4      71.7
# 2  2016-04-03  11.1      65.6
# 3  2016-04-04  15.1      73.2

行列の選択においてloc, iloc, ixという3つのメソッドが存在するが、以下のページによるとその違いは、
python - pandas iloc vs ix vs loc explanation, how are they different? - Stack Overflow

  • loc: インデックスのラベル名に対応
  • iloc: インデックスの順序に対応
  • ix: 基本はlocのように振る舞うが、インデックスにラベル名が存在しない場合、ilocのように振る舞う

とのことらしい。

例えば、2列目のデータを抜き出す際に"iloc"を使用しているが、行(すなわちインデックスおよびラベル名)を指定してないため、"loc"は使えず、エラーが返される。また、同じ例で"ix"を使った場合、"loc"が使えないので"iloc"と同じ結果が得られることになる。


なお、今回のデータの選択処理については、以下サイトも参考にしている。
sinhrks.hatenablog.com