机器学习需要知道的二次函数

二次函数的基础数学

解一元二次方程式的根

ax^{2}+bx+c=0

x=\frac{-b\pm \sqrt{b^{2}-4ac}}{2a}

如果b^{2}-4ac> 0        有2个实数根

如果b^{2}-4ac=0        有1个实数根

如果b^{2}-4ac< 0        没有实数根 

解下例一元二次方程式:

x^{2}-2x-8=0

代码如下:

a = 1
b = -2
c = -8

r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)
print("r1 = %6.4f,  r2 = %6.4f" % (r1, r2))

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
r1 = 4.0000,  r2 = -2.0000

[Done] exited with code=0 in 0.498 seconds

重新设计,使用sympy。

代码如下:

from sympy import *

x = Symbol('x')
f = Symbol('f')
f = x**2 - 2*x - 8
root = solve(f)
print(root)

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
[-2, 4]

[Done] exited with code=0 in 2.457 seconds

使用sympy模块解下列一元二次方程式:

f(x)=3(x-2)^{2}-2

代码如下:

from sympy import *

x = Symbol('x')
f = Symbol('f')
f = 3*(x-2)**2 - 2
root = solve(f)
print(root)

运行结果如下: 

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
[2 - sqrt(6)/3, sqrt(6)/3 + 2]

[Done] exited with code=0 in 2.025 seconds

绘制一元二次方程式的图形

在一元二次方程式中,可以使用抛物线绘制此方程式图形:

y=f(x)=ax^{2}+bx+c

如果a>0,代表函数抛物线开口向上。

如果a<0,代表函数曲线开口向下。

绘制y=3x^{2}-12x+10的二次函数图形,同时标记和输出两个根:

代码如下:(代码没看懂)

import matplotlib.pyplot as plt
import numpy as np

def f(x):
    ''' 求解方程式 '''
    return (3*x**2 - 12*x + 10)

a = 3
b = -12
c = 10
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)         # r1
r1_y = f(r1)                                # f(r1)
plt.text(r1-0.2, r1_y+0.3, '('+str(round(r1,2))+','+str(0)+')')         
plt.plot(r1, r1_y, '-o')                    # 标记
print('root1 = ', r1)                       # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)         # r2
r2_y = f(r2)                                # f(r2)
plt.text(r2-0.2, r2_y+0.3, '('+str(round(r2,2))+','+str(0)+')') 
plt.plot(r2, r2_y, '-o')                    # 标记
print('root2 = ', r2)                       # print(r2)

# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = 3*x**2 - 12*x + 10
plt.plot(x, y)
plt.show()

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 =  2.8164965809277263
root2 =  1.183503419072274

[Done] exited with code=0 in 17.871 seconds

绘制f(x)=-3x^{2}+12x-9的函数图形,同时标记和输出 两个根:

代码如下:

import matplotlib.pyplot as plt
import numpy as np

def f(x):
    ''' 求解方程式 '''
    return (-3*x**2 + 12*x - 9)

a = -3
b = 12
c = -9
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)         # r1
r1_y = f(r1)                                # f(r1)
plt.text(r1-0.2, r1_y+0.3, '('+str(round(r1,2))+','+str(0)+')')         
plt.plot(r1, r1_y, '-o')                    # 标记
print('root1 = ', r1)                       # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)         # r2
r2_y = f(r2)                                # f(r2)
plt.text(r2-0.3, r2_y+0.3, '('+str(round(r2,2))+','+str(0)+')') 
plt.plot(r2, r2_y, '-o')                    # 标记
print('root2 = ', r2)                       # print(r2)

# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = -3*x**2 + 12*x - 9
plt.plot(x, y)
plt.show()

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 =  1.0
root2 =  3.0

[Done] exited with code=0 in 24.578 seconds

一元二次方程式的最小值与最大值

当a>0时,因为抛物线开口向上,可以找到此抛物线函数f(x)的最小值。当a<0时,因为抛物线开口下向,可以找到此抛物线函数f(x)的最大值。

对于二次函数y=ax^{2}+bx+c,不论是最大值或是最小值,坐标公式皆是:(-\frac{b}{2a},\frac{4ac-b^{2}}{4a})

scipy模块内的optimize模块内有minimize_scalar()方法可以找出f(x)函数的最小值,也可以由此导入函数找出最小值的坐标(x,y)。

使用scipy模块前需要安装此模块:

pip install scipy

然后程序前方需要导入此模块:

from scipy.optimeze import minize_scalar

语法如下:

minimize_scalar(fun)

上述fun是一元二次方程式。

增加列出最小值的坐标(x,y),下列是此二次函数:

y=3x^{2}-12x+10

由于a是3大于0,可以得到最小值。

