線形回帰モデル(燃費) scikit-learn

線形回帰モデル(燃費)

scikit-learnを使用して、線形回帰モデルを作成してみましょう。

以下は、燃費データを使って車の燃費を予測する例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import pandas as pd
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# データの読み込み
url = "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data"
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight', 'Acceleration', 'Model Year', 'Origin']
data = pd.read_csv(url, sep='\s+', names=column_names, na_values='?')

# 欠損値を削除
data = data.dropna()

# 特徴量とターゲットの選択
X = data[['Cylinders', 'Displacement', 'Horsepower', 'Weight', 'Acceleration']]
y = data['MPG']

# モデルの訓練
model = LinearRegression()
model.fit(X, y)

# 予測と実際の値の比較
predictions = model.predict(X)

# グラフ化
plt.figure(figsize=(10, 6))
plt.scatter(y, predictions)
plt.xlabel('実際のMPG')
plt.ylabel('予測されたMPG')
plt.title('実際のMPGと予測されたMPGの比較')
plt.grid(True)
plt.show()

このコードでは、UCI Machine Learning Repositoryから車の燃費データを読み込み、線形回帰モデルを用いて車の燃費(MPG)を予測します。

そして、実際のMPGと予測されたMPGの比較を散布図として表示しています。

ソースコード解説

このコードは、以下の手順で車の燃費(MPG)データを分析し、線形回帰モデルを作成しています。

データの読み込みと前処理

  • UCI Machine Learning Repositoryから車の燃費データをダウンロードし、Pandasを使って読み込みます。
  • データにはカラム名がないので、カラム名を定義しています。
  • 欠損値が含まれる可能性があるため、欠損値を含む行を削除します。

特徴量とターゲットの選択

  • 説明変数(特徴量)と目的変数(ターゲット)を選択します。
    ここでは、車の性能に関連する特徴量(気筒数、排気量、馬力、重量、加速度)を特徴量として選択し、燃費(MPG)を目的変数として選択しています。

モデルの訓練

  • scikit-learnのLinearRegression()を使用して線形回帰モデルを作成し、特徴量と目的変数を使ってモデルを訓練します。

予測と実際の値の比較

  • 訓練済みモデルを使って、特徴量から燃費(MPG)を予測します。
  • 実際の燃費と予測された燃費の関係を比較するため、散布図を作成しています。

グラフ化

  • 予測されたMPGと実際のMPGを散布図で表示しており、x軸が実際のMPG、y軸が予測されたMPGを示しています。
  • グラフのタイトルや軸ラベルが追加されており、グリッドが表示されています。

結果解説

このグラフは、実際の燃費(実際のMPG)と機械学習モデルによって予測された燃費(予測されたMPG)の関係を示しています。

各点は、個々の車両に対しての実際の燃費とモデルによる予測のペアを表しています。

x軸は実際のMPGを示し、y軸はそれに対する機械学習モデルによる予測されたMPGを表しています。

各点が45度の直線に近い位置に集中している場合、予測が実際の値とほぼ同じであることを意味します。

グラフ全体が45度の直線に近い形をしている場合、モデルが実際の値と良好に一致して予測していることを示し、点が直線から離れてばらつきが大きい場合、予測が実際の値との間で大きくズレていることを示します。

高度な数式 SciPy

高度な数式

Scipyを使用して、高度な数式を解くためのサンプルコードを提供します。

以下は、$ y = x^3 + 2x^2 - 5x + 6 $の関数を考え、その解を見つける例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
from scipy.optimize import root
import matplotlib.pyplot as plt

# 解きたい方程式の関数
def equation(x):
return x**3 + 2*x**2 - 5*x + 6

# 初期値を設定
initial_guess = 0

# 方程式の解を求める
solution = root(equation, initial_guess)

# 解を表示
print("解:", solution.x)

# グラフ化
x_vals = np.linspace(-5, 3, 1000)
y_vals = equation(x_vals)

plt.figure(figsize=(8, 6))
plt.plot(x_vals, y_vals, label='y = x^3 + 2x^2 - 5x + 6')
plt.scatter(solution.x, equation(solution.x), color='red', label='Solution', s=100)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Graph of the Equation')
plt.legend()
plt.grid(True)
plt.show()

このコードは、scipy.optimize.rootを使用して方程式の解を見つけます。

また、解を求める過程をグラフに表しています。

方程式の解は赤い点で示されています。

ソースコード解説

このコードは、Scipyライブラリを使用して非線形方程式を解く手順を示しています。

詳細を以下にまとめます。

ライブラリのインポート

1
2
3
import numpy as np
from scipy.optimize import root
import matplotlib.pyplot as plt

方程式の定義

1
2
def equation(x):
return x**3 + 2*x**2 - 5*x + 6

この関数では、$ y = x^3 + 2x^2 - 5x + 6 $という非線形方程式が定義されています。

初期値の設定

1
initial_guess = 0

初期推定値を$ (x=0) $に設定しています。

方程式の解を求める

1
solution = root(equation, initial_guess)

scipy.optimize.rootを使用して、指定した方程式の解を計算します。
この場合、equation関数を与えています。

解の表示

1
print("解:", solution.x)

解をコンソールに表示します。

グラフ化

1
2
3
4
5
6
7
8
9
10
11
12
x_vals = np.linspace(-5, 3, 1000)
y_vals = equation(x_vals)

plt.figure(figsize=(8, 6))
plt.plot(x_vals, y_vals, label='y = x^3 + 2x^2 - 5x + 6')
plt.scatter(solution.x, equation(solution.x), color='red', label='Solution', s=100)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Graph of the Equation')
plt.legend()
plt.grid(True)
plt.show()

指定した範囲の$ (x) 値$に対する方程式の$ (y) 値$を計算し、グラフ上に方程式の曲線を描画します。

また、方程式の解を赤い点で示しています。

このコード全体は、非線形方程式の数値解法とその結果の視覚化を行っています。

統計 SciPy

統計

統計に関する問題をSciPyを使用して解いて、その結果をグラフ化します。

以下は、あるデータセットを使って簡単な統計的な問題を解決し、その結果をグラフ化する例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt

