通过任意数量点拟合曲线

原理是:任意数量点,都可以计算出穿过他们的一个多项式公式。

# -*-coding:utf-8-*-
from sympy import *
import numpy as np
import matplotlib.pyplot as plt
import random
# x = Symbol('x')
# y = Symbol('y')
# print(solve([3*x + 4*y - 49, 8*x - y - 14], [x, y]))


def do_a(points = None):
    vari = []

    for i, point in enumerate(points):
        var_tem = Symbol('a_'+str(i))
        vari.append(var_tem)

    express_arr = []
    for i, point in enumerate(points):
        express_arr.append(0)
        for j in range(len(vari)):
            express_arr[i] = express_arr[i] + vari[j] *  (point[0]**j)
        express_arr[i] -= point[1]
    return solve(express_arr, vari)

def draw_pic(var, points ):
    t = np.arange(0, 100, 1)
    y_arr = []
    str_exp = 'y = '

    for i in range(len(t)):
        y_arr.append(0)
        for j,ex in enumerate(var):
            if i == 0:
                if j == 0:
                    str_exp += str(var[ex])
                else:
                    if var[ex] > 0:
                        str_exp += ' + ' + str(var[ex]) + ' * ' + 'X^'+str(j)
                    else:
                        str_exp += ' - ' + str(abs(var[ex]) ) + ' * ' + 'X^'+str(j)
            y_arr[i] += var[ex] * ( t[i]**j )

    print('表达式:', str_exp)
    plt.figure(num=1, figsize=(100, 100))
    plt.axis([0, 200, 0, 200])
    plt.plot(t, y_arr, color='red')
    plt.scatter([p[0] for p in points],[p[1] for p in points])
    plt.show()

p = [ [2,10], [3,7], [11.5, 20.5], [20.2, 12.5] ]
p = [ ]
for i in range(6):
    x = random.randint(0, 100)
    y = random.randint(0, 100)
    p.append([x, y ])

la = do_a(points = p)

