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

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

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

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

Q&A

解決済

1回答

983閲覧

エラーへの対処の仕方がわかりません。

kikuchiX

総合スコア8

Python

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

0グッド

0クリップ

投稿2020/11/21 06:40

前提・実現したいこと

以下のサイトのサイプルコードを変えながら、最小二乗法を実施しようとしております。
https://medium.com/micin-developers/decipher-github-lr-sw-40e519a13c0a

サンプルコード

# 必要なライブラリのインポート import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression # 観測点の生成(等間隔のxに対して、ノイズを乗っけたyを生成) np.random.seed(0) x = (np.arange(51) / 50)[:, np.newaxis] noise = (np.random.rand(51) / 3)[:, np.newaxis] y = (x * 2) + noise # -------------------------------------------------- # scikit-learnのsolverによって、近似直線を得る clf = LinearRegression(fit_intercept=True) clf.fit(X=x, y=y) y_hat = clf.predict(x) # -------------------------------------------------- # 最小二乗法の式を解いて、近似直線式の係数を得る x_ = np.concatenate([x, np.ones(np.shape(x))], axis=1) w = np.dot(np.linalg.inv(np.dot(x_.T, x_)), np.dot(x_.T, y)) y_hat_ = np.dot(x_, w) # -------------------------------------------------- # x、yと学習によって得た近似直線を描画する cmap = plt.get_cmap("tab10") plt.figure(figsize=(12,16), dpi=100) plt.subplot(2, 1, 1) plt.grid(which='major', color=[0.7, 0.7, 0.7], linestyle='-') plt.scatter(x, y, s=300, alpha=0.7, color=cmap(0), label='観測点') plt.plot(x, y_hat, linewidth=10, alpha=0.7, color=cmap(1), label='近似曲線 by scikit-learn') plt.plot(x, y_hat_, linewidth=8, alpha=0.3, color=cmap(2), label='近似曲線 by 最小二乗法', linestyle='--') plt.legend(fontsize=15, loc='lower right') plt.ylim([0, 3.5]) print('scikit-learnで解いたweight = [%.3f, %.3f]' % (clf.coef_, clf.intercept_)) print('最小二乗法で解いたweight = [%.3f, %.3f]' % (w[0], w[1])) plt.show()

変更したコード

サンプルコードの観測点の部分を、実験値に置き換えただけです。

# 必要なライブラリのインポート import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression # 測定値 x = np.array([6.26379, 8.57417, 8.66527, 8.75069, 11.6708, 12.3487, 14.5032, 15.7422, 21.7646, 23.0518, 26.5069, 26.4035, 26.321, 23.0045, 19.2654, 17.9425, 14.5669, 13.513, 10.4902, 9.95136, 9.77395]) y = np.array([3.709910308, 3.300454417, 3.219869361, 2.879991517, 2.250120678, 2.24981186, 1.859931899, 1.839996231, 1.560029151, 1.360016958, 1.210037387, 1.527926405, 1.320005022, 1.340038138, 1.618120234, 1.410033737, 1.83006856, 1.849465938, 2.141939621, 2.219958336, 2.494675074]) # -------------------------------------------------- # scikit-learnのsolverによって、近似直線を得る clf = LinearRegression(fit_intercept=True) clf.fit(X=x, y=y) y_hat = clf.predict(x) # -------------------------------------------------- # 最小二乗法の式を解いて、近似直線式の係数を得る x_ = np.concatenate([x, np.ones(np.shape(x))], axis=1) w = np.dot(np.linalg.inv(np.dot(x_.T, x_)), np.dot(x_.T, y)) y_hat_ = np.dot(x_, w) # -------------------------------------------------- # x、yと学習によって得た近似直線を描画する cmap = plt.get_cmap("tab10") plt.figure(figsize=(12,16), dpi=100) plt.subplot(2, 1, 1) plt.grid(which='major', color=[0.7, 0.7, 0.7], linestyle='-') plt.scatter(x, y, s=300, alpha=0.7, color=cmap(0), label='測定値') plt.plot(x, y_hat, linewidth=10, alpha=0.7, color=cmap(1), label='近似曲線 by scikit-learn') plt.plot(x, y_hat_, linewidth=8, alpha=0.3, color=cmap(2), label='近似曲線 by 最小二乗法', linestyle='--') plt.legend(fontsize=15, loc='lower right') plt.ylim([0, 3.5]) print('scikit-learnで解いたweight = [%.3f, %.3f]' % (clf.coef_, clf.intercept_)) print('最小二乗法で解いたweight = [%.3f, %.3f]' % (w[0], w[1])) plt.show()

このコードを実行すると以下のようなエラ〜メッセージが出てしまいます。

エラー