# サンプルデータ生成
np.random.seed(0)
data = np.random.normal(loc=5, scale=2, size=1000) # 平均=5, 標準偏差=2の正規分布からのサンプルデータ

# データの基本的な統計量計算
mean = np.mean(data)
std_dev = np.std(data)
median = np.median(data)

# 正規分布の確率密度関数の作成
x = np.linspace(np.min(data), np.max(data), 100)
pdf = norm.pdf(x, mean, std_dev)

# グラフ化
plt.figure(figsize=(10, 6))

# ヒストグラム
plt.hist(data, bins=30, density=True, alpha=0.5, label='Histogram')

# 正規分布の確率密度関数
plt.plot(x, pdf, 'r', label='Normal Distribution')

# 平均と中央値の縦線
plt.axvline(mean, color='green', linestyle='dashed', linewidth=2, label='Mean')
plt.axvline(median, color='orange', linestyle='dashed', linewidth=2, label='Median')

plt.title('Histogram and Normal Distribution of Data')
plt.xlabel('Values')
plt.ylabel('Density')
plt.legend()
plt.grid(True)
plt.show()

# 統計量の表示
print(f"平均: {mean}")
print(f"標準偏差: {std_dev}")
print(f"中央値: {median}")

このコードは、平均・標準偏差・中央値の計算、データのヒストグラムと正規分布の確率密度関数のグラフ表示を行います。

また、平均と中央値を縦線で示しています。

これにより、データの分布や統計的な特性を視覚化し、計算結果を表示します。

ソースコード解説

以下にソースコードの詳細を説明します。

ライブラリのインポートとサンプルデータの生成

1
2
3
4
5
6
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt

np.random.seed(0)
data = np.random.normal(loc=5, scale=2, size=1000)
  • numpyは数値計算を行うためのライブラリです。
    scipy.statsからnormは正規分布を扱うための統計関数を提供します。
    matplotlib.pyplotはグラフ描画ライブラリです。
  • np.random.normal()は平均が5で標準偏差が2の正規分布から1000個のサンプルデータを生成します。

基本的な統計量の計算

1
2
3
mean = np.mean(data)
std_dev = np.std(data)
median = np.median(data)
  • np.mean()、np.std()、np.median()はそれぞれデータの平均、標準偏差、中央値を計算します。

正規分布の確率密度関数の作成

1
2
x = np.linspace(np.min(data), np.max(data), 100)
pdf = norm.pdf(x, mean, std_dev)
  • np.linspace()はdataの最小値から最大値までの範囲を100個の等間隔な数値に分割します。
    これにより、x軸の値を作成します。
  • norm.pdf()は平均と標準偏差を指定して、正規分布の確率密度関数を計算します。

グラフ化

1
2
3
4
5
6
7
8
9
10
11
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, density=True, alpha=0.5, label='Histogram')
plt.plot(x, pdf, 'r', label='Normal Distribution')
plt.axvline(mean, color='green', linestyle='dashed', linewidth=2, label='Mean')
plt.axvline(median, color='orange', linestyle='dashed', linewidth=2, label='Median')
plt.title('Histogram and Normal Distribution of Data')
plt.xlabel('Values')
plt.ylabel('Density')
plt.legend()
plt.grid(True)
plt.show()
  • plt.figure(figsize=(10, 6))は図のサイズを設定します。
  • plt.hist()はヒストグラムを描画します。
  • plt.plot()は正規分布の確率密度関数を描画します。
  • plt.axvline()は平均と中央値を縦線で表示します。それぞれ緑とオレンジの破線で示されています。
  • plt.title()、plt.xlabel()、plt.ylabel()はそれぞれグラフのタイトルと軸ラベルを設定します。
  • plt.legend()は凡例を表示し、plt.grid(True)はグリッドを表示します。
  • plt.show()はグラフを表示します。

統計量の表示

1
2
3
print(f"平均: {mean}")
print(f"標準偏差: {std_dev}")
print(f"中央値: {median}")
  • 最後に、計算された平均、標準偏差、中央値を表示します。

ポートフォリオ最適化(凸最適化) CVXPY

ポートフォリオ最適化(凸最適化)

CVXPYは凸最適化のためのライブラリです。

以下では、例としてポートフォリオ最適化問題を解いてみましょう。

ポートフォリオ最適化は投資資産の配分を決定する問題で、リスクを最小化しつつ期待収益を最大化する配分を見つけます。

まず、例として適当なデータを生成し、それを用いてポートフォリオ最適化を行います。

その後、結果をグラフ化します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import cvxpy as cp
import numpy as np
import matplotlib.pyplot as plt

# データ生成
np.random.seed(42)
n = 5 # 資産の数
mean_returns = np.random.randn(n) / 100 # 平均収益率
cov_matrix = np.random.randn(n, n)
cov_matrix = np.dot(cov_matrix.T, cov_matrix) / 100 # 共分散行列

# ポートフォリオ最適化問題の定義
weights = cp.Variable(n)
expected_return = mean_returns.T @ weights
risk = cp.quad_form(weights, cov_matrix)
constraints = [
cp.sum(weights) == 1, # 資産の割合の合計は1
weights >= 0 # 資産の割合は0以上
]
problem = cp.Problem(cp.Maximize(expected_return - 0.5 * risk), constraints) # 目的関数

# 最適化
result = problem.solve()

# 結果を表示
print("最適化されたポートフォリオの割合:")
print(weights.value)
print("期待収益率:", expected_return.value)
print("リスク:", np.sqrt(risk.value))

# グラフ化
plt.figure(figsize=(8, 6))
plt.bar(range(n), weights.value, tick_label=[f"Asset {i+1}" for i in range(n)])
plt.xlabel('Assets')
plt.ylabel('Portfolio Weights')
plt.title('Optimized Portfolio Allocation')
plt.show()

このコードは、CVXPYを使ってランダムな収益率と共分散行列を生成し、ポートフォリオの最適な資産割合を求めます。

そして、最適化されたポートフォリオの割合を棒グラフで表示します。

[実行結果]

ソースコード解説

