方法分析
上一篇我们用随机暴力试探得到中的值,大约是34,但是这个暴力随机的方法好不好?
评估一个算法可以从几个方面考虑:
算法的结果准不准,不管白猫黑猫,抓到老鼠就好猫。
算法的训练train的速度快不快,性能好不好,一年只抓到一只老鼠的也不是好猫。
算法是不是可以被理解,如果自家的猫只要一念咒语就会出现一只死老鼠,这样的猫也太恐怖了。
第2点性能评估容易,只要在train函数加入时间输出就可以了,如果进一步考虑的话可以跟踪输出cost值的下降曲线,看它是否能比较快的到达最终结果,毕竟最后那些+0.1又-0.1来回震荡的时间没啥意义。
第3点可理解性也不难,毕竟算法是我们自己写的,绝大多数时候我们自己还是可以解释清楚猫是怎么抓老鼠的,比如我们这个暴力靠近的方法中间没有任何魔法。
第1点稍微麻烦些,怎么知道34这个结果是不是足够好?很简单,用用就知道,我们用这个34来预测些未知的房屋面积,看看是不是靠谱,有多靠谱就好了。
性能评估
我们准备用plotly把100次循环中cost下降的情况绘制出来,下面的代码执行绘图:
import plotly.offline as pyimport plotly.graph_objs as go py.init_notebook_mode() costData=go.Scatter( x=[n for n in range(100)], y=[0 for n in range(100)], ) costLayout = go.Layout( title='Cost下降曲线', autosize=False, width=500, height=500, xaxis=dict( autorange=False, range=(0, 100), dtick=10, showline=True, mirror='ticks', title='Loops', rangemode='tozero' ), yaxis=dict( autorange=True, showline=True, mirror='ticks', title='Costs', rangemode='tozero' ), ) costFig = go.FigureWidget([costData],costLayout) costFig train()
如果执行这个代码会出现一个图:
这是因为我们没有在train
函数中更新绘图数据。
修改上面的train
函数:
import timedef train(): start = time.time() lastA = 1 lastCost = 0 learnRate = 1 for i in range(100): newA = lastA + learnRate newCost = getCost(newA) if newCost > lastCost: learnRate = learnRate * (-1) lastCost = newCost lastA = newA #更新costFig dataY = list(costFig.data[0]['y']) dataY[i] = newCost costFig.data[0]['y'] = dataY end = time.time() print('>耗时:{}毫秒 '.format(end - start)) return newA
运行得到:
可以从图中看到33次左右之后cost价值就不再降低,也就是已经达到最优值34左右了,整个耗时4.34秒,但其中大部分时间(30多次之后)纯粹是在做无意义的震荡。
没有对比就没有伤害,初来乍到的我们目前还不好说这个算法的性能是否够好,但是,可以把这个作为一个参考,在此基础上进行优化。
精准度评估
我们的模型否好用?我们需要用事实来检测,我们的模型只使用了100个样本进行训练,我们可以拿另外100个样本让它来评估一下,给出推荐租金,然后我们再对比这个推荐租金和真实租金之间的差距,可以把它作为模型的精准度。
评估函数及执行
def evaluate(a): cost_li=[] for n in range(0,100): item=df.loc[n] area=float(item['area']) predict=a*area offset=float(item['money'])-predict cost_li.append(offset) return cost_li evalLi=evaluate(34.8)
对评估结果绘图。
import randomimport plotly.offline as pyimport plotly.graph_objs as go py.init_notebook_mode() evalData=go.Scatter( x=[n for n in range(100)], y=[evalLi[i] for i in range(len(evalLi))], ) evalLayout = go.Layout( title='预测评估', autosize=False, width=500, height=500, xaxis=dict( autorange=False, range=(0, 100), dtick=10, showline=True, mirror='ticks', title='Loops', rangemode='tozero' ), yaxis=dict( autorange=False, range=(-10000, 10000), showline=True, mirror='ticks', title='Offsets', ), ) evalFig = go.FigureWidget([evalData],evalLayout) evalFig print('平均偏差:{}'.format(sum(evalLi)/len(evalLi)))
对于100~200之间的样本预测,得到很大的偏差-512,差距很大。而且分布非常不均匀,很多偏差都超过正负1000,就是说预测租金和实际租金相差超过1000元,这个还是很糟糕的。
作者:zhyuzh3d
链接:https://www.jianshu.com/p/a7509e764f16