import matplotlib.pyplot as plt
from scipy.optimize import minimize_scalar
import numpy as np

def f(x):
    ''' 求解方程式 '''
    return (3*x**2 - 12*x + 10)

a = 3
b = -12
c = 10
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)         # r1
r1_y = f(r1)                                # f(r1)
plt.text(r1+0.1, r1_y-0.2, '('+str(round(r1,2))+','+str(0)+')')         
plt.plot(r1, r1_y, '-o')                    # 标记
print('root1 = ', r1)                       # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)         # r2
r2_y = f(r2)                                # f(r2)
plt.text(r2-0.6, r2_y-0.2, '('+str(round(r2,2))+','+str(0)+')') 
plt.plot(r2, r2_y, '-o')                    # 标记
print('root2 = ', r2)                       # print(r2)

# 计算最小值
r = minimize_scalar(f)
print("当x是 %4.2f 时, 有函数最小值 %4.2f" % (r.x, f(r.x)))
plt.text(r.x-0.25, f(r.x)+0.3, '('+str(round(r.x,2))+','+str(round(r.x,2))+')') 
plt.plot(r.x, f(r.x), '-o')                 # 标记

# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = 3*x**2 - 12*x + 10
plt.plot(x, y, color='b')
plt.show()

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 =  2.8164965809277263
root2 =  1.183503419072274
当x是 2.00 时, 有函数最小值 -2.00

[Done] exited with code=0 in 19.479 seconds

增加列出最大值的坐标(x,y),下列是此二次函数:

f(x)=-3x^{2}+12x-9

import matplotlib.pyplot as plt
from scipy.optimize import minimize_scalar
import numpy as np

def fmax(x):
    ''' 计算最大值 '''
    return (-(-3*x**2 + 12*x - 9))

def f(x):
    ''' 求解方程式 '''
    return (-3*x**2 + 12*x - 9)

a = -3
b = 12
c = -9
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)         # r1
r1_y = f(r1)                                # f(r1)
plt.text(r1+0.1, r1_y+-0.2, '('+str(round(r1,2))+','+str(0)+')')         
plt.plot(r1, r1_y, '-o')                    # 标记
print('root1 = ', r1)                       # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)         # r2
r2_y = f(r2)                                # f(r2)
plt.text(r2-0.5, r2_y-0.2, '('+str(round(r2,2))+','+str(0)+')') 
plt.plot(r2, r2_y, '-o')                    # 标记
print('root2 = ', r2)                       # print(r2)

# 计算最大值
r = minimize_scalar(fmax)
print("当x是 %4.2f 时, 有函数最大值 %4.2f" % (r.x, f(r.x)))
plt.text(r.x-0.25, f(r.x)-0.7, '('+str(round(r.x,2))+','+str(round(r.x,2))+')') 
plt.plot(r.x, f(r.x), '-o')                 # 标记

# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = -3*x**2 + 12*x - 9
plt.plot(x, y, color='b')
plt.show()

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 =  1.0
root2 =  3.0
当x是 2.00 时, 有函数最大值 3.00

[Done] exited with code=0 in 9.859 seconds

二次函数参数整理

对于下列二次函数:

y=f(x)=ax^{2}+bx+c

参数a:

参数a决定抛物线的开口向上(a>0)或是向下(a<0).

参数a和b:

参数a和参数b会影响对称轴的位置,对称轴公式如下:

x=-b/2a

如果b=0,抛物线的对称轴是y轴。

如果a和b是同号,对称轴在y轴左边。

如果a和b是异号,对称轴在y轴右边。

参数c:

参数c可以决定抛物线和y轴的交叉点,如果x为0,表示y=c。

三次函数的图形特征

所谓的三次函数,是指x的最高项是三次方,基本概念如下:

ax^{3}+bx^{2}+cx+d=0                #a不等于0

绘制x在-1.0~1.0的下列函数:

f(x)=x^3-x

代码如下:

import matplotlib.pyplot as plt
import numpy as np

# 绘制此函数图形
x = np.linspace(-1, 1, 100)
y = x**3 - x
plt.plot(x, y)
plt.grid()
plt.show()

运行结果如下:

绘制x在-2.0~2.0的同上函数:

代码如下:

import matplotlib.pyplot as plt
import numpy as np

# 绘制此函数图形
x = np.linspace(-2, 2, 100)
y = x**3 - x
plt.plot(x, y)
plt.grid()
plt.show()

运行结果如下:

从一次到二次函数

呈现好的变化

真实业绩,在线性方程式预估业绩的上面

呈现坏的变化

真实业绩,在线性方程式预估业绩的下面。

认识二次函数的系数

在一次线性函数y=ax+b中,a是斜率,b是截距,二次函数可参考下列公式:

y=ax^2+bx+c