以下にソースコードの詳細を示します。

1. ライブラリのインポート

1
2
3
import cvxpy as cp
import numpy as np
import matplotlib.pyplot as plt
  • cvxpyは凸最適化問題を解くためのライブラリです。
  • numpyは数値計算を行うためのライブラリです。
  • matplotlib.pyplotはグラフを描画するためのライブラリです。

2. データの生成

1
2
3
4
5
np.random.seed(42)
n = 5 # 資産の数
mean_returns = np.random.randn(n) / 100 # 平均収益率
cov_matrix = np.random.randn(n, n)
cov_matrix = np.dot(cov_matrix.T, cov_matrix) / 100 # 共分散行列
  • mean_returnsは資産の平均収益率をランダムに生成しています。
  • cov_matrixは共分散行列を生成しています。
    この行列は資産間の関係性(共分散)を表します。

3. ポートフォリオ最適化問題の定義

1
2
3
4
5
6
7
8
weights = cp.Variable(n)
expected_return = mean_returns.T @ weights
risk = cp.quad_form(weights, cov_matrix)
constraints = [
cp.sum(weights) == 1, # 資産の割合の合計は1
weights >= 0 # 資産の割合は0以上
]
problem = cp.Problem(cp.Maximize(expected_return - 0.5 * risk), constraints) # 目的関数
  • weightsは資産の割合を表す変数です。
  • expected_returnはポートフォリオの期待収益率を表します。
  • riskはポートフォリオのリスクを表します。
  • constraintsでは資産の割合が0以上で合計が1であることを制約として設定しています。
  • problemは最大化する目的関数を定義しています。

4. 最適化

1
result = problem.solve()
  • problem.solve()でポートフォリオ最適化問題を解きます。

5. 結果の表示

1
2
3
4
print("最適化されたポートフォリオの割合:")
print(weights.value)
print("期待収益率:", expected_return.value)
print("リスク:", np.sqrt(risk.value))
  • 最適化されたポートフォリオの割合、期待収益率、リスクを表示しています。

6. グラフ化

1
2
3
4
5
6
plt.figure(figsize=(8, 6))
plt.bar(range(n), weights.value, tick_label=[f"Asset {i+1}" for i in range(n)])
plt.xlabel('Assets')
plt.ylabel('Portfolio Weights')
plt.title('Optimized Portfolio Allocation')
plt.show()
  • 最適化されたポートフォリオの割合を棒グラフで表示しています。
    各資産の割合を視覚的に確認できます。

結果解説

[実行結果]

この結果は、ポートフォリオの最適化後の割合、期待収益率、そしてリスクを示しています。

最適化されたポートフォリオの割合:

各資産の最適な配分を示しています。
例えば、1番目の資産の割合は約12.20%、3番目の資産の割合は約60.58%、4番目の資産の割合は約27.22%となっています。
2番目と最後の資産はほとんど割り当てられていません。

期待収益率:

最適化されたポートフォリオの期待収益率は約0.0087です。
これは、ポートフォリオが1単位投資した場合の平均的なリターンを示しています。

リスク:

ポートフォリオのリスクは、標準偏差またはボラティリティを示しており、約0.0575です。
この値はポートフォリオの変動性を表しています。

極座標 matplotlib

極座標

極座標は、平面上の一点を中心に、その点からの距離と角度で位置を表現する座標系のことを指します。

例えば、ある場所から見た時に、その場所がどれだけ離れていて、どの方向にあるかを考えてみましょう。
その場所の「距離」は、ある場所からその場所までの「直線」の長さを指し、「角度」はその場所がどの方向にあるかを表します。

この「距離」と「角度」を使って、ある場所の位置を表現するのが極座標です。
例えば、ある場所があなたの自宅から10メートル離れており、その場所があなたの自宅の右側にあるとします。
この場合、その場所の極座標は「(10メートル, 右)」と表現できます。

このように、極座標は「距離」と「角度」を使って、場所の位置を表現する座標系です。
これは、地図やコンパスなど、位置を表現するための座標系としてよく使われます。

サンプルコード

Pythonとmatplotlibを使用して複雑なグラフを作成する例として、4つの象限を持つ極座標のグラフを考えてみましょう。

この例では、Pythonのnumpyライブラリを使用してランダムなデータを生成し、そのデータを使用してグラフを描きます。

まず、必要なライブラリをインポートします。

1
2
import numpy as np
import matplotlib.pyplot as plt

次に、ランダムなデータを生成します。

1
2
theta = np.linspace(0, 2*np.pi, 100)
r = np.random.uniform(0, 1, 100)

次に、4つの象限を持つ極座標のグラフを作成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fig, axes = plt.subplots(2, 2, subplot_kw=dict(polar=True), figsize=(16, 8))

# 第1象限
axes[0, 0].plot(theta, r)

# 第2象限
axes[0, 1].plot(theta, r)
axes[0, 1].set_theta_offset(np.pi)

# 第3象限
axes[1, 0].plot(theta, r)
axes[1, 0].set_theta_direction(-1)

# 第4象限
axes[1, 1].plot(theta, r)
axes[1, 1].set_theta_offset(np.pi)
axes[1, 1].set_theta_direction(-1)

plt.show()

このコードは、4つの象限を持つ極座標のグラフを描きます。

subplot_kw=dict(polar=True)を指定することで、各サブプロットが極座標を持つグラフになります。

set_theta_offsetメソッドとset_theta_directionメソッドを使用して、各象限の位置と方向を設定します。

なお、このコードは適当なデータを使用していますので、実際のデータを使用する場合には、そのデータを適切に準備する必要があります。

ソースコード解説

コードの概要

このコードは、numpyとmatplotlibを使用して、4つの極座標グラフを作成しています。
それぞれのグラフは極座標上の異なる象限を示しており、乱数を使って円周上に点を配置しています。

ライブラリのインポート

1
2
import numpy as np
import matplotlib.pyplot as plt
  • numpyは数値計算を行うためのライブラリです。
  • matplotlib.pyplotはグラフを描画するためのライブラリです。

データの準備

