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

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

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

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

Q&A

解決済

3回答

3479閲覧

点郡から2直線を推定したいです.

93monocro

総合スコア8

Python

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

0グッド

0クリップ

投稿2020/03/09 18:45

python3で,ある点郡をなぞるような2直線を引きたいと考えております.
イメージとしては下図のとおりです.ここでは赤線を推定したいです.
イメージ説明

よろしくお願い申し上げます。

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

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

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

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

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

guest

回答3

0

python3で,ある点郡をなぞるような2直線を引きたいと考えております.

イメージとしては下図のとおりです.ここでは赤線を推定したいです.

※あくまでこちらの創造出来る範囲で答えさせて頂きます。

点郡ということは散らばっているのをイメージしましたので、配列順で線を引いていくだけだと味気ないと思います。多分そういうことをしたいのではないと思います。

1回目は単純に点郡との距離が一番近いところに線を引っ張り、2回目以降は一つ前の線の進行方向と近しい点のベクトルの内積が最も0に近い方向に進んでいく。

この方法なら、しっかりと点郡に沿って線が引けるのではないかと思います。

投稿2020/03/10 06:30

stdio

総合スコア3307

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

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

0

ベストアンサー

とりあえずその線の式について考えます。パラメータ4つの式になるはずです。

plain

1y = ax + b (x < c) 2y = dx + (a - d)c + b (x >= c) 3# (c, ac + b)を通る傾きdの式なので 4# y - ac - b = d(x - c) (x >= c) 5# である。上式二行目はそれを整理したもの

素晴らしいことに、式がわかればscipy.optimize.curve_fitを使って最小ニ乗推定を行うことができます。これだと多少ノイズがあったりしても上手く解けます。

scipy.optimize.curve_fit — SciPy v1.4.1 Reference Guide

(今回の関数はx=cの点で微分できないのだと思いますが、これで数理的に厳しいことになるのかどうかは正確には把握できていないので、識者の方のご意見を伺いたいです)
(ちなみに、ノイズがないなら、各隣接点同士を結ぶ傾きをすべて求めればいいです。出てくるユニークな値は2つになるのでそれが上の式のaとdで、あとは適当な点を使ってb, cのパラメータを求めれば良いです)

python

1import numpy as np 2import matplotlib.pyplot as plt 3from scipy.optimize import curve_fit 4 5a, b, c, d = -1, 2, -3, 4 6 7def func(x, a, b, c, d): 8 """ 9 y = ax + b (x < c) 10 y = dx + (a - d)c + b (x >= c) 11 # (c, ac + b)を通る傾きdの式なので 12 # y - ac - b = d(x - c) (x >= c) 13 # である。上式はそれを整理したもの 14 """ 15 16 mask = x < c 17 result = np.empty(dtype=np.float64, shape=x.shape) 18 result[mask] = a * x[mask] + b 19 result[~mask] = d * x[~mask] + (a - d) * c + b 20 return result 21 22x = np.arange(-10, 10, 0.5) 23y_ = func(x, a, b, c, d) 24y = y_ + np.random.normal(size=x.shape) 25result = curve_fit(func, x, y) 26plt.scatter(x, y, label="samples", alpha=0.5) 27plt.plot(x, y_, linestyle="--", label="true") 28plt.plot(x, func(x, *result[0]), linestyle="--", label="estimated") 29plt.title("a:{:.2f} b:{:.2f} c:{:.2f} d:{:.2f}".format(*result[0])) 30plt.legend() 31plt.savefig("result.png") 32

イメージ説明

悪くない感じでフィッティングされます。

追記

でもこれだと、x方向に折り返すような関数は駄目なはずなので、もう少し改良の余地がある。できるようになる座標変換を考えることはできるはずなので、まあなんとかなるとは思うのですが。しばらく考えさせてください(先に思いついた方は回答を投稿していただけると嬉しいです)。

投稿2020/03/10 06:30

編集2020/03/10 07:02
hayataka2049

総合スコア30935

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

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

hayataka2049

2020/03/10 07:31 編集

駄目なときは90度回せばいいかな? xとyを入れ替えて両方やって、良かった方の結果を採用するとかでいいんでしょうか (当然回転側になったときは90度回転した空間で出したパラメータになるのですが)
guest

0

点の並び順が直線上になっているならば、2点間の線分(の傾き)を算出しながら進み、傾きが変化したところが曲がり角ですから、最初の点→曲がり角の点と、曲がり角の点→最後の点、の2直線を引けば済みますが……そういうことではないですよね?

必ずしも2直線上には並んでいない点群から、2直線でなぞりたい、のですよね?
であれば、点群からもっとも近似する「曲線」を作成し、その曲線の両端点での接線を出す……のかな?

投稿2020/03/10 01:21

tacsheaven

総合スコア13703

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問