pizza预测问题:
pizza店又要推出新款pizza了,该怎么更加合理的定义其价格呢?
以下是pizza的现有数据:
pizza直径(cm):6, 8, 10, 14 , 18
对应价格 (元) :7, 9, 13, 17.5, 18
新款的pizza直径(cm)为21,欲求价格???
说明:pizza店中有很多不同size的pizza,随着pizza的直径越来越大,价格肯定越来越高,显然目标函数是线性函数。那么就可以将已有的数据作为训练数据。通过训练数据优化出一条最优曲线,使pizza店中推出新款pizza时,更友好的根据其大小预测其价格。
(本文中只根据相同配料的一类pizza作为数据。因为在现实生活中,pizza的大小相同,如果配料不同,那肯定价格也不一致。所以,本文只对一类pizza的不同大小以及对应价格作为训练数据。)
具体代码如下:
import numpy as np
import matplotlib.pyplot as plt
def targetFunction(W,X,Y): #目标函数
w1,w0 = W #w1作为斜率 , w0作为截距
return np.sum((w0 + w1 * X - Y)**2)/(2*len(X))
def gradientFunction(W,X,Y): #梯度函数(主要针对w1,w0求偏导)
w1,w0 = W
w0_grad = np.sum(w0 + w1*X - Y)/len(X)
w1_grad = X.dot(w0 + w1*X - Y)/len(X)
return np.array([w1_grad,w0_grad])
def batch_gradient_distance(targetFunc,gradientFunc,init_W,X,Y,learning_rate = 0.01,tolerance = 0.00001):
'''
:param targetFunc: 目标函数
:param gradientFunc: 梯度函数:目标函数的偏导
:param init_W: 包括w1和w0的数组
:param X: pizza直径样本数据
:param Y: pizza价格样本数据
:param learning_rate: 步近速率
:param tolerance: 极限值
:return:
'''
W = init_W
counts = 0 #初始化循环次数
target_value = targetFunc(W,X,Y)
while counts<5000:
gradient = gradientFunc(W,X,Y)
next_W = W - gradient * learning_rate #相当于W = W- ΔW * α
next_target_value = targetFunc(next_W,X,Y)
if abs(next_target_value - target_value) < tolerance:
print("此结果经过了",counts,"次循环")
return next_W #当新旧目标值相减小于极限值时,认为此时的截距和斜率最优,结束循环
else:
W,target_value = next_W,next_target_value #不满足,则赋予当前最新值继续计算
counts += 1
x = np.array([6,8,10,14,18])
y = np.array([7,9,13,17.5,18])
np.random.seed(0) #保证每次运行时,随机出来的结果一致。
init_W = np.array([np.random.random(),np.random.random()]) #给定两个随机的w0,w1的值
w1,w0 = batch_gradient_distance(targetFunction,gradientFunction,init_W,x,y)
print("截距为:",w0,"斜率为:",w1)
def initPlot(): #如下绘图
plt.figure()
plt.title("Volume Gradient Decline")
plt.xlabel("X")
plt.ylabel("Y")
plt.axis([0,25,0,25])
plt.grid(True)
return plt
plt = initPlot()
plt.plot(x,y,"k.")
plt.plot(x,w0+w1*x,"g-")
new_x = np.array([21]) #当pizza直径为21cm时
predict_y = w0 + w1 * new_x #预测其价格
print("当pizza直径为",new_x[0],"(cm)时","其价格为:",predict_y[0],"元")
plt.plot(new_x,predict_y,"k.",c="red")
plt.show()
如下图所示:
由此,可得到最优曲线的截距和斜率,即可计算出当pizza大小为21cm时,其最合理的定价为 22.62元。