1
2
theta = np.linspace(0, 2*np.pi, 100)
r = np.random.uniform(0, 1, 100)
  • thetaは0から2πまでの値を等間隔で100点取得しています。
  • rは0から1までの乱数を100点取得しています。

グラフの作成

1
fig, axes = plt.subplots(2, 2, subplot_kw=dict(polar=True), figsize=(16, 8))
  • plt.subplots()で2x2の4つの極座標グラフを作成し、figに図全体、axesにそれぞれのサブプロットが割り当てられます。

第1象限のグラフ

1
axes[0, 0].plot(theta, r)
  • axes[0, 0]はsubplotの位置を指定しています。
    第1象限のグラフを作成しています。

第2象限のグラフ

1
2
axes[0, 1].plot(theta, r)
axes[0, 1].set_theta_offset(np.pi)
  • axes[0, 1]は第2象限の位置を指定しています。
    set_theta_offset(np.pi)でグラフの方向を反転しています。

第3象限のグラフ

1
2
axes[1, 0].plot(theta, r)
axes[1, 0].set_theta_direction(-1)
  • axes[1, 0]は第3象限の位置を指定しています。
    set_theta_direction(-1)でグラフの方向を反転しています。

第4象限のグラフ

1
2
3
axes[1, 1].plot(theta, r)
axes[1, 1].set_theta_offset(np.pi)
axes[1, 1].set_theta_direction(-1)
  • axes[1, 1]は第4象限の位置を指定しています。
    set_theta_offset(np.pi)とset_theta_direction(-1)でグラフの方向を反転しています。

グラフの表示

1
plt.show()
  • 作成したグラフを表示しています。
    それぞれのサブプロットが極座標上の異なる象限を示しています。

3Dプロット Plotly

3Dプロット

Plotlyライブラリを使って、複数の3Dプロットを組み合わせて表現してみます。

以下に、複数の3Dサブプロットを表示する例を示します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import plotly.graph_objs as go
import plotly.subplots as subplots
import numpy as np

# サンプルデータの生成
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
x, y = np.meshgrid(x, y)
z1 = np.sin(np.sqrt(x**2 + y**2))
z2 = np.cos(np.sqrt(x**2 + y**2))
z3 = x**2 - y**2

# 3Dサブプロットの作成
fig = subplots.make_subplots(rows=1, cols=3,
subplot_titles=('sin(sqrt(x^2 + y^2))', 'cos(sqrt(x^2 + y^2))', 'x^2 - y^2'),
specs=[[{'type': 'surface'}, {'type': 'surface'}, {'type': 'surface'}]])

# 3つの3Dサブプロットを追加
fig.add_trace(go.Surface(x=x, y=y, z=z1, colorscale='Viridis'), row=1, col=1)
fig.add_trace(go.Surface(x=x, y=y, z=z2, colorscale='Rainbow'), row=1, col=2)
fig.add_trace(go.Surface(x=x, y=y, z=z3, colorscale='Jet'), row=1, col=3)

# レイアウトの設定
fig.update_layout(title_text='複数の3Dサブプロット', height=600, width=1000)
fig.show()

このコードは、3つの異なる3Dプロットを1つのグラフに表示しています。

それぞれのプロットは異なる関数を表しており、それを3Dサブプロットとして横に並べて表示しています。

サンプルデータとして、2つの円周の$sin$、$cos$関数、そして$ x^2 - y^2 $の関数を生成し、それぞれの3Dサブプロットを作成しています。

これにより、複数の3Dグラフを組み合わせて表示する方法がわかります。

ソースコード解説

ソースコードの各部分を順に説明します。

ライブラリのインポート

1
2
3
import plotly.graph_objs as go
import plotly.subplots as subplots
import numpy as np
  • plotly.graph_objs はPlotlyのグラフオブジェクトを作成するためのモジュールです。
  • plotly.subplots はPlotlyのサブプロットを作成するためのモジュールです。
  • numpy は数値計算を行うためのライブラリです。

サンプルデータの生成

1
2
3
4
5
6
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
x, y = np.meshgrid(x, y)
z1 = np.sin(np.sqrt(x**2 + y**2))
z2 = np.cos(np.sqrt(x**2 + y**2))
z3 = x**2 - y**2
  • np.linspace() は一様に区間を分割する関数で、-5から5までの区間を100分割してxとyの値を生成しています。
  • np.meshgrid() はx、yの値から格子状の座標を作成しています。
  • np.sin()、np.cos()、**(べき乗演算子)を使用してz1、z2、z3の値を計算しています。

3Dサブプロットの作成

1
2
3
fig = subplots.make_subplots(rows=1, cols=3,
subplot_titles=('sin(sqrt(x^2 + y^2))', 'cos(sqrt(x^2 + y^2))', 'x^2 - y^2'),
specs=[[{'type': 'surface'}, {'type': 'surface'}, {'type': 'surface'}]])
  • subplots.make_subplots() は、指定された行数と列数のサブプロットを作成する関数です。
    ここでは1行3列のサブプロットを作成しています。
  • subplot_titles は、各サブプロットのタイトルを指定しています。
  • specs は各サブプロットのタイプを指定しています。

3つの3Dサブプロットを追加

1
2
3
fig.add_trace(go.Surface(x=x, y=y, z=z1, colorscale='Viridis'), row=1, col=1)
fig.add_trace(go.Surface(x=x, y=y, z=z2, colorscale='Rainbow'), row=1, col=2)
fig.add_trace(go.Surface(x=x, y=y, z=z3, colorscale='Jet'), row=1, col=3)
  • fig.add_trace() を使用して、各3Dサブプロットを作成しています。
  • go.Surface() は3Dサーフェスプロットを作成するPlotlyの関数です。
  • colorscale はカラーマップの設定を行っています。

レイアウトの設定と表示

1
2
fig.update_layout(title_text='複数の3Dサブプロット', height=600, width=1000)
fig.show()
  • fig.update_layout() でグラフ全体のレイアウトを設定しています。
    ここではグラフのタイトルとサイズを指定しています。
  • fig.show() で作成したグラフを表示しています。