Expected 2D array, got 1D array instead: array=[ 6.26379 8.57417 8.66527 8.75069 11.6708 12.3487 14.5032 15.7422 21.7646 23.0518 26.5069 26.4035 26.321 23.0045 19.2654 17.9425 14.5669 13.513 10.4902 9.95136 9.77395]. Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

この場合、どのようにコードを改変するべきなのでしょうか?
ご教授いただけると幸いです。
何卒宜しくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

中身は理解していませんが、元のコードから推測すると以下のコードを追加すればよいかと思います。

Python

12x = np.array([6.26379, 8.57417, 8.66527, 8.75069, 11.6708, 12.3487, 14.5032, 15.7422, 21.7646, 23.0518, 26.5069, 26.4035, 26.321, 23.0045, 19.2654, 17.9425, 14.5669, 13.513, 10.4902, 9.95136, 9.77395]) 3y = np.array([3.709910308, 3.300454417, 3.219869361, 2.879991517, 2.250120678, 2.24981186, 1.859931899, 1.839996231, 1.560029151, 1.360016958, 1.210037387, 1.527926405, 1.320005022, 1.340038138, 1.618120234, 1.410033737, 1.83006856, 1.849465938, 2.141939621, 2.219958336, 2.494675074]) 4 5# 以下を追加 6x = x[:,np.newaxis] 7y = y[:,np.newaxis]

イメージ説明

投稿2020/11/21 06:48

can110

総合スコア38280

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

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

kikuchiX

2020/11/21 06:54

ありがとうございます!!
kikuchiX

2020/11/21 06:57

ちなみになんですけど、このサンプル(直線近似)を曲線(非線形)にすることって可能なのでしょうか?
can110

2020/11/21 06:59

中身は理解していませんので分かりかねます。
kikuchiX

2020/11/21 07:32

ご回答ありがとうございます。
kikuchiX

2020/11/22 01:00

コメントありがとうございます。 今検討している関数は以下のコードの通りです。 これを実験データにフィッティングしたいということです。 ``` import numpy as np import matplotlib.pyplot as plt import math from scipy.optimize import curve_fit # 係数を見つけたい関数 def func(x, a): return ((-(a+(0.0615*x))) + ((a+((0.0615*x)**2)) - (4*0.0615*math.log(0.1)))**0.5) / (2*0.0615) # 求めたい分布関数の元データ x = np.array([6.26379, 8.57417, 8.66527, 8.75069, 11.6708, 12.3487, 14.5032, 15.7422, 21.7646, 23.0518, 26.5069, 26.4035, 26.321, 23.0045, 19.2654, 17.9425, 14.5669, 13.513, 10.4902, 9.95136, 9.77395]) y = np.array([3.709910308, 3.300454417, 3.219869361, 2.879991517, 2.250120678, 2.24981186, 1.859931899, 1.839996231, 1.560029151, 1.360016958, 1.210037387, 1.527926405, 1.320005022, 1.340038138, 1.618120234, 1.410033737, 1.83006856, 1.849465938, 2.141939621, 2.219958336, 2.494675074]) sigma = (x, y) plt.plot(x, y, 'bo', label='Experimental data') plt.legend() ```
jbpb0

2020/11/22 11:09

https://teratail.com/questions/305680 とかの件ですよね sigmaは、yのそれぞれの誤差に違いがあるという「知識」をfitに反映させるためのものです たとえば、xが大きい方の5つのデータだけ他よりも測定誤差が(yが測定データだとして)大きいという「知識」があれば、下記のようすると、その「知識」を反映させるとfit結果が変わることが分かります # xの大小で並べ替え z = zip(x, y) zz = sorted(z) xx, yy = zip(*zz) xx = np.array(xx) yy = np.array(yy) xs = np.linspace( min(xx), max(xx), 100) # 普通のfit popt, pcov = curve_fit(func, xx, yy) # 重み付きfit sigma = np.ones(len(yy)) * 0.01 sigma[-5:] = 0.1 sigma popt2, pcov2 = curve_fit(func, xx, yy, sigma=sigma) # 比較 plt.plot(xx, yy, 'bo', label="Experimental data") plt.plot(xs, func(xs, *popt),'r', label="Unweighted fitting:a={:.3f}".format(*popt)) plt.plot(xs, func(xs, *popt2),'g', label="Weighted fitting:a={:.3f}".format(*popt2)) plt.legend() plt.show() データの素性を知らない我々の様な第三者にはその「知識」は無いので、このデータだけからsigmaを作れる方法を聞いても、回答をもらうのは難しいと思いますよ
jbpb0

2020/11/22 11:19

もしも、yが測定生値ではなく、yは測定生値y'から何らかの方法で変換されたもので、測定生値y'は全て誤差が同じならば、y'からyへの変換方法に基づいて各yの誤差(curve_fitのsigma)を決めることができます https://teratail.com/questions/305680 でtoast-uzさんが提示された https://sturgeon.hatenablog.com/entry/log-lsm に、その方法が説明されています
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問