给定使用给定基向量建立的函数的矩阵的值近似

时间:2018-06-02 23:17:22

标签: python python-3.x machine-learning linear-algebra linear-regression

首先请原谅我,如果标题听起来有点令人困惑。英语不是我的母语,所以虽然我很流利,但某些技术术语可能不正确。让我知道我是否以及如何改进它。

我在Python的机器学习课程中获得了一项任务。我有一个值表(我相信我可以称之为矩阵),可以使用以下代码进行可视化:

import numpy as np
from numpy.linalg import inv
import pandas as pd
import matplotlib.pyplot as plt


h = np.array([x for x in range(0,5500,500)])
v = np.array([x for x in range(0,65,5)])

print(h.shape,v.shape)

y = np.array([83.4, 78.7, 74.1, 69.7, 65.4, 61.3, 57.4, 53.6, 50.0, 46.5, 43.2,
 75.1, 70.8, 66.6, 63.3, 59.5, 55.7, 52.7, 49.2, 46.4, 43.2, 40.5,
 69.7, 65.7, 62.2, 58.8, 55.2, 52.0, 48.9, 45.9, 43.1, 40.3, 37.6,
 64.4, 61.0, 57.6, 54.2, 51.0, 48.0, 45.1, 42.4, 39.7, 37.1, 34.7,
 59.9, 56.6, 53.3, 50.3, 47.5, 44.6, 41.9, 39.3, 36.8, 34.4, 32.1,
 56.1, 53.0, 50.1, 47.2, 44.5, 41.9, 39.3, 36.9, 34.6, 32.3, 30.2,
 53.3, 50.4, 47.5, 44.8, 42.2, 39.8, 37.4, 35.1, 32.8, 30.7, 28.6,
 50.9, 48.1, 45.4, 42.8, 40.3, 38.0, 35.7, 33.4, 31.3, 29.3, 27.3,
 48.7, 46.0, 43.4, 40.9, 38.6, 36.3, 34.1, 31.9, 29.9, 27.9, 26.1,
 46.4, 43.9, 41.4, 39.0, 36.8, 34.6, 32.4, 30.4, 28.5, 26.6, 24.8,
 44.1, 41.7, 39.3, 37.1, 34.9, 32.8, 30.7, 28.8, 26.9, 25.2, 23.4,
 41.7, 39.4, 37.2, 34.9, 32.9, 30.9, 29.0, 27.2, 25.4, 23.7, 22.0,
 39.3, 37.2, 34.9, 32.9, 31.0, 29.1, 27.3, 25.6, 23.8, 22.3, 20.7])

# Confirm lengths all match
y.shape
len(y) == len(h)*len(v)

###################################
# Matrix visualization with Pandas
dataframe = pd.DataFrame(y.reshape(13,11), index=v, columns=h)

print(dataframe)

对于情境化,线条是速度(m / s),列是飞艇的高度(m)。这些值是飞机的推力(N - 牛顿)。

要解决的问题是:

  

使用以下基数元素构建的函数近似矩阵:{1,v,h,v²,h²,vh,v³,h³,v²h,vh²,v²h²,v³h,vh³}

首先,我真的不明白问题的核心是什么。那些是多元线性回归中的β值?如此多的测试版有什么好处?

在朋友的帮助下,我能够实现以下解决方案:

base = []
i = 0
j = 0

for i in range(0,len(v)):
    for j in range(0,len(h)):
        base.append([1, v[i], h[j], v[i]**2 , h[j]**2, v[i] * h[j],
                    v[i]**3, h[j]**3, (v[i]**2) * h[j], v[i] * (h[j]**2),
                    (v[i]**2) * (h[j]**2), (v[i]**3) * h[j], v[i] * (h[j]**3)])

base = np.array(base)
base.shape
base_df = pd.DataFrame(base)
print(base_df)


base_tp = np.transpose(base)
d = np.dot(base_tp, base)
inv_d = inv(d)
# print(inv_d.shape, base_tp.shape)
x = np.dot(inv_d, base_tp)
beta = np.dot(x, y)

print(beta.shape,beta)

这就是我到目前为止所拥有的。我相信这是正确的,但我不会因为它而伸出脖子。在继续之前,我应该使用y.reshape(143,1)重新整形初始y数组吗?如果是这样的话?

2 个答案:

答案 0 :(得分:0)

据我所知,这是一个多元回归问题,其中飞机速度(v)和高度(h)用于模拟推力(t) - 即推力=模型(速度,高度)&# 34 ;.这意味着某些数学公式将使用给定的数据和所提供的数学函数建模,例如v平方,高度立方等。最简单的方法是使用"线性回归"其中使用给定函数的不同组合,如" t = a + b h + c v"等等。" 1"给出的意思是" a * 1"这只是" a",这通常被称为偏移参数。

我制作了数据的3D散点图,看起来有一些突然的不连续性,这是一张图片显示:

still.png

然而,使用此3D动画GIF(6.6 MBytes)在3个空间中旋转的数据更容易看到:http://zunzun.com/temp/static_images/rotation.gif

为了帮助您创建3D散点图,函数的3D曲面图和3D轮廓图,这里是一些用于 - 线性拟合的Python代码,它使用matplotlib创建这些图。< / p>

import numpy, scipy, scipy.optimize
import matplotlib
from mpl_toolkits.mplot3d import  Axes3D
from matplotlib import cm # to colormap 3D surfaces from blue to red
import matplotlib.pyplot as plt

graphWidth = 800 # units are pixels
graphHeight = 600 # units are pixels

# 3D contour plot lines
numberOfContourLines = 16


def SurfacePlot(func, data, fittedParameters):
    f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

    matplotlib.pyplot.grid(True)
    axes = Axes3D(f)

    x_data = data[0]
    y_data = data[1]
    z_data = data[2]

    xModel = numpy.linspace(min(x_data), max(x_data), 20)
    yModel = numpy.linspace(min(y_data), max(y_data), 20)
    X, Y = numpy.meshgrid(xModel, yModel)

    Z = func(numpy.array([X, Y]), *fittedParameters)

    axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)

    axes.scatter(x_data, y_data, z_data) # show data along with plotted surface

    axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
    axes.set_xlabel('X Data') # X axis data label
    axes.set_ylabel('Y Data') # Y axis data label
    axes.set_zlabel('Z Data') # Z axis data label

    plt.show()
    plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


def ContourPlot(func, data, fittedParameters):
    f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
    axes = f.add_subplot(111)

    x_data = data[0]
    y_data = data[1]
    z_data = data[2]

    xModel = numpy.linspace(min(x_data), max(x_data), 20)
    yModel = numpy.linspace(min(y_data), max(y_data), 20)
    X, Y = numpy.meshgrid(xModel, yModel)

    Z = func(numpy.array([X, Y]), *fittedParameters)

    axes.plot(x_data, y_data, 'o')

    axes.set_title('Contour Plot') # add a title for contour plot
    axes.set_xlabel('X Data') # X axis data label
    axes.set_ylabel('Y Data') # Y axis data label

    CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
    matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours

    plt.show()
    plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


def ScatterPlot(data):
    f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

    matplotlib.pyplot.grid(True)
    axes = Axes3D(f)
    x_data = data[0]
    y_data = data[1]
    z_data = data[2]

    axes.scatter(x_data, y_data, z_data)

    axes.set_title('Scatter Plot (click-drag with mouse)')
    axes.set_xlabel('X Data')
    axes.set_ylabel('Y Data')
    axes.set_zlabel('Z Data')

    plt.show()
    plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


def func(data, a, alpha, beta):
    t = data[0]
    p_p = data[1]
    return a * (t**alpha) * (p_p**beta)


if __name__ == "__main__":
    xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
    yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
    zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])

    data = [xData, yData, zData]

    # this example uses curve_fit()'s default initial paramter values
    fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData)

    ScatterPlot(data)
    SurfacePlot(func, data, fittedParameters)
    ContourPlot(func, data, fittedParameters)

    print('fitted prameters', fittedParameters)

答案 1 :(得分:0)

  

首先,我真的不明白内心的含义   题。这些是多元线性中的beta值   回归对吗?这么多人做这件事有什么好处   贝塔?

此处的任务是假设y值可以根据vh值建模,作为指定基本元素的线性组合。你提到的 beta 是各个基本元素所贡献的系数。

正式来说,正在寻找A . betas = y的解决方案,其中y作为一维数组(向量)输入,矩阵元素A_ij包含j基础元素评估对应于v的{​​{1}}和h值(即y_iv的值h被测量“)。

由于问题是超定的(矩阵y_i有更多的行而不是列),人们必须以某种方式放松“解决方案”的定义 - 一个可能的候选者是可以正式获得的最小二乘解(如你已经在你的问题中实现了)作为方程组A的解决方案。

然而,矩阵(A^T.A) . betas = A^T . y往往非常恶劣,所以我建议使用numpy提供的最小二乘解算器,而不是明确地计算逆矩阵:

(A^T.A)

或改为使用pseudoinverse

beta, res, rank, s = np.linalg.lstsq(base, y, rcond = -1)

现在,如果您将获得的“fit”的最大相对误差检查为:

beta = np.dot(np.linalg.pinv(base), y)

然后基于计算矩阵np.max(np.abs((np.dot(base, beta) - y) / y)) 的直接逆的方法得到大约A^T.A,而最小二乘求解器提供0.05的值。

  

我应该用y.reshape(143,1)重新整形初始y数组吗?   在继续之前?

如果您不重新塑造0.01,则解决方案y的形状为beta,如果您执行(13,),则形状为y.reshape(143, 1) {}}将是beta,但两种情况都同样有效......