a、b、c就不称斜率或截距,而是直接称系数,a是x的二次方系数,b是x的一次方系数,c是常数。

ax^2呈现的是正向变化,表示 a>0,同时随着x的值增加,ax^2的值也会增加。呈现好的变化。

ax^2呈现的是负向变化,表示a<0,同时随着x的值增加,将加大负值。呈现坏的变化。

使用3个点求解二次函数

y=ax^2+bx+c

x代表拜访次数,以100为单位,y是实际业绩,得到下列3个二次方程式:

500=a+b+c                #第100次        x=1

1000=4a+2b+c        #第200次        x=2

2000=9a+3b+c        #第300次        x=3

由于有c,分别将第200次和第300次公式减去第100次公式,得到下列联立方程式:

500=3a+b                #第200次公式减去第100次公式

1500=8a+2b                #第300次公式减去第100次公式

简化后得到下列联立方程式:

500=3a+b                #公式一

750=4a+b                #公式二

a=250,b=-250,c=500

y=f(x)=250x^2-250x+500

求解上述联立方程式。

代码如下:

import matplotlib.pyplot as plt
from sympy import Symbol, solve
import numpy as np

a = Symbol('a')                         # 定义公式中使用的变量
b = Symbol('b')                         # 定义公式中使用的变量
c = Symbol('c')                         # 定义公式中使用的变量

eq1 = a + b + c - 500                   # 第100次公式
eq2 = 4*a + 2*b + c - 1000              # 第200次公式
eq3 = 9*a + 3*b + c - 2000              # 第300次公式
ans = solve((eq1, eq2, eq3))
print('a = {}'.format(ans[a]))
print('b = {}'.format(ans[b]))
print('c = {}'.format(ans[c]))

运行结果如下:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
a = 250
b = -250
c = 500

[Done] exited with code=0 in 5.451 seconds

y=f(x)=250x^2-250x+500

先使用相同的数据找出此二次函数,然后绘制此二次函数图形,同时将先前拜访次数所创的业绩在图上标记出来,再用所计算的二次函数求解当拜访客户400次时,所产生的业绩,同时在坐标图内标记此坐标。

代码如下:

import matplotlib.pyplot as plt
from sympy import Symbol, solve
import numpy as np

a = Symbol('a')                         # 定义公式中使用的变量
b = Symbol('b')                         # 定义公式中使用的变量
c = Symbol('c')                         # 定义公式中使用的变量
eq1 = a + b + c - 500                   # 第100次公式
eq2 = 4*a + 2*b + c - 1000              # 第200次公式
eq3 = 9*a + 3*b + c - 2000              # 第300次公式
ans = solve((eq1, eq2, eq3))
print('a = {}'.format(ans[a]))
print('b = {}'.format(ans[b]))
print('c = {}'.format(ans[c]))

x = np.linspace(0, 5, 50)
y = [(ans[a]*y**2 + ans[b]*y + ans[c]) for y in x]
plt.plot(x, y)                          # 绘二次函数

x4 = 4                                  # 第400次
y4 = ans[a]*x4**2 + ans[b]*x4 + ans[c]  # 第400次的y值
plt.plot(x4, y4, '-o')                  # 绘交叉点
plt.text(x4-0.7, y4-50, '('+str(x4)+','+str(y4)+')')

plt.plot(1, 500, '-x', color='b')       # 绘100次业绩点
plt.text(1-0.7, 500-50, '('+str(1)+','+str(500)+')')
plt.plot(2, 1000, '-x', color='b')      # 绘200次业绩点
plt.text(2-0.7, 1000-50, '('+str(2)+','+str(1000)+')')
plt.plot(3, 2000, '-x', color='b')      # 绘300次业绩点
plt.text(3-0.7, 2000-50, '('+str(3)+','+str(2000)+')')

plt.xlabel("Times(unit=100)")
plt.ylabel("Revenue")
plt.grid()                              # 加网格线
plt.show()

运行结果:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
a = 250
b = -250
c = 500

[Done] exited with code=0 in 18.406 seconds

250x^2-250x+500=3000

250x^2-250x+500-3000=0

250x^2-250x-2500=0

x^2-x-10=0

计算要达到3000张考卷销售,需要多少拜访次数,在这个程序设计中因为拜访次数必须是正值,所以负数根将舍去。

代码如下:

a = 1
b = -1
c = -10

r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)
if r1 > 0:
    times = int(r1 * 100)
else:
    if r2 > 0:
        times = int(r2 * 100)
print("拜访次数 = {}".format(times))

运行结果:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
拜访次数 = 370

[Done] exited with code=0 in 0.338 seconds

二次函数的配方法

二次函数的一般式:y=ax^2+bx+c

