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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

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

Q&A

解決済

1回答

7596閲覧

シグモイド曲線へのフィッティングがうまくいきません。

ancho

総合スコア2

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

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

0グッド

0クリップ

投稿2021/10/27 07:01

実験の測定値をシグモイド曲線にフィッティングしたいのですが,下図のように曲線が直角になってしまいます。
イメージ説明

使用しているコードのうち,フィッティングを行っている部分は以下のように書いています。

Python

1import matplotlib.pyplot as plt 2import csv 3import numpy as np 4import pandas as pd 5time = data["day.1"] 6E = data["E.1"] 7 8N = len(E) 9e = max(E)-E 10 11de_e = np.zeros(N-1) 12e_slope = np.zeros(N-1) 13 14## object input 15for n in range(N-1): 16 de_e[n] = e[n+1]-e[n] 17 e_slope[n] = de_e[n]/(time[n+1]-time[n]) 18 19##approximation 20from scipy.optimize import curve_fit 21e_rmax = max(e_slope) 22e_Tinf = time[np.argmax(e_slope)] 23x = time; y = e ;z = max(e)-min(e) 24 25###defining your fitfunction 26def func(x, A, B): 27 return z/(1+ np.exp(-A * (x-B))) 28 29###guess some start values 30initialGuess=[e_rmax,e_Tinf] 31guessedFactors=[func(x,*initialGuess) for x in time] 32###making the actual fit 33popt,pcov = curve_fit(func, time, y, initialGuess) 34#one may want to 35 36E_rmax = popt[0] 37E_Tinf = popt[1] 38E_dC = max(e)-min(e) 39 40#近似曲線 41t_E = np.arange(0, 15, 0.1) 42p_E = max(E)-(max(e)-min(e))/(1+ np.exp(-popt[0]*(t_E - popt[1]))) 43 44ax2.scatter(time,E,color="red",label="⊿E",s=10,zorder=1) 45ax2.plot(t_E,p_E,color="grey",marker="", linewidth = 1.0,zorder=0) 46

元データは以下の通りです。
day.1 E.1
0 1.0 0.000000
1 2.0 7.545589
2 3.0 5.371153
3 3.5 1.667747
4 4.5 6.016085
5 5.0 25.000000
6 5.5 42.660328
7 6.0 51.000000
8 6.5 60.464650
9 7.5 63.169740
10 8.5 62.563373
11 9.5 65.173223
12 10.0 59.794710

また,出力グラフの上部にはこのようなエラーが出ていました。

OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)
RuntimeWarning: overflow encountered in exp
[<matplotlib.lines.Line2D at 0x7f847b6602d0>]

よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず、最適化時に

OptimizeWarning: Covariance of the parameters could not be estimated

のようにエラーができたらおかしい、と感じましょう。
共分散が計算できませんでした = フィッティングがおかしい、です。

原因を探ると、curve_fit(func, time, y, initialGuess)に原因があることが分かりました。
curve_fit(func, x軸, y軸, オプションで初期値)ですが、y軸の値にe = max(E)-Eが適用されていました。初期値はうまくいっていれば特に指定する必要はありません。

ですので、curve_fit(func, day.1の値, E.1の値)とすれば、返ってくる値がfuncの最適値リストと共分散となります。

  • 赤: 生の値
  • 灰:エラーが起きた時の関数(補完)
  • 青:修正関数(補完)

イメージ説明

Python3

1import matplotlib.pyplot as plt 2import csv 3import numpy as np 4import pandas as pd 5############################### 6""" # day1.csv 7day.1,E.1 81,0 92,7.545589 103,5.371153 113.5,1.667747 124.5,6.016085 135,25 145.5,42.660328 156,51 166.5,60.46465 177.5,63.16974 188.5,62.563373 199.5,65.173223 2010,59.79471 21 22""" 23data = pd.read_csv("day1.csv") 24############################### 25 26time = data["day.1"] 27E = data["E.1"] 28 29N = len(E) 30e = max(E)-E 31 32de_e = np.zeros(N-1) 33e_slope = np.zeros(N-1) 34 35## object input 36for n in range(N-1): 37 de_e[n] = e[n+1]-e[n] 38 e_slope[n] = de_e[n]/(time[n+1]-time[n]) 39 40##approximation 41from scipy.optimize import curve_fit 42e_rmax = max(e_slope) 43e_Tinf = time[np.argmax(e_slope)] 44x = time; y = e ;z = max(e)-min(e) 45 46###defining your fitfunction 47def func(x, A, B): 48 return z/(1+ np.exp(-A * (x-B))) 49 50###guess some start values 51initialGuess=[e_rmax,e_Tinf] 52guessedFactors=[func(x,*initialGuess) for x in time] 53###making the actual fit 54popt,pcov = curve_fit(func, time, y, initialGuess) 55 56 57 58 59############################### 60# OptimizeWarning: Covariance of the parameters could not be estimated 61# --> FAILED! 62 63 64# X 表示用 65x_filled = np.linspace(np.min(time),np.max(time),len(time)*5) 66 67# Y 表示用(元) 68y_estimated = [func(x,popt[0], popt[1]) for x in x_filled] 69 70 71# 曲線のフィッティング(NEW) 72popt2,pcov2 = curve_fit(func, time, E) 73 74 75# Y 表示用(NEW) 76y_new = [func(x,popt2[0], popt2[1]) for x in x_filled] 77 78 79fig = plt.figure() 80plt.scatter(time, E, color="red", label="RAW") 81plt.scatter(x_filled, y_estimated, color="gray", label="ESTIMATED") 82 83plt.scatter(x_filled, y_new, color="blue", label="NEW") 84plt.legend() 85plt.show() 86############################### 87 88###one may want to 89## 90##E_rmax = popt[0] 91##E_Tinf = popt[1] 92##E_dC = max(e)-min(e) 93## 94###近似曲線 95##t_E = np.arange(0, 15, 0.1) 96## 97##p_E = max(E)-(max(e)-min(e))/(1+ np.exp(-popt[0]*(t_E - popt[1]))) 98## 99## 100############################### 101##ax2 = fig.add_subplot(111) 102############################### 103##ax2.scatter(time,E,color="red",label="⊿E",s=10,zorder=1) 104##ax2.plot(t_E,p_E,color="grey",marker="", linewidth = 1.0,zorder=0) 105

※追加した部分は###############################で示しました。

投稿2021/10/29 22:23

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ancho

2021/10/30 09:31

ありがとうございます! ずっとエラーの原因がわからず先に進めなかったんですが,教えていただいたようにしたら正しく動きました。本当に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問