このコードは、3つの異なる関数を表す3Dサブプロットを作成し、それらを1つのグラフにまとめて表示するものです。

それぞれのサブプロットは、異なる特徴を持つ関数を3Dプロットとして表現しています。

非線形の最適化問題 SciPy

非線形の最適化問題

非線形の最適化問題を解くためには、SciPyライブラリのminimize()関数を使用します。

ここでは、簡単な非線形の最適化問題を解いてみます。

例として、次の非線形関数を最小化する問題を考えます。

$$
f(x) = x^2 + 5 \sin(x)
$$

この関数を最小化する$ (x) $の値を見つけることを目指します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt

# 最小化する非線形関数
def objective_function(x):
return x**2 + 5 * np.sin(x)

# 初期値
x0 = 0

# 最適化の実行
result = minimize(objective_function, x0, method='BFGS')

# 結果の表示
print("Optimal solution:", result.x)

# グラフ化
x_vals = np.linspace(-10, 10, 100)
y_vals = objective_function(x_vals)

plt.plot(x_vals, y_vals, label='Objective Function')
plt.scatter(result.x, objective_function(result.x), color='red', label='Optimal Solution')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Nonlinear Optimization')
plt.legend()
plt.grid(True)
plt.show()

このコードは、minimize()関数を使用して非線形関数を最小化しています。

関数の最小値を求めるためにBFGS(Broyden-Fletcher-Goldfarb-Shanno)最適化手法を使用しています。

最適解は result.x に格納されます。

また、matplotlibライブラリを使用して、非線形関数をグラフ化しています。

最小値の位置を赤色の点で表示しています。

ソースコード解説

このコードは、PythonのSciPyライブラリを使用して非線形最適化問題を解くものです。

  1. numpyおよびscipy.optimizeから必要なライブラリをインポートしています。
    また、グラフを描画するためにmatplotlib.pyplotもインポートしています。

  2. objective_function(x)という関数を定義しています。
    これは最小化する非線形関数です。
    ここでは$ ( f(x) = x^2 + 5 \sin(x) ) $となっています。

  3. 初期値 x0 を 0 としています。
    最適化アルゴリズムはこの初期値から始まり、関数の最小値を見つけようとします。

  4. minimize()関数を使用して、objective_functionを最小化します。
    ここでは** BFGS(Broyden-Fletcher-Goldfarb-Shanno)法 **を使用しています。

  5. result.xには、最適化アルゴリズムによって見つけられた最適解が格納されます。

  6. グラフ化のために、np.linspace()を使用して$ ( x ) $の値を範囲$ [-10, 10] $で生成し、それに対応する$ ( f(x) ) $の値を計算しています。

  7. plt.plot()を使って非線形関数を青色の折れ線グラフでプロットし、plt.scatter()を使って最適解の位置を赤い点で表示しています。

  8. 最後に、グラフの軸ラベル、タイトル、凡例、グリッドを設定し、plt.show()でグラフを表示しています。

このコードは、非線形最適化問題を解く手法とその結果を可視化する方法を示しています。

関数の最小値を見つけ、最適解の位置を視覚的に示すためにグラフを使用しています。

結果解説

この非線形関数$ ( f(x) = x^2 + 5 \sin(x) ) $を最小化するために、Scipyのminimize()関数を使用しました。

最適化手法としてはBFGS法を選択しました。

結果として得られた最適解は$ ( x \approx -1.11051052 ) $です。

この$ ( x ) $の値が関数$ ( f(x) ) $を最小化する点です。

グラフでは、横軸が$ ( x )$、縦軸が$ ( f(x) ) $となっており、非線形関数が青線で表示されています。

赤い点が求められた最適解の位置を示しています。

この点は、関数が最小値を取る位置を表しています。

関数$ ( f(x) ) は ( x \approx -1.11051052 ) $の位置で最小値を持ちます。

この値は、関数が最小となる$ ( x ) $の位置を示しており、BFGS最適化アルゴリズムがこの値を見つけることができたことを示しています。

資源割り当て問題 (Resource Allocation Problem) PuLP

資源割り当て問題 (Resource Allocation Problem)

最適化問題として、**資源割り当て問題 (Resource Allocation Problem)**を考えてみましょう。

この問題では、限られた資源を異なるタスクに効果的に割り当て、特定の目的関数を最大化または最小化することが求められます。

例えば、以下のような状況を考えます:

問題:資源割り当て問題

資源:

ある会社のプロジェクトマネージャが5人の従業員と10,000ドルの予算を持っています。

タスク:

プロジェクトには3つの重要なタスクがあります。
それぞれのタスクには異なる従業員のスキルが必要で、予算も異なります。

目標:

全体のプロジェクト効率を最大化するために、どの従業員にどのタスクを割り当て、予算をどのように使うべきかを決定します。

この問題を数理最適化問題としてモデル化し、例えば全体のプロジェクト効率を最大化するような目的関数を設定し、従業員と予算の制約条件を考慮して解を求めることができます。

このような問題は実際のビジネスやプロジェクト管理でよく発生し、最適な資源割り当てによって企業の生産性や利益を向上させることが期待されます。

サンプルソース

資源割り当て問題を解くために、PuLPと呼ばれる線形プログラミングライブラリを使用します。

以下は、Pythonコードの一例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from pulp import LpProblem, LpVariable, lpSum, LpMaximize

def solve_resource_allocation_problem():
# 問題の設定
problem = LpProblem("Resource_Allocation", LpMaximize)

# 従業員とタスクの数
num_employees = 5
num_tasks = 3

# 従業員のスキル
skills = [
[3, 1, 4], # 従業員1のスキル
[2, 0, 5], # 従業員2のスキル
[1, 4, 2], # 従業員3のスキル
[4, 3, 1], # 従業員4のスキル
[0, 2, 3] # 従業員5のスキル
]

# タスクごとの予算
budgets = [3000, 5000, 2000]

# 従業員ごとの変数(0または1のバイナリ変数)
employees = [LpVariable(f"Employee_{i}", cat='Binary') for i in range(num_employees)]

