質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3906閲覧

pymc3でベイズ推定

color_8

総合スコア20

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/01/31 06:31

編集2020/01/31 13:05

映画サイトのレビュー(星マークの0〜5)の妥当性をベイズ推論で評価しようと考えてます。

取り込んだデータは以下のような形です
イメージ説明

▼変数の説明
review_rate →これがレビュー(0〜5で投稿されたものの平均)
review_num  →レビューの投稿数

これに対して、以下の通りモデルの設計をしました。

python

1##------------------------------- 2# モデルの設計 3##------------------------------- 4 5# レビュー評価の事後分布の軌跡(trace)を取得する 6# レビューの評価は0.0〜5.0のものを、0~1の範囲の一様分布で扱うため、引数で与えられた値に対して調整を加える 7# name は確率変数名 8def get_posterior_review_rate_trace(review_rate, review_num): 9 _review_rate = pm.Uniform(name='review_rate', lower=0, upper=1) 10 review_rate_0_to_1 = (review_rate - 1) * 0.25 11 print('0~1の範囲でのレビュー評価 : ', review_rate_0_to_1) 12 13 # 連続確率変数のためBeta分布を使用 14 theta = pm.Beta(name='theta', alpha=1, beta=1) 15 observations = pm.Binomial( 16 # nはレビュー数、valueはレビュー評価にレビュー数を乗算した値を指定 17 name='obs', n=review_num, p=theta, 18 value=review_rate_0_to_1 * review_num, 19 observed=True) 20 map_ = pm.MAP([theta, observations]).fit() 21 model = pm.Model([theta, observations]) 22 mcmc = pm.MCMC(model) 23 # MCMCの探索を。第一引数は探索回数。第二引数のバーンインは最初の収束していない一定数は好ましくないので破棄して5000件目~20000件目のサンプリング結果を取得 24 mcmc.sample(20000, 5000) 25 # 探索結果のthetaの確率変数の軌跡を取得 26 trace = mcmc.trace('theta') 27 return trace 28

次に、モデルの妥当性を評価するため、以下の処理を実行しました。

python

1##------------------------------- 2# モデルの妥当性を確認 3##------------------------------- 4import pymc3 as pm 5from pymc3 import plots as mcplot 6 7 8# レビュー評価4.5に対して、取得した軌跡(trace)を引数に渡して事後分布の確認 9trace_of_review_num_2 = get_posterior_review_rate_trace( 10 review_rate=4.5, review_num=2)

その結果、事後分布を確認するつもりなのですが、
ここで、以下のエラーが発生してしまいます。


IndexError Traceback (most recent call last)
~/anaconda3/lib/python3.7/site-packages/pymc3/model.py in get_context(cls, error_if_none)
212 try:
--> 213 candidate = cls.get_contexts()[idx] # type: Optional[T]
214 except IndexError as e:

IndexError: list index out of range

During handling of the above exception, another exception occurred:

TypeError Traceback (most recent call last)
~/anaconda3/lib/python3.7/site-packages/pymc3/distributions/distribution.py in new(cls, name, *args, **kwargs)
32 try:
---> 33 model = Model.get_context()
34 except TypeError:

~/anaconda3/lib/python3.7/site-packages/pymc3/model.py in get_context(cls, error_if_none)
217 if error_if_none:
--> 218 raise TypeError("No %s on context stack"%str(cls))
219 return None

TypeError: No <class 'pymc3.model.Model'> on context stack

During handling of the above exception, another exception occurred:

TypeError Traceback (most recent call last)
<ipython-input-3-3c1692da3682> in <module>
1 # レビュー評価4.5に対して、取得した軌跡(trace)を引数に渡して事後分布の確認
2 trace_of_review_num_2 = get_posterior_review_rate_trace(
----> 3 review_rate=4.5, review_num=2)

<ipython-input-1-04c321e246cf> in get_posterior_review_rate_trace(review_rate, review_num)
30 # name は確率変数名
31 def get_posterior_review_rate_trace(review_rate, review_num):
---> 32 _review_rate = pm.Uniform(name='review_rate', lower=0, upper=1)
33 review_rate_0_to_1 = (review_rate - 1) * 0.25
34 print('0~1の範囲でのレビュー評価 : ', review_rate_0_to_1)

