Parabola JournalPython

Rグラフィックスクックブックをpythonのggplotで試す(2)

引き続き.
python+ggplotのセットアップ | 左京区パラボラ日記
Rグラフィックスクックブックをpythonのggplotで試す | 左京区パラボラ日記

この本を試してみる.

Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集
Winston Chang
オライリージャパン
売り上げランキング: 48,925

Rで作られる横に並んだような棒グラフ.関数scale_fill_brewerや実装上のズレ?よりpython#ggplotでは実現できない.

スクリーンショット 2015-01-10 21.47.39

他にも全体的に棒グラフの処理はR#ggplotに比べて苦手なように感じる.詳細は不明.例えば左右のスケールで少し描画にあまり領域が出る事がある.

figure_3

こういう棒グラフも出来ない.geom_bar(position=”dodge”)の”dodge”がおそらく未実装.

output

こういうグラフも出来ない.軸指定でこの場合は文字列データを軸に置こうとしている(aesのy=””)けど,これがPythonではエラーになる.全体的にこういう微妙な差異は上手く吸収できない様子.あとこの章だとgeom_ribbonも未実装っぽかった.

output

Parabola JournalPython

Rグラフィックスクックブックをpythonのggplotで試す

引き続き.
python+ggplotのセットアップ | 左京区パラボラ日記

この本を試してみる.

Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集
Winston Chang
オライリージャパン
売り上げランキング: 48,925

ただしRのggplotに入っているデータセットがpythonのggplotには当然入っていないので,CSVで書きだした後にpython側のpandas#read_csvを使ってpandas#DataFrameとして読み込む必要がある.例.
# R
library(ggplot2)
write.table(pressure, file="pressure.csv", sep=",", row.names=FALSE)

# Python
import pandas as pd
data_frame = pd.read_csv("presssure.csv")

またすべての関数は(おそらく)実装されていないので,一部は別の方法を試す必要があるかもしれない(要確認).例えばqplotは実装されていないので,普通にggplot関数を使う必要がある.Too
# R
ggplot(mtcars$wt, mtcars$mpg)

# python
ggplot(aes(x="wt", y="mpg"), data=mtcars) + geom_point()

散布図の例.
figure_1

Rで言うfactor関数はpythonにはないけど,ggplotの機能で実装されていた.
ggplot(mtcars, aes(x='factor(cyl)')) + geom_bar()

figure_2

序盤の例ではgeom_boxplot(); 箱ひげ図が上手く動かなかった.

Python

python+ggplotのセットアップ

numpy/scipy/matplotlibはインストールされていたが,何故かpipが入っていなかったのでインストール.

port install py27-pip
port select --set pip pip27


ggplotのインストール(参考: https://github.com/yhat/ggplot)
pip install ggplot


サンプルコードを打ち込む.
from ggplot import *

print ggplot(mtcars, aes('mpg', 'qsec')) + \
  geom_point(colour='steelblue') + \
  scale_x_continuous(breaks=[10,20,30],  \
                     labels=["horrible", "ok", "awesome"])


動いた.

figure_1

楽しい.

参考URL

Parabola JournalPython

ヒストグラムからサンプルを取る(numpy.random.choice)

最近のバージョンのnumpyだとnp.random.choiceを使える.
numpy.random.choice — NumPy v1.9 Manual

hist = np.array([1,2,3], dtype=float) # 1:2:3の比率でサンプル ([0,1,2])
hist = hist / hist.sum()
cc = np.random.choice(len(hist), 100, p=hist)
print len(np.where(cc==0)[0]) # Example) 13, 16
print len(np.where(cc==1)[0]) # Example) 33, 29
print len(np.where(cc==2)[0]) # Example) 54, 55

PythonMachine Learning

円の方程式/人工データ作成/スペクトラムクラスタリング

よくある例題データみたいなのを使ってscikit-learn(sklearn)を使ってスペクトラムクラスタリングを(英語版Wikipedia)を試そうと思っていろいろやっていたのをメモしておく.

円の方程式

凄い当たり前だけど,半径rの円上の点を生成するには三角関数(cos/sin)を使えばいい.媒介変数とし角度θ(0≦θ≦2π)として,θの基準となる軸からθだけ回転した点の(x,y)座標は (r \cos(\theta), r \sin(\theta))

人工データの作成

適当に小さい円(r=1.5)と大きい円(r=3.0)に関して人工データを作成する.どうやって二次元ベクトルを作るかよく分からなかったのでnumpy.r_[X,Y]というベクトルをくっつけてくれるっぽい感じのメソッドをそのまま使った.媒介変数θは0から2πの間を適当に分割して作った.こういう昨日はMatlabと一緒でnumpy.linspaceがやってくれる.2つ作った店の集合(small/large)を縦にくっつけるのにnumpy.r_とは反対でnumpy.c_を使った.ついでに(標準)正規分布の乱数を適当に付けた(numpy.random.randn)
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
np.random.seed(0)

N = 500
theta = np.linspace(0, 2 * np.pi, N / 2)
r1, r2 = 1.5, 3.0
small = np.c_[r1 * np.cos(theta), r1 * np.sin(theta)]
large = np.c_[r2 * np.cos(theta), r2 * np.sin(theta)]
dataX = np.r_[small, large] + np.random.randn(N, 2) * 0.25

# plot
plt.figure()
plt.plot(dataX[:,0], dataX[:,1], 'bo')
plt.savefig("sample.png")

プロットするとよくある図みたいにこうなる.
sample

スペクトラムクラスタリング

スペクトラムクラスタリングに関してはリンク先が解説してくれている(スペクトラルクラスタリングの話 – おいしいお米の話).numpy/scipyだけではなく,ここからはscikit-learnを使う.スペクトラムクラスタリングに相当する機能はsklearn.clusterに納められているクラスタリング関係のパッケージ群の中に

  • SpectralClustering (クラス)
  • spectral_clustering (関数)
の2つが何故か用意されていて,関数で直接計算する場合とクラスにいろいろとパラメータを設定してfit→predictするという,いつものsklearn方式が使える,と思いきやfit_predictという関数に統合されているという謎な感じになっている.スペクトラムクラスタリングに必要な行列W(affinity matrix)をどう計算するかという問題があるけど,データをnumpy.ndarrayの形(例えば人工データのdataX)で入れると,クラスSpectralClustering自体が計算してくれる.パラメータを設定すると,事前に自分が計算した行列を使うことも可能.以下のように使う.

# spectral clustering by scikit-learn
from sklearn.cluster import SpectralClustering, spectral_clustering
sc = SpectralClustering(n_clusters = 2, eigen_solver='arpack', affinity = 'rbf', gamma = 10.0)
assigned_labels = sc.fit_predict(dataX)

assigned_labels(SpectralClustering#fit_predictの返り値)にはfitしたデータ(dataX)の各データ点がどのクラスタ番号に割り振られたか,というラベル情報が返ってくるので,それとnumpy.whereを使ってデータを分けることが可能.

plt.figure()
c1 = dataX[np.where(assigned_labels == 1)]
c0 = dataX[np.where(assigned_labels == 0)]
plt.plot(c1[:,0], c1[:,1], 'bo')
plt.plot(c0[:,0], c0[:,1], 'rx')
plt.savefig("clustered.png")

プロットするとよくある感じの結果が得られた.

clustered