# 目的関数(最大化する対象:全体のプロジェクト効率)
problem += lpSum([employees[i] * skills[i][j] for i in range(num_employees) for j in range(num_tasks)]), "Total_Efficiency"

# 制約条件
for j in range(num_tasks):
problem += lpSum([employees[i] * skills[i][j] for i in range(num_employees)]) >= 1, f"Task_{j + 1}_Requirement"

problem += lpSum([employees[i] for i in range(num_employees)]) == 3, "Total_Employees"

# 最適化の実行
problem.solve()

# 結果の表示
print("Status:", LpProblem.status[problem.status])
print("Optimal Resource Allocation:")
for i, employee in enumerate(employees):
if employee.varValue == 1:
print(f"Employee {i + 1} is assigned to the project.")
print(f"Total Project Efficiency: {problem.objective.value()}")

# 最適化の実行
solve_resource_allocation_problem()

このコードでは、各従業員がプロジェクトにアサインされるかどうかを表すバイナリ変数を導入し、目的関数と制約条件を設定しています。

これにより、全体のプロジェクト効率を最大化するための最適な資源割り当てが求まります。

具体的な制約条件やデータは問題により異なるため、適宜調整してください。

ソースコード解説

以下に、ソースコード各部分の詳細を説明します。

1
from pulp import LpProblem, LpVariable, lpSum, LpMaximize

PuLPライブラリから必要なモジュールをインポートしています。

PuLPは線形および整数計画問題を解くための強力なツールです。

1
2
3
def solve_resource_allocation_problem():
# 問題の設定
problem = LpProblem("Resource_Allocation", LpMaximize)

LpProblemクラスのインスタンスを作成しています。

これは線形計画問題を表します。

最大化問題か最小化問題かを指定しています。

1
2
3
# 従業員とタスクの数
num_employees = 5
num_tasks = 3

問題のサイズを設定しています。

この場合、5人の従業員と3つのタスクがあります。

1
2
3
4
5
6
7
8
# 従業員のスキル
skills = [
[3, 1, 4], # 従業員1のスキル
[2, 0, 5], # 従業員2のスキル
[1, 4, 2], # 従業員3のスキル
[4, 3, 1], # 従業員4のスキル
[0, 2, 3] # 従業員5のスキル
]

各従業員の各タスクにおけるスキルを表す2次元リストを作成しています。

1
2
# タスクごとの予算
budgets = [3000, 5000, 2000]

各タスクに対する予算を示すリストを作成しています。

1
2
# 従業員ごとの変数(0または1のバイナリ変数)
employees = [LpVariable(f"Employee_{i}", cat='Binary') for i in range(num_employees)]

各従業員がプロジェクトにアサインされるかどうかを表すバイナリ変数を作成しています。

1
2
# 目的関数(最大化する対象:全体のプロジェクト効率)
problem += lpSum([employees[i] * skills[i][j] for i in range(num_employees) for j in range(num_tasks)]), "Total_Efficiency"

目的関数を設定しています。

この場合、各従業員が各タスクに対して持つスキルとアサインのバイナリ変数を考慮して、総合プロジェクト効率を最大化するようにしています。

1
2
3
# 制約条件
for j in range(num_tasks):
problem += lpSum([employees[i] * skills[i][j] for i in range(num_employees)]) >= 1, f"Task_{j + 1}_Requirement"

各タスクに対する制約条件を設定しています。

各タスクには少なくとも1人の従業員がアサインされる必要があります。

1
problem += lpSum([employees[i] for i in range(num_employees)]) == 3, "Total_Employees"

従業員の総数に関する制約条件を設定しています。

この場合、総従業員数は3人となります。

1
2
# 最適化の実行
problem.solve()

PuLPを使用して最適化を実行しています。

1
2
3
4
5
6
7
8
9
10
    # 結果の表示
print("Status:", LpProblem.status[problem.status])
print("Optimal Resource Allocation:")
for i, employee in enumerate(employees):
if employee.varValue == 1:
print(f"Employee {i + 1} is assigned to the project.")
print(f"Total Project Efficiency: {problem.objective.value()}")

# 最適化の実行
solve_resource_allocation_problem()

最適化の結果や最適解を表示しています。

それぞれの従業員がプロジェクトにアサインされ、総合プロジェクト効率が表示されます。

結果解説

[実行結果]

Optimal Resource Allocation:
Employee 1 is assigned to the project.
Employee 3 is assigned to the project.
Employee 4 is assigned to the project.
Total Project Efficiency: 23.0

この実行結果は、与えられた資源割り当て問題に対してPuLPを使用して最適解を求めた結果です。

Optimal Resource Allocation (最適な資源割り当て):

  • Employee 1, Employee 3, Employee 4がプロジェクトにアサインされました。
    これは、それぞれの従業員がプロジェクトに対してスキルを持っており、かつ制約条件を満たす最適な割り当てが行われたことを示しています。

Total Project Efficiency (総合プロジェクト効率):

  • 最適な資源割り当てによって得られるプロジェクト全体の効率は、合計で23.0です。
    この値は、目的関数である「Total_Efficiency」を最大化することによって求められたもので、各従業員のスキルとプロジェクトへの割り当てに基づいています。

この結果から、プロジェクト全体の効率を最大化するためには、Employee 1、Employee 3、Employee 4の3人がプロジェクトにアサインされ、これによって23.0の総合プロジェクト効率が達成されることが分かります。

車両ルーティング問題(Vehicle Routing Problem, VRP) Google OR-Tools

車両ルーティング問題(Vehicle Routing Problem, VRP)

Google OR-Toolsは、数理最適化や制約充足問題を解くためのツールキットであり、Pythonで使用できます。

ここでは、具体的な実用的な問題として、車両ルーティング問題(Vehicle Routing Problem, VRP)を取り上げ、Google OR-Toolsを使用して解決し、結果をグラフで可視化してみます。

VRPは、与えられた車両数で、複数の顧客を巡回する最適な経路を見つける問題です。

以下に、Google OR-Toolsを使用してVRPを解くPythonコードの例を示します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import matplotlib.pyplot as plt
import networkx as nx

