sklearn进行简单的线性回归以及求切线

目录

需求分析

处理一段数据,需要求某点切线的斜率。想法是先用线性回归拟合出曲线的解析式,然后根据高中学的导数的定义求出某点的导数。

数据很整齐,但是是一条曲线,应该先把x进行升维然后进行更高次的线性回归,输出曲线解析式。然后根据导函数的定义输出导函数解析式。但是因为我没学过高等数学也没学过线性代数,sklearn也只会熟悉最基础的几个部分所以代码有不太成熟的地方就当是抛砖引玉。

关键代码

升维部分

初高中学过的 y = k x + b y = kx+b y=kx+b图像时一条直线,实际数据很少会这么规整,所以要进行升维
(以三次多项式为例) y y y= k 1 k_1 k1​ x 3 x^3 x3+ k 2 k_2 k2​ x 2 x^2 x2+ k 3 k_3 k3​ x x x+ b b b的形式
学过线代的就可以写成 y = w x + b y=wx+b y=wx+b
像我这样没学过的,就先百度明白了再接着写吧

def __rise_x_dimension(self, x_data):
        """
        多项式升维
        :param n: 升维次数,默认四次
        """
        res = []
        temp_x_data = x_data.reshape(-1, 1)
        for i in range(1, self.dimension + 1):
            res.append(temp_x_data ** i)
        return np.hstack(res)

求导部分

就是根据导数的定义了,没啥好说的。感觉有更好的办法,发现了再说。

def __get_k_s(self, point_x):
        """
        获取切线方程
        :param point_x:切点坐标
        """
        for i in range(0, self.dimension):
            self.k += (i + 1) * (point_x ** i) * self.w[i]
        temp_x = self.__rise_x_dimension(np.array([point_x]).reshape(1, 1))
        self.s = np.dot(temp_x, self.w) + self.b - self.k * point_x

全部代码

import numpy as np
from sklearn.linear_model import LinearRegression
import pandas as pd
import matplotlib.pyplot as plt

# 处理数据相关的代码,和整体没啥关系
def y_filter(raw):
    res = raw[raw.iloc[:, 1] < 5e-7]
    return res


class TangentSlope:
    def __init__(self, x_data, y_data, dimension=4):
        # 原始数据
        self.x_raw_data = x_data
        self.y_raw_data = y_data
        # 用于训练的数据
        self.x_data = None
        # 多项式次数
        self.dimension = dimension
        # 拟合曲线解析式参数
        self.w = None
        self.b = None
        # 拟合曲线的y值
        self.y_hat = None
        # 切线解析式参数(斜率、截距)
        self.k = 0
        self.s = 0
        # 回归模型
        self.line_regression = LinearRegression()

    def __rise_x_dimension(self, x_data):
        """
        多项式升维
        :param n: 升维次数,默认四次
        """
        res = []
        temp_x_data = x_data.reshape(-1, 1)
        for i in range(1, self.dimension + 1):
            res.append(temp_x_data ** i)
        return np.hstack(res)

    def __get_k_s(self, point_x):
        """
        获取切线方程
        :param point_x:切点坐标
        """
        for i in range(0, self.dimension):
            self.k += (i + 1) * (point_x ** i) * self.w[i]
        temp_x = self.__rise_x_dimension(np.array([point_x]).reshape(1, 1))
        self.s = np.dot(temp_x, self.w) + self.b - self.k * point_x

    def fit(self, show_hat=False, show_raw=False):
        self.x_data = self.__rise_x_dimension(self.x_raw_data)
        self.line_regression.fit(X=self.x_data, y=self.y_raw_data)
        self.w = np.array(self.line_regression.coef_).reshape(-1, 1)
        self.b = self.line_regression.intercept_
        self.y_hat = np.dot(self.x_data, self.w) + self.b

        if show_hat:
            plt.plot(self.x_raw_data, self.y_hat, color='r')
        if show_raw:
            plt.scatter(self.x_raw_data, self.y_raw_data, color='b')
        if show_hat or show_raw:
            plt.show()

    def get_tangent(self, point_x, show_chart=True):
        """
        获取切线
        :param show_chart: 是否显示图表
        :param point_x:切点x坐标
        :return:
        """
        self.__get_k_s(point_x)
        print("切线斜率", self.k)
        if show_chart:
            plt.plot(self.x_raw_data, self.y_raw_data, color='b')
            tangent_y = self.k * self.x_raw_data + self.s
            tangent_y = tangent_y.reshape(-1, 1)
            plt.plot(self.x_raw_data, tangent_y, color="r")
            plt.show()


if __name__ == '__main__':
	
	#获取数据的x,y根据自己的实际业务
    #PATH = "../data/idvg_comp.csv"
    #raw_data = pd.read_csv(PATH)
    #data_1 = y_filter(raw_data[["x1", "y1"]])
    #x = np.log10(data_1["y1"].values)
    #y = data_1["x1"].values

    tangent_slope = TangentSlope(x, y, 2)
    tangent_slope.fit(False, True)
    tangent_slope.get_tangent(-7)

上一篇:Double—Ten alpha冲刺9


下一篇:使用jsdoc-to-markdown提前js文件的文档