~/anaconda3/lib/python3.7/site-packages/pymc3/distributions/distribution.py in new(cls, name, *args, **kwargs)
33 model = Model.get_context()
34 except TypeError:
---> 35 raise TypeError("No model on context stack, which is needed to "
36 "instantiate distributions. Add variable inside "
37 "a 'with model:' block, or use the '.dist' syntax "

TypeError: No model on context stack, which is needed to instantiate distributions. Add variable inside a 'with model:' block, or use the '.dist' syntax for a standalone distribution.

上記を解消するためのコードを教えていただけませんでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2020/01/31 11:03

エラーは全文ですか? 全文でない場合は全文掲載してください。
color_8

2020/01/31 13:06

ご確認有難うございます。 エラーコードを全文記載しました。 お手数ですが、ご確認頂けますと幸いです。
meg_

2020/01/31 13:53

_review_rate = pm.Uniform(name='review_rate', lower=0, upper=1)の前に 「with pm.Model() as model:」の一文を追加してみてください。
color_8

2020/01/31 14:08

ご指摘頂いた1文を追加してみたところ、やはり同じところ --- # レビュー評価4.5に対して、取得した軌跡(trace)を引数に渡して事後分布の確認 trace_of_review_num_2 = get_posterior_review_rate_trace( review_rate=4.5, review_num=2) --- ↑このコードを実行した後に、以下のエラーが発生しました。 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-3-3c1692da3682> in <module> 1 # レビュー評価4.5に対して、取得した軌跡(trace)を引数に渡して事後分布の確認 2 trace_of_review_num_2 = get_posterior_review_rate_trace( ----> 3 review_rate=4.5, review_num=2) <ipython-input-1-e8bd83e316d6> in get_posterior_review_rate_trace(review_rate, review_num) 41 name='obs', n=review_num, p=theta, 42 value=review_rate_0_to_1 * review_num, ---> 43 observed=True) 44 map_ = pm.MAP([theta, observations]).fit() 45 model = pm.Model([theta, observations]) ~/anaconda3/lib/python3.7/site-packages/pymc3/distributions/distribution.py in __new__(cls, name, *args, **kwargs) 44 raise TypeError("observed needs to be data but got: {}".format(type(data))) 45 total_size = kwargs.pop('total_size', None) ---> 46 dist = cls.dist(*args, **kwargs) 47 return model.Var(name, dist, data, total_size) 48 else: ~/anaconda3/lib/python3.7/site-packages/pymc3/distributions/distribution.py in dist(cls, *args, **kwargs) 55 def dist(cls, *args, **kwargs): 56 dist = object.__new__(cls) ---> 57 dist.__init__(*args, **kwargs) 58 return dist 59 ~/anaconda3/lib/python3.7/site-packages/pymc3/distributions/discrete.py in __init__(self, n, p, *args, **kwargs) 61 62 def __init__(self, n, p, *args, **kwargs): ---> 63 super().__init__(*args, **kwargs) 64 self.n = n = tt.as_tensor_variable(intX(n)) 65 self.p = p = tt.as_tensor_variable(floatX(p)) ~/anaconda3/lib/python3.7/site-packages/pymc3/distributions/distribution.py in __init__(self, shape, dtype, defaults, *args, **kwargs) 181 "are not allowed.") 182 --> 183 super().__init__(shape, dtype, defaults=defaults, *args, **kwargs) 184 185 TypeError: __init__() got an unexpected keyword argument 'value'
color_8

2020/01/31 14:14

ちなみに、補足させていただきますと やりたいこととしては、以下のURLに載っているものと同じ分析をしてみようと考えてます。 https://qiita.com/simonritchie/items/c06219d45618140ab26c しかし、上記のサイトは「pymc」を使っているのですが、環境として「pymc3」しか使えないため、 mypc3に変更して試みているのですがつまづいております。
guest

回答1

0

ベストアンサー

下記コードはエラーなく動きますか?

Python

1import pymc3 as pm 2 3with pm.Model() as model: 4 _review_rate = pm.Uniform(name='review_rate', lower=0, upper=1)

下記環境では問題なく実行できました。
Python:3.6.9
pymc3:3.7


【追記】
質問のコードの下記部分を変更したところ(変数名modelが重複していたのでmodel2に変更)

Python

1model2 = pm.Model([theta, observations]) 2 mcmc = pm.MCMC(model2)

「0~1の範囲でのレビュー評価 : 0.875」の表示までは出来ました。他のエラーが出ましたが
TypeError: init() got an unexpected keyword argument 'value'
そちらの環境では問題なく動くのではないでしょうか?


【追記】
pm.Binomial()のところで、observed=review_rate_0_to_1 * review_numに変更し、TypeErrorは解消しました。
しかし下記コードにて「pm.MAP」と「pm.MCMC」でAttributeErrorが出ます。
pymc3にはこれらのAttributeはないようです。
この2つの代々手段について別の質問を立ち上げた方が良いと思います。

Python

1##------------------------------- 2# モデルの設計 3##------------------------------- 4 5# レビュー評価の事後分布の軌跡(trace)を取得する 6# レビューの評価は0.0〜5.0のものを、0~1の範囲の一様分布で扱うため、引数で与えられた値に対して調整を加える 7# name は確率変数名 8def get_posterior_review_rate_trace(review_rate, review_num): 9 with pm.Model() as model: 10 _review_rate = pm.Uniform(name='review_rate', lower=0, upper=1) 11 review_rate_0_to_1 = (review_rate - 1) * 0.25 12 print('0~1の範囲でのレビュー評価 : ', review_rate_0_to_1) 13 14 # 連続確率変数のためBeta分布を使用 15 with pm.Model() as model: 16 theta = pm.Beta(name='theta', alpha=1, beta=1) 17 18 with pm.Model() as model: 19 observations = pm.Binomial( 20 # nはレビュー数、valueはレビュー評価にレビュー数を乗算した値を指定 21 name='obs', n=review_num, p=theta, 22 observed=review_rate_0_to_1 * review_num) 23 map_ = pm.MAP([theta, observations]).fit() 24 25 with pm.Model() as model: 26 model2 = pm.Model([theta, observations]) 27 mcmc = pm.MCMC(model2) 28 29 # MCMCの探索を。第一引数は探索回数。第二引数のバーンインは最初の収束していない一定数は好ましくないので破棄して5000件目~20000件目のサンプリング結果を取得 30 mcmc.sample(20000, 5000) 31 # 探索結果のthetaの確率変数の軌跡を取得 32 trace = mcmc.trace('theta') 33 return trace

投稿2020/02/01 00:27

編集2020/02/01 01:42
meg_

総合スコア10580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

color_8

2020/02/01 00:37

有難うございます。 上記のコード単体では、問題なく動きます。 なので、最後の一行でエラーが起こっているようです。 コードを改めてまとめると以下になります。 もしよろしければ、meg_さんの環境で動いたコードを見せていただくことは可能でしょうか? ##------------------------------- # ライブラリのインポート ##------------------------------- import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns ##------------------------------- # データの取り込み # review_num:映画作品に対するレビュー数 # review_rate:映画作品に対する★1.0〜5.0のレビュー評価値の平均 ##------------------------------- data = pd.read_csv("movie_review4.csv") data = data.astype({'review_rate': float, 'review_num': int}) # x軸にreview_rate、y軸にreview_num data.plot(x='review_rate', y='review_num', kind='hist', bins=20) ##------------------------------- # モデルの設計 ##------------------------------- # レビュー評価の事後分布の軌跡(trace)を取得する # レビューの評価は0.0〜5.0のものを、0~1の範囲の一様分布で扱うため、引数で与えられた値に対して調整を加える # name は確率変数名 def get_posterior_review_rate_trace(review_rate, review_num): with pm.Model() as model: _review_rate = pm.Uniform(name='review_rate', lower=0, upper=1) review_rate_0_to_1 = (review_rate - 1) * 0.25 print('0~1の範囲でのレビュー評価 : ', review_rate_0_to_1) # 連続確率変数のためBeta分布を使用 theta = pm.Beta(name='theta', alpha=1, beta=1) observations = pm.Binomial( # nはレビュー数、valueはレビュー評価にレビュー数を乗算した値を指定 name='obs', n=review_num, p=theta, value=review_rate_0_to_1 * review_num, observed=True) map_ = pm.MAP([theta, observations]).fit() model = pm.Model([theta, observations]) mcmc = pm.MCMC(model) # MCMCの探索を。第一引数は探索回数。第二引数のバーンインは最初の収束していない一定数は好ましくないので破棄して5000件目~20000件目のサンプリング結果を取得 mcmc.sample(20000, 5000) # 探索結果のthetaの確率変数の軌跡を取得 trace = mcmc.trace('theta') return trace ##------------------------------- # モデルの妥当性を確認 ##------------------------------- import pymc3 as pm from pymc3 import plots as mcplot # レビュー評価4.5に対して、取得した軌跡(trace)を引数に渡して事後分布の確認 trace_of_review_num_2 = get_posterior_review_rate_trace( review_rate=4.5, review_num=2)
color_8

2020/02/01 01:00

追記でもらった通り model2 = pm.Model([theta, observations]) mcmc = pm.MCMC(model2) で実行してみても、同じく以下エラーになります。。。 TypeError: __init__() got an unexpected keyword argument 'value'
color_8

2020/02/01 02:01

有難うございます。 改めて別スレッドで進めてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問