Pandasデータフレーム内の複数の文字を「.str.split」を使って区切る
Pandas(@Python)のデータフレーム内のstringを複数の文字で区切りたい場合があります.
「.str.split」を使うのですが少し工夫が必要です.
まぁ,簡単に言うと縦棒「|」で区切るわけですよ.
import pandas as pd df = pd.DataFrame( {'Time': ['jt=10:00:00:-p', 'jt=10:01:01:-p', 'jt=10:10:02:-p', 'jt=10:50:03:-p', 'jt=11:00:04:-p'], 'Value': [25, 30, 104, 52, 41]}) df_spr = df['Time'].str.split('=|:-', expand=True) print(df_spr)
出力すると・・
0 1 2 0 jt 10:00:00 p 1 jt 10:01:01 p 2 jt 10:10:02 p 3 jt 10:50:03 p 4 jt 11:00:04 p
ベイズ更新をやってみた!
3月の末にベイズ推定の勉強会に参加してきました!
math-unknown.connpass.com
この勉強会では単に講師の話を聞くだけではなく,みんなでワイワイディスカッションしながら進めるような形式で,グループ内の誰かが疑問に思ったことを後で調べることでより理解が深まったように思います.
そして講師の方の説明の流暢さに脱帽でした!
その中でもベイズ更新の例としてオオカミ少年の例が興味深いと思いました.勉強会の案内のところに次のリンクが貼ってあったので,共有しておきます.
okandayo.hatenablog.com
ベイズ更新を使ってオオカミ少年の例をシミュレーションしてみようと思いましたが,なかなか時間がなく出来ませんでした.ようやく取り掛かることが出来たのでちょこっとやってみたわけです.
問題設定
次のような風に問題文を作ってみます.「オオカミ少年」のお話は昔NHKの番組で見たことがある程度なのでうろ覚えですが,少年が嘘をついて「オオカミが来たぞ!」と叫んでいるうちに村人が誰も少年を信用しなくなってしまい,本当にオオカミが来た時に村人が食べられてしまった話だったと思います.
問題文;オオカミ少年
ある村では嘘つきは75%の確率で嘘をつき,正直者は85%の確率で本当のことを証言することが知られている.
この村のある少年は事あるごとに「オオカミが来たぞ!」と叫んでいるが,本当に狼が来るときと来ない時があるようだ.この少年は嘘をついている,もしくは時々間違えるようである.この少年が100回叫んだ結果から,この少年は正直者か嘘つきかを答えよ.
問題文から仮定と各値を書き出す
この問題文から,次の様のような仮定を置きます.
- :少年は嘘つき
- :少年は正直者
「オオカミが来たぞ!」と叫ぶイベントに対して,本当にオオカミが来る事象と来ない事象があります.これを次のように置きます.
- :少年は嘘をつく(「オオカミが来たぞ!」と叫んだときにオオカミが来ない)
- :少年は本当のことを言う(「オオカミが来たぞ!」と叫んだときにオオカミが来る)
とは「オオカミが来たぞ!」と叫んで来ないときと実際に来たときに相当します.これらには次の図のような関係があります.
]
さて,次に問題文からそれぞれの値を次のように置きます.
- :ある村で嘘つきが本当の証言をする確率
- →嘘つきが「オオカミが来たぞ!」と叫んで,オオカミが来る確率
- :ある村で正直者が本当の証言をつく確率
- →正直者が「オオカミが来たぞ!」と叫んでオオカミが来る確率
- :ある村で嘘つきが嘘の証言をする確率
- →嘘つきが「オオカミが来たぞ!」と叫んでもオオカミが来ない確率
- :ある村で正直な人が間違えて嘘の証言をする確率
- →正直者が間違えて「オオカミが来たぞ!」と叫んでオオカミが来ない確率
これを表にするとこんな感じです.
オオカミが来る | オオカミが来ない | |
嘘つき | 0.15 | 0.85 |
正直 | 0.75 | 0.25 |
シミュレーション
次に実際にシミュレーションしてみます.Pythonでこんな感じに書きました.
import numpy as np import matplotlib.pyplot as plt # 確率の設定 p_AH1 = 0.15 # 嘘つきがが嘘をついてオオカミが来ない確率 p_AH2 = 0.75 # 正直者が本当のことを言ってオオカミが来る確率 p_barAH1 = 0.85 # 嘘つきが間違えて正しいことを言う確率 p_barAH2 = 0.25 # 正直者が間違える確率 # 嘘つきである確率の初期値 p_l = [0.5] # ループ計算 for i in range(99): rand = np.random.random() #「オオカミが来たぞ!」と叫んだときに狼が来る if rand >0.5: p_l.append(p_l[i]*p_barAH1/(p_barAH1*p_l[i]+p_barAH2*(1-p_l[i]))) #「オオカミが来たぞ!」と叫んだときに狼が来ない else: p_l.append(p_l[i]*p_AH1/(p_AH1*p_l[i]+p_AH2*(1-p_l[i]))) # 描画 plt.plot(range(100),p_l) plt.xlabel('times') plt.ylabel('H1') plt.grid() plt.show()
ATOMをCドライブ以外にインストールする方法
ATOMってエディタがあって,これはでは「こいつはCドライブ以外にインストールできないのか?」と思っていましたが,ひょんなことからDドライブとかにもインストールできました.
ある時ATOMを再インストールしようとすると「Installation has failed」と表示されました.なので下記を参考にさせていただきました.
takumi9942.net
これによれば
ということでしたが,この3番めのファイルを展開する際にD:\Tempとかで展開すればDドライブにもインストールできるというわけです.
おしまい.
PandasとStatsModelsを使って重回帰分析をしてみた
Pythonで重回帰分析をやってみました
- 作者: 永田靖,棟近雅彦
- 出版社/メーカー: サイエンス社
- 発売日: 2001/04/01
- メディア: 単行本
- 購入: 2人 クリック: 9回
- この商品を含むブログ (1件) を見る
- 作者: 高橋信,井上いろは,トレンドプロ
- 出版社/メーカー: オーム社
- 発売日: 2005/09/01
- メディア: 単行本
- 購入: 42人 クリック: 186回
- この商品を含むブログ (101件) を見る
今回はStatsModelsというライブラリを使いました.
データを可視化する
データファイルを読み込んでどんなデータかを観察します.
今回は3次元データなので3次元プロットをしてみます.
# データの読み込み import pandas as pd file = 'reg_test_data.csv' df = pd.read_csv(file) df = df.set_index('val')
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 初期化 fig = plt.figure() ax = Axes3D(fig) # 軸ラベルを設定する ax.set_xlabel("X-axis") ax.set_ylabel("Y-axis") ax.set_zlabel("Z-axis") # データを無理やりarrayに変換する xs = df.T.ix[:,0].values ys = df.T.ix[:,1].values zs = df.T.ix[:,2].values # 描画 ax.scatter3D(xs, ys, zs) plt.show()
3次元プロットをしてみるとこんな感じです.
横からみるとこんな感じです.x1とx2には相関はなさそうですが,x1とy,x2とyには相関がありそうです.
散布図行列を描く
描画をしただけだと感覚的にしかわからないので,定量的に評価します.
今回は散布図行列という可視化をしてみました.
from pandas.tools.plotting import scatter_matrix scatter_matrix(df.T) plt.show()
相関係数を計算する
同じく,各変数の相関を定量評価します.
# 相関係数を表示 df.T.corr() print(df.T.corr())
val x1 x2 y val x1 1.000000 -0.170384 0.675085 x2 -0.170384 1.000000 0.603907 y 0.675085 0.603907 1.000000
この通りx1とx2には相関はなさそうですが,x1とy,x2とyには相関がありそうというのがわかります.
重回帰分析の計算をする
ここからが実際の分析です.
今回使ったStatsModelsのドキュメントは下記のとおりです
import statsmodels.formula.api as sm reg = "y ~ x1 + x2" model = sm.ols(formula=reg, data=df.T) # 回帰分析を実行する result = model.fit()
============================================================================== Dep. Variable: y R-squared: 0.988 Model: OLS Adj. R-squared: 0.987 Method: Least Squares F-statistic: 703.1 Date: Sun, 28 Jan 2018 Prob (F-statistic): 4.53e-17 Time: 19:34:45 Log-Likelihood: -25.297 No. Observations: 20 AIC: 56.59 Df Residuals: 17 BIC: 59.58 Df Model: 2 Covariance Type: nonrobust ============================================================================== coef std err t P>|t| [95.0% Conf. Int.] ------------------------------------------------------------------------------ Intercept 0.7622 0.829 0.919 0.371 -0.988 2.512 x1 1.0248 0.034 29.785 0.000 0.952 1.097 x2 1.0218 0.037 27.524 0.000 0.943 1.100 ============================================================================== Omnibus: 4.291 Durbin-Watson: 1.543 Prob(Omnibus): 0.117 Jarque-Bera (JB): 1.439 Skew: 0.024 Prob(JB): 0.487 Kurtosis: 1.687 Cond. No. 86.1 ==============================================================================
回帰式を使ってもう一回描画する
# 先程の結果から値を獲得 b0,b1,b2= result.params # もう一回描画する import numpy as np # 変数の区間の指定 x = np.arange(0, 21, 3) y = np.arange(0, 21, 3) # メッシュ表示 X, Y = np.meshgrid(x, y) # 回帰式を代入する Z = b0 + b1*X +b2*Y # 初期化 fig = plt.figure() ax = Axes3D(fig) ax.plot_wireframe(X,Y,Z) # 軸名を設定する ax.set_xlabel("X-axis") ax.set_ylabel("Y-axis") ax.set_zlabel("Z-axis") # 表示範囲を指定する ax.set_xlim(-5, 25) ax.set_ylim(0, 25) ax.set_zlim(0, 35) # データを無理やりarrayに変換する xs = df.T.ix[:,0].values ys = df.T.ix[:,1].values zs = df.T.ix[:,2].values
結構上手くフィティングされているように見えます.
真横から見ると,ピタッと合っている気がします
PyCharm:interpolaterの設定にまつわるエラー
年末年始にかけてPyCharmをインストールし直したら,エラーが出まくりました・・・
自分が勉強不足のところもあるわけですが,直すのに時間が掛かりました.
色々試行錯誤したのでメモっておきます.
ちなみにインストールしているバージョンは「Anaconda3-5.0.1-Windows-x86_64」「pycharm-community-2017.3.2」です.
そもそもRun出来ない場合
症状
Runしようとすると
Please Select a valid Python interpolater
と出る.
ちなみにバージョンはCommunity版の2017.3
解決法
stackoverflowに書いてあったのでメモ
- 左上の「File」
- 「Settings」
- 「Project:○○(プロジェクトの名前)」
- Project interpolater右のギアマーク
- Add Local
ライブラリが読み込めない,importしない
症状
- Pandasとかを読み込もうとすると,「ModuleNotFoundError: No module named ~~」とか出る
- improt OSなどはできる
- 上の写真のようにPandasのところだけ「no module name」と出る
- Jupyter Notebookとかではimportできる
解決法
これは正しい解決法か知りませんが,Projectを作成する際に,「Existing interplater」の値にAnaconda直下のPython3のEXEファイルを代入しました
Pandas:グループ毎に括って最大の値を含む列を抜き出す
PythonのライブラリーであるPandasを使って,「グループ毎に括って最大の値を含む列を抜き出す」方法のメモです.
対象とするのはこんなデータ
Sensor Time Value 0 T-A 10:00:00 25 1 T-B 10:00:01 30 2 T-C 10:00:02 104 3 T-B 10:00:03 52 4 T-C 10:00:04 41 5 T-A 10:00:05 91 6 T-C 10:00:06 102 7 T-B 10:00:07 40 8 T-B 10:00:08 101 9 T-C 10:00:09 97
3種類のSensorから時間と検知された値(Value)が返ってきます.
Sensorの種類ごとに括って,その中で最大の値を出す時間(と言うか行)を抜き出す,というのが今回の狙いです.
コードは下記の通り.
特定の列に含まれる最大値を含む行を抜き出す(日本語が複雑・・)方法が分からなかったのでやや力技を使いました.
import pandas as pd # データ生成 df = pd.DataFrame( {'Time': ['10:00:00', '10:00:01', '10:00:02', '10:00:03', '10:00:04','10:00:05', '10:00:06', '10:00:07', '10:00:08', '10:00:09'], 'Sensor': ['T-A', 'T-B', 'T-C', 'T-B', 'T-C', 'T-A', 'T-C', 'T-B' ,'T-B' ,'T-C'], 'Value': [25, 30, 104, 52, 41, 91, 102, 40 ,101 ,97]}) # datetime型に変換 df['Time'] = df['Time'].apply(lambda dd: pd.to_datetime(dd)) # 'Sensor'で括る df_g = df.groupby('Sensor') # 'Sensor'でくくられたデータフレームの中で'Value'に最大値を含む行を抜き出す def select(xx): # 'Value'に最大値を含む行を抜き出す(そういうメソッドがあるのかもしれないけど分からなかった) val_r = xx[xx['Value'] == max(xx['Value']) ] # 全く同じ行があった場合は削除(このデータの場合は無いですけど) val_r = val_r.drop_duplicates() return val_r df_new = df_g.apply(select)
ご覧の通り,Valueに含まれる最大値を含む行は無理やり書きました.
結果は下記の通り
Sensor Time Value Sensor T-A 5 T-A 2017-10-08 10:00:05 91 T-B 8 T-B 2017-10-08 10:00:08 101 T-C 2 T-C 2017-10-08 10:00:02 104
Anacondaをインストールしようとすると「Failed to create Anaconda menus」と言われる
Anacondaをアップデートしたらおかしくなったので再インストールした.
そしたら「Failed to create Anaconda menus」と言われてインストールできない.
アンインストールしてもフォルダが残っていたので削除したらインストールできたっぽい