二次函数的标准式:y=a(x-h)^2+k

在标准式中,可以清楚得到抛物线的顶点坐标是(h,k)。

这个概念在机器学习过程中使用最小平方法计算最小误差时会使用。

配方法是将两次函数从一般式推导到标准式。

y=ax^2+bx+c

y=a(x^2+\frac{b}{a}x)+c

y=a(x^2+\frac{b}{a}x+\frac{b^2}{4a^2})+c-\frac{b^2}{4a}

y=a(x+\frac{b}{2a})^2+\frac{4ac-b^2}{4a}

h=-\frac{b}{2a}        k=\frac{4ac-b^2}{4a}

从标准式计算二次函数的最大值 

二次函数的标准式概念如下:

y=a(x-h)^2+k

当a<0时抛物线开口向下,因为(x-h)^2\geqslant 0,所以可以得到:

a(x-h)^2\leqslant 0

当x=h时,会造成:

a(x-h)^2=0

这时可以得到y=k是最大值,因为:

y=a(x-h)^2+k

y=0+k

y=k

所以当二次函数存在最大值时,最大值的坐标如下:

(-\frac{b}{2a},\frac{4ac-b^2}{4a})

从标准式计算二次函数的最小值

 二次函数的标准式概念如下:

y=a(x-h)^2+k

当a>0时抛物线开口向上,因为(x-h)^2\geqslant 0,所以可以得到:

a(x-h)^2\geqslant 0

当x=h时,会造成:

a(x-h)^2=0

这时可以得到y=k是最小值,因为:

y=a(x-h)^2+k

y=0+k

y=k

所以当二次函数存在最小值时,最小值的坐标如下:

(-\frac{b}{2a},\frac{4ac-b^2}{4a})

二次函数与解答区间

公司内部的统计信息:

每月次数增加业绩金额/万元
110
218
319

假设营销次数是x,增加业绩单位是万元、金额是y。将上述数据代入二次函数y=ax^2+bx+c可以得到下列联立方程式:

a+b+c=10

4a+2b+c=18

9a+3b+c=19

经过计算可以得到下列a、b、c的值:

a=-3.5

b=18.5

c=-5

所以可以得到营销的二次函数:

y=-3.5x^2+18.5x-5

二次函数的标准式:

y=-3(x-2.6)^2+19.4

绘制上述数据的图表,同时使用'x'标记此原始数据,并使用圆点标记极大值。

import matplotlib.pyplot as plt
from sympy import Symbol, solve
import numpy as np

a = Symbol('a')                         # 定义公式中使用的变量
b = Symbol('b')                         # 定义公式中使用的变量
c = Symbol('c')                         # 定义公式中使用的变量
eq1 = a + b + c - 10                    # 第1次公式
eq2 = 4*a + 2*b + c - 18                # 第2次公式
eq3 = 9*a + 3*b + c - 19                # 第3次公式
ans = solve((eq1, eq2, eq3))
print('a = {}'.format(ans[a]))
print('b = {}'.format(ans[b]))
print('c = {}'.format(ans[c]))

x = np.linspace(0, 4, 50)
y = [(ans[a]*y**2 + ans[b]*y + ans[c]) for y in x]
plt.plot(x, y)                          # 绘二次函数

plt.plot(1, 10, '-x', color='b')        # 绘1次业绩点
plt.plot(2, 18, '-x', color='b')        # 绘2次业绩点
plt.plot(3, 19, '-x', color='b')        # 绘3次业绩点

h = (-1 * ans[b] / (2 * ans[a]))
k = (4 * ans[a] * ans[c] - (ans[b] ** 2)) / (4 * ans[a])
plt.plot(h, k, '-o', color='b')         # 绘最大值坐标
h = round(float(h), 1)
k = round(float(k), 1)
plt.text(h-0.25, k-1.5, '('+str(h)+','+str(k)+')')

plt.xlabel("Times")
plt.ylabel("Performance")
plt.grid()                              # 加网格线
plt.show()

执行结果:

假设改为想要达到销售增幅15万元(含)以上。

y值概率:y\geqslant 15

y=-3.5x^2+18.5x-5

y是15,得到下列二次函数:

15=-3.5x^{2}+18.5x-5

可以得到下列推导结果:

-3.5x^2+18.5x-20=0

计算公式-3.5x^2+18.5x-20=0的值。

from sympy import *

x = Symbol('x')
eq = -3.5*x**2 + 18.5*x - 20
ans = solve(eq)
x1 = round(ans[0], 1)
x2 = round(ans[1], 1)
print('x1 = {}'.format(x1))
print('x2 = {}'.format(x2))

执行结果:

[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
x1 = 1.5
x2 = 3.8

[Done] exited with code=0 in 1.647 seconds

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值