# 顧客の座標と需要を定義
locations = [(35, 10), (15, 15), (25, 25), (30, 40), (45, 35), (10, 20), (50, 25)]

# デポの座標
depot = (0, 0)

def create_data_model():
data = {}
data['distance_matrix'] = [
[0, 10, 15, 20, 25, 30, 35],
[10, 0, 10, 15, 20, 25, 30],
[15, 10, 0, 10, 15, 20, 25],
[20, 15, 10, 0, 10, 15, 20],
[25, 20, 15, 10, 0, 10, 15],
[30, 25, 20, 15, 10, 0, 10],
[35, 30, 25, 20, 15, 10, 0]
]
data['num_vehicles'] = 1
data['depot'] = 0
return data

def plot_solution(manager, routing, solution):
index = routing.Start(0)
plan_output = 'Route for vehicle 0:\n'
route_distance = 0
while not routing.IsEnd(index):
plan_output += f'{manager.IndexToNode(index)} -> '
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
plan_output += f'{manager.IndexToNode(index)}\n'
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
print(plan_output)
print(f'Distance of the route: {route_distance} units')

# グラフの描画
G = nx.Graph()
for i in range(len(locations)):
G.add_node(i, pos=locations[i])
for i in range(manager.GetNumberOfVehicles()):
index = routing.Start(i)
while not routing.IsEnd(index):
next_index = solution.Value(routing.NextVar(index))
G.add_edge(manager.IndexToNode(index), manager.IndexToNode(next_index))
index = next_index

pos = nx.get_node_attributes(G, 'pos')
nx.draw(G, pos, with_labels=True, font_weight='bold', node_size=700, node_color='skyblue', font_size=8, font_color='black')
plt.show()

def main():
data = create_data_model()

# マネージャーの作成
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['depot'])

# モデルの作成
routing = pywrapcp.RoutingModel(manager)

# 距離のコスト関数の作成
def distance_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['distance_matrix'][from_node][to_node]

transit_callback_index = routing.RegisterTransitCallback(distance_callback)

# 距離のコストをセット
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

# ソルバーの設定
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.local_search_metaheuristic = (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
search_parameters.time_limit.seconds = 30

# ルートの構築
solution = routing.SolveWithParameters(search_parameters)

# 結果の表示
if solution:
plot_solution(manager, routing, solution)

if __name__ == '__main__':
main()

このコードは、7つの顧客と1つのデポ(出発点)がある場合の例です。

適切に顧客の座標と距離行列を設定し、Google OR-Toolsを使用して問題を解きます。

解が得られたら、経路と距離を表示し、グラフで可視化します。

なお、上記のコードを実行するには、ortools, matplotlib, networkx ライブラリがインストールされている必要があります。

インストールされていない場合は、以下のコマンドでインストールしてください。

1
pip install ortools matplotlib networkx

このコードをベースに、実際の問題に合わせて座標や距離行列を設定し、VRPを解くことができます。

ソースコード解説

このコードは、Google OR-Toolsを使用してVehicle Routing Problem (VRP) を解くサンプルです。

以下に、コードの各部分の詳細な説明を提供します。

1. モジュールのインポート:

1
2
3
4
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import matplotlib.pyplot as plt
import networkx as nx
  • ortoolsモジュールから、制約充足問題を解くための関連するクラスやメソッドをインポートしています。
  • matplotlibとnetworkxは、グラフを描画するためのライブラリです。

2. 顧客の座標とデポの座標の定義:

1
2
locations = [(35, 10), (15, 15), (25, 25), (30, 40), (45, 35), (10, 20), (50, 25)]
depot = (0, 0)
  • locationsは各顧客の座標を表すリストです。
  • depotはデポ(出発点)の座標を表します。

3. データモデルの作成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def create_data_model():
data = {}
data['distance_matrix'] = [
[0, 10, 15, 20, 25, 30, 35],
[10, 0, 10, 15, 20, 25, 30],
[15, 10, 0, 10, 15, 20, 25],
[20, 15, 10, 0, 10, 15, 20],
[25, 20, 15, 10, 0, 10, 15],
[30, 25, 20, 15, 10, 0, 10],
[35, 30, 25, 20, 15, 10, 0]
]
data['num_vehicles'] = 1
data['depot'] = 0
return data
  • create_data_model関数は、問題のデータモデルを作成します。
    距離行列、使用する車両の数、デポのインデックスなどが含まれています。

4. 解のプロット関数:

1
2
def plot_solution(manager, routing, solution):
# ...(省略)...
  • plot_solution関数は、解を受け取り、経路と距離を表示し、結果をグラフで可視化します。

5. メイン関数:

1
2
3
4
5
def main():
data = create_data_model()
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['depot'])
routing = pywrapcp.RoutingModel(manager)
# ...(省略)...
  • main関数は、問題データの作成、マネージャーとモデルの初期化、解の構築、および解の表示とグラフ描画を行います。

6. 距離のコスト関数の設定:

1
2
3
4
def distance_callback(from_index, to_index):
# ...(省略)...
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
  • distance_callback関数は、各エッジのコスト(距離)を定義します。
    この関数は、SetArcCostEvaluatorOfAllVehiclesメソッドを使用して、ルーティングモデルに登録されます。

7. ソルバーの設定と解の構築:

1
2
3
4
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.local_search_metaheuristic = (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
search_parameters.time_limit.seconds = 30
solution = routing.SolveWithParameters(search_parameters)
  • ソルバーの設定は、検索パラメーターを調整しています。
    GUIDED_LOCAL_SEARCHメタヒューリスティックを使用し、最大で30秒間の制限時間で解を構築します。

8. メイン関数の実行:

1
2
if __name__ == '__main__':
main()
  • スクリプトが直接実行された場合にmain関数を呼び出します。
    これにより、問題が解かれ、結果が表示されます。

このコードは、Google OR-Toolsを使用してVRPを解決し、解をコンソールに表示し、最適な経路をmatplotlibとnetworkxを使用してグラフで可視化します。

結果解説

[実行結果]

Route for vehicle 0:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0

Distance of the route: 130 units

上記の結果から、車両0が巡回した最適な経路は、デポ(出発点)を起点に顧客1、顧客2、顧客3、顧客4、顧客5、顧客6、そして再びデポへ戻るという順序です。

具体的な経路は、「0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0」となっています。

また、この最適な経路の総距離は130単位です。

この距離は、各辺(エッジ)の距離を合算したものであり、最適化アルゴリズムによって最小化された結果です。

さらに、上記の結果に対する可視化グラフが以下の通りです。

各ノードは顧客またはデポを表し、エッジは巡回した経路を示しています。

グラフはmatplotlibとnetworkxライブラリを使用して描画されています。

青い点は顧客やデポを表し、黒い線は最適な経路を示しています。

このグラフから、車両がどのように巡回したかが視覚的に理解できます。

非線形最小二乗法(Nonlinear Least Squares) SciPy

非線形最小二乗法(Nonlinear Least Squares)

SciPyを使用して非線形最小二乗法(Nonlinear Least Squares)を実行し、その結果をグラフ化する例を示します。

具体的には、次のような非線形関数を仮定して、ノイズが混じったデータを生成し、それを元に非線形最小二乗法でパラメータを推定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# 非線形関数の定義
def nonlinear_function(x, a, b):
return a * np.exp(b * x)

# データ生成
np.random.seed(42)
x_data = np.linspace(0, 2, 100)
y_data = 2.5 * np.exp(1.2 * x_data) + 0.2 * np.random.normal(size=len(x_data))

# 非線形最小二乗法でパラメータ推定
params, covariance = curve_fit(nonlinear_function, x_data, y_data)

# 推定されたパラメータ
a_fit, b_fit = params

# 推定した関数をプロット
y_fit = nonlinear_function(x_data, a_fit, b_fit)

# グラフ化
plt.scatter(x_data, y_data, label='実際のデータ')
plt.plot(x_data, y_fit, 'r', label='非線形最小二乗法によるフィット')
plt.title('非線形最小二乗法によるフィット')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

この例では、非線形関数 $a * exp(b * x)$ に従うデータを生成し、curve_fit 関数を使用して非線形最小二乗法によりパラメータ $a$ と $b$ を推定しています。

結果をグラフで可視化しています。

このコードを実行すると、元データと非線形最小二乗法によってフィットされた曲線が可視化されます。

データにノイズが含まれているため、フィットされた曲線が元データによく適合していることが期待されます。

ソースコード解説

以下にソースコードの各部分の詳細な説明をします。

1. import numpy as np:

  • NumPy ライブラリを np としてインポートしています。
    NumPyは数値計算や行列演算を行うための基本的なライブラリです。

2. import matplotlib.pyplot as plt:

  • Matplotlib ライブラリの pyplot モジュールを plt としてインポートしています。
    Matplotlibはグラフ描画ライブラリで、pyplot モジュールは簡単なプロットを作成するための機能を提供します。

3. from scipy.optimize import curve_fit:

  • SciPy ライブラリから curve_fit 関数をインポートしています。
    curve_fit 関数は、非線形最小二乗法によって関数のパラメータを推定するために使用されます。

4. 非線形関数の定義:

  • nonlinear_function は非線形関数を表しています。
    この例では、指数関数 $a * exp(b * x)$ が使われています。
    関数はパラメータ $a$ と $b$ を受け取り、$a * np.exp(b * x)$ を返します。

5. データ生成:

  • np.linspace(0, 2, 100) を用いて、0から2までの範囲を等間隔に区切った x_data を生成します。
  • 2.5 * np.exp(1.2 * x_data) + 0.2 * np.random.normal(size=len(x_data)) により、ノイズを加えた非線形なデータ y_data を生成します。
    np.random.normal は平均0、標準偏差0.2の正規分布に従うノイズです。

6. 非線形最小二乗法:

  • curve_fit(nonlinear_function, x_data, y_data) で非線形最小二乗法を実行し、関数 nonlinear_function のパラメータをデータにフィットさせます。
    結果として、params には推定されたパラメータが、covariance には共分散行列が格納されます。

7. 推定されたパラメータ:

  • params から得られた推定されたパラメータ a_fit と b_fit を抽出します。

8. 推定した関数をプロット:

  • 推定されたパラメータを用いて、元の非線形関数を再度計算し、y_fit として保存します。

9. グラフ化:

  • plt.scatter を用いて元のデータを散布図としてプロットします。
  • plt.plot を用いて、非線形最小二乗法によって得られたフィットした曲線をプロットします。
    色は赤色 ('r') に設定されています。
  • タイトル、x軸ラベル、y軸ラベルを設定します。
  • plt.legend() で凡例を表示します。
  • plt.show() でグラフを表示します。

このプログラムを実行すると、元のデータと非線形最小二乗法によってフィットされた曲線が同じグラフ上に表示されます。

これにより、非線形最小二乗法がデータに適切に適合しているかを可視化できます。

結果解説

上記のコードで生成されるグラフは、非線形最小二乗法を使用してフィットされた曲線と元のデータを可視化したものです。

以下にグラフの要素について詳しく説明します。

1. 散布図(Scatter plot):

  • データ生成時に生成されたノイズの影響を受けた実際のデータ点が散布図として表示されています。

2. フィットされた曲線(Fitted Curve):

  • 赤い線が非線形最小二乗法によって推定された非線形関数の曲線です。
    この曲線は、データに最もよく適合するようにパラメータ a と b が調整された結果です。

3. タイトル(Title):

  • グラフのタイトルは「非線形最小二乗法によるフィット」となっています。

4. x軸とy軸(X-axis and Y-axis):

  • x軸は x_data で、y軸は y_data および y_fit で、それぞれデータのx座標とy座標を表しています。

5. 凡例(Legend):

  • グラフには凡例が表示されており、散布図が「実際のデータ」、赤い線が「非線形最小二乗法によるフィット」を示しています。

このグラフから、非線形最小二乗法が元のデータに対して適切な曲線をフィットしていることがわかります。

データの散らばりに対応して、赤い線がデータの傾向を捉えています。

最小二乗法によって得られたパラメータにより、元の非線形関数が近似され、それが赤い線として表示されています。