print(la )
draw_pic(la, points= p)

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RANSAC(Random Sample Consensus)是一种基于随机采样的拟合算法,常用于拟合含有噪声的数据集。在拟合曲线时,RANSAC可以过滤掉不符合模型的噪声,从而得到更准确的曲线拟合结果。 下面是用Python实现RANSAC拟合曲线的示例代码: ```python import numpy as np import matplotlib.pyplot as plt # 生成含噪声的数据集 x = np.linspace(-5, 5, 50) y = 2 * x + 3 + np.random.randn(50) * 3 # 定义RANSAC函数 def ransac(data, model, n, k, t, d, debug=False, return_all=False): """ 输入: data - 样本 model - 假设模型:事先自己确定,比如这里的lineModel n - 生成模型所需的最少样本 k - 最大迭代次数 t - 阈值:作为判断满足模型的条件 d - 拟合度:样本满足模型的最少数量 """ iterations = 0 bestfit = None besterr = np.inf best_inlier_idxs = None while iterations < k: # 从样本中随机选取n个 maybe_idxs = np.random.randint(0, data.shape[0], n) maybe_inliers = data[maybe_idxs, :] # 除去随机选出的,剩下的就是测试 test_idxs = np.arange(data.shape[0]) test_idxs = np.delete(test_idxs, maybe_idxs) test_inliers = data[test_idxs, :] # 用假设模型拟合随机选取的 maybemodel = model.fit(maybe_inliers) # 计算所有到这条线的距离 test_err = model.get_error(test_inliers, maybemodel) # 找到满足条件的 also_idxs = test_idxs[test_err < t] also_inliers = data[also_idxs, :] # 如果满足条件的数量大于d,说明找到了一个合理的模型 if len(also_inliers) > d: # 将随机选取的和满足条件的合并,重新拟合模型 betterdata = np.concatenate((maybe_inliers, also_inliers)) bettermodel = model.fit(betterdata) # 计算新模型下所有到曲线的距离 better_errs = model.get_error(betterdata, bettermodel) # 计算误差 thiserr = np.mean(better_errs) # 如果误差小于之前的最小误差,就更新最优模型 if thiserr < besterr: bestfit = bettermodel besterr = thiserr best_inlier_idxs = np.concatenate((maybe_idxs, also_idxs)) iterations += 1 if debug: print('RANSAC Iteration %d: Inliers: %d' % (iterations, len(best_inlier_idxs))) if bestfit is None: raise ValueError("RANSAC: unable to find a valid consensus set") if return_all: return bestfit, {'inliers': best_inlier_idxs} else: return bestfit # 定义线性模型 class LineModel: def __init__(self): self.a = None self.b = None def fit(self, data): x = data[:, 0] y = data[:, 1] A = np.vstack([x, np.ones(len(x))]).T self.a, self.b = np.linalg.lstsq(A, y, rcond=None)[0] return self def get_error(self, data, model): x = data[:, 0] y = data[:, 1] A = np.vstack([x, np.ones(len(x))]).T return np.abs(np.dot(A, model) - y) # 使用RANSAC拟合直线 data = np.column_stack([x, y]) model = LineModel() ransac_fit = ransac(data, model, 2, 100, 10, 40, debug=True, return_all=True) # 绘制结果 inlier_idxs = ransac_fit[1]['inliers'] outlier_idxs = np.delete(np.arange(len(data)), inlier_idxs) plt.plot(data[inlier_idxs, 0], data[inlier_idxs, 1], '.g', label='Inliers') plt.plot(data[outlier_idxs, 0], data[outlier_idxs, 1], '.r', label='Outliers') line_x = np.array([-5, 5]) line_y = ransac_fit[0].a * line_x + ransac_fit[0].b plt.plot(line_x, line_y, '-b', label='RANSAC line') plt.legend(loc='best') plt.show() ``` 上述代码生成含噪声的数据集,然后定义了一个线性模型和RANSAC函数。最后使用RANSAC拟合直线并绘制结果。可以根据需要修改代码以拟合不同的曲线。 ### 回答2: RANSAC是一种基于迭代的参数估计方法,常用于拟合曲线。它主要通过随机选择样本中的一部分来估计曲线的参数,并根据估计结果计算其他样本与估计曲线之间的误差。下面我来介绍一下RANSAC拟合曲线Python实现。 首先,我们需要导入一些必要的库: ```python import numpy as np from sklearn.linear_model import RANSACRegressor from sklearn.preprocessing import PolynomialFeatures import matplotlib.pyplot as plt ``` 接下来,我们准备一些样本数据: ```python x = np.linspace(-5, 5, 100) y = 2 * x**2 - 3 * x + 1 + np.random.randn(100) * 5 # 添加噪声 ``` 然后,我们使用RANSACRegressor进行拟合曲线的操作: ```python ransac = RANSACRegressor() poly = PolynomialFeatures(degree=2) # 设置多项式最高阶数为2 x_poly = poly.fit_transform(x.reshape(-1, 1)) ransac.fit(x_poly, y) inlier_mask = ransac.inlier_mask_ outlier_mask = np.logical_not(inlier_mask) ``` 这里我们使用了二次多项式进行拟合,因此设置`degree=2`。`inlier_mask`是用于识别符合模型的内,`outlier_mask`则是用于识别不符合模型的外。 最后,我们可以将拟合结果可视化: ```python plt.scatter(x[inlier_mask], y[inlier_mask], color='blue', label='Inliers') plt.scatter(x[outlier_mask], y[outlier_mask], color='red', label='Outliers') plt.plot(x, ransac.predict(poly.fit_transform(x.reshape(-1, 1))), color='black', label='RANSAC') plt.legend() plt.show() ``` 这里,我们使用蓝色的表示符合模型的内,红色的表示不符合模型的外,黑色的曲线表示拟合的曲线。 以上就是RANSAC拟合曲线Python实现方法。通过以上步骤,我们可以很方便地使用RANSAC算法来拟合曲线并识别出符合模型的内。 ### 回答3: RANSAC(Random Sample Consensus)是一种鲁棒拟合模型的算法,可以用于拟合曲线。在Python中,可以使用scikit-learn库中的RANSACRegressor类来实现RANSAC算法。 首先,导入必要的库: ```python from sklearn.linear_model import RANSACRegressor import numpy as np import matplotlib.pyplot as plt ``` 然后,准备数据集,包括自变量和因变量: ```python x = np.array([1, 2, 3, 4, 5]) # 自变量 y = np.array([2, 3, 4, 5, 6]) # 因变量 ``` 接下来,使用RANSACRegressor类进行拟合: ```python model = RANSACRegressor() model.fit(x[:, np.newaxis], y) # 将自变量转换成列向量 ``` 拟合完成后,可以得到拟合的直线的斜率和截距: ```python slope = model.estimator_.coef_[0] intercept = model.estimator_.intercept_ ``` 最后,可以绘制原始数据和拟合的曲线: ```python plt.scatter(x, y, color='blue', label='Data') plt.plot(x, model.predict(x[:, np.newaxis]), color='red', label='RANSAC Fit') plt.legend() plt.show() ``` 以上就是用Python实现RANSAC拟合曲线的过程。通过这个方法可以对任意数据集进行曲线拟合,并得到拟合的直线模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值