美文网首页
0#01 房价的思考

0#01 房价的思考

作者: dogo_L1L | 来源:发表于2018-07-22 15:04 被阅读0次

    0x00 起因

    看了吴恩达大佬的视频,有点似懂非懂的感觉,于是网上找了几篇实现的过程进行解析,加深理解。
    这个是第一篇也是,房价的影响因素。

    0x01 数据

    数据来源:
    来源prices.txt
    房子面积,价格

    1534,314900
    1427,198999
    1380,212000
    1494,242500
    1940,239999
    2000,347000
    1890,329999
    4478,699900
    1268,259900
    2300,449900
    1320,299900
    1236,199900
    2609,499998
    3031,599000
    1767,252900
    1888,255000
    1604,242900
    1962,259900
    3890,573900
    1100,249900
    1458,464500
    2526,469000
    2200,475000
    2637,299900
    1839,349900
    1000,169900
    2040,314900
    3137,579900
    1811,285900
    1437,249900
    1239,229900
    2132,345000
    4215,549000
    2162,287000
    1664,368500
    2238,329900
    2567,314000
    1200,299000
    852,179900
    1852,299900
    1203,239500
    

    将以上数据保存文件为place.csv
    保存在/home/lee/ml/1.hv/place.csv

    0x02 思路

    1. 读取数据
    2. 将房子面积进行标准化
    3. 进行图形的散点显示
    4. 训练数据(训练3类,n=1,4,10阶拟合)
      5.将散点和拟合曲线进行显示

    0x03 训练数据

    最重要的一步,单独分析。

    1. 我们训练的是
      f(x|p;n)=p0x^n+p1x^n-1+...+pn
      (p为系数,n为指数,m为样本数量)
    2. 训练的方式:
      使代价函数最下
      L(p;n)=1/2 ∑(f(x|p;n)-y)^2


      cost.png

    0x04 人生苦短,我用python

    numpy库

    假设x=numpy.array([1,2,3,4,5,6,7,8,9])

    1. array.mean()

    求取平均值
    >>> x.mean()
    5.0

    2. array.std()

    求取标准差
    >>> x.std()
    2.581988897471611

    3. numpy.polyfit(x,y,deg)

    作用:训练函数
    参数:
    x:输入()
    y:实际的输出
    deg:多项式的阶数
    返回:
    p:使上述代价函数最小的参数p

    4. numpy.polyval(p,x)

    作用:将p和x带入多项式子计算结果
    参数:
    p:多项式的系数
    x:输入的参数x
    返回:
    y:多项式的输出

    >>> p=[1,2,3,4]
    >>> numpy.polyval(p,2)
    26
    12^3+222+3*21+4=26

    matplotlib.pythonplot库

    图像显示的库,有点类似matlab的操作
    import matplotlib.pyplot as plt

    1. plt.figure()

    创建窗口类

    2. plt.scatter(x,y,s=20,c='b')

    介绍:散点图,参数很多这个几个比较常用。
    参数:
    x:x轴坐标
    y:y轴坐标
    s:点的大小
    c:颜色
    >>> x=[1,2,3,4,5]
    >>> y=[1,2,3,4,5]
    >>> plt.scatter(x,y,s=20,c='r')
    >>>plt.show()

    show.png

    3. plt.show()

    将图形显示出来

    4. plt.xlim(a,b)

    x轴的范围
    a:x轴左端
    b:x轴右端
    plt.ylim(a,b)同理

    5. plt.legend()

    显示使曲线对应的标签

    6. plt.plot(x,y,label=)

    画出(x,y)点构成的曲线
    x:x轴坐标
    y:y轴坐标
    label:标签
    >>> pi=3.14159
    >>> x=[xx0.01 for xx in range(0,100)]
    >>> y= [np.sin(xx
    2*pi) for xx in x]
    >>> plt.plot(x,y,label="sin")
    >>> plt.show()

    sin.png

    0x05 具体代码

    导入要用的库

    import numpy as np
    import matplotlib.pyplot as plt
    

    数据导入

    x,y=[],[]
    # x为输入数据,y为目标数据
    for sample in open("/home/lee/Desktop/ml/1.hv/place.csv",'r'):
        area,value = sample.split(",")
        x.append(float(area))
        y.append(float(value))
    x,y = np.array(x),np.array(y)
    

    得到下面的内容

    >>> x
    array([2104., 1600., 2400., 1416., 3000., 1985., 1534., 1427., 1380.,
           1494., 1940., 2000., 1890., 4478., 1268., 2300., 1320., 1236.,
           2609., 3031., 1767., 1888., 1604., 1962., 3890., 1100., 1458.,
           2526., 2200., 2637., 1839., 1000., 2040., 3137., 1811., 1437.,
           1239., 2132., 4215., 2162., 1664., 2238., 2567., 1200.,  852.,
           1852., 1203.])
    >>> y
    array([399900., 329900., 369000., 232000., 539900., 299900., 314900.,
           198999., 212000., 242500., 239999., 347000., 329999., 699900.,
           259900., 449900., 299900., 199900., 499998., 599000., 252900.,
           255000., 242900., 259900., 573900., 249900., 464500., 469000.,
           475000., 299900., 349900., 169900., 314900., 579900., 285900.,
           249900., 229900., 345000., 549000., 287000., 368500., 329900.,
           314000., 299000., 179900., 299900., 239500.])
    
    

    对x进行标准化

    利用公式:x=(x-x.平均数)/x.方差

    x=(x-x.mean())/x.std()
    

    标准化后

    >>> x
    array([ 1.31415422e-01, -5.09640698e-01,  5.07908699e-01, -7.43677059e-01,
            1.27107075e+00, -1.99450507e-02, -5.93588523e-01, -7.29685755e-01,
           -7.89466782e-01, -6.44465993e-01, -7.71822042e-02, -8.65999486e-04,
           -1.40779041e-01,  3.15099326e+00, -9.31923697e-01,  3.80715024e-01,
           -8.65782986e-01, -9.72625673e-01,  7.73743478e-01,  1.31050078e+00,
           -2.97227261e-01, -1.43322915e-01, -5.04552951e-01, -4.91995958e-02,
            2.40309445e+00, -1.14560907e+00, -6.90255715e-01,  6.68172729e-01,
            2.53521350e-01,  8.09357707e-01, -2.05647815e-01, -1.27280274e+00,
            5.00114703e-02,  1.44532608e+00, -2.41262044e-01, -7.16966387e-01,
           -9.68809863e-01,  1.67029651e-01,  2.81647389e+00,  2.05187753e-01,
           -4.28236746e-01,  3.01854946e-01,  7.20322135e-01, -1.01841540e+00,
           -1.46104938e+00, -1.89112638e-01, -1.01459959e+00])
    

    将原始数据进行显示

    plt.figure()
    plt.scatter(x,y,c='g',s=6)
    plt.show()
    
    prices.png

    训练

    # 在(-2,4)区间上取100个点,等差
    x0=np.linspace(-2,4,100)
    # 设置3个阶数
    test_set = (1,4,10)
    for d in test_set:
        p=np.polyfit(x,y,d)
        cost=(0.5*((np.polyval(p,x)-y)**2).sum())        #计算代价函数  
        print(d,":",cost)
        plt.plot(x0,np.polyval(p,x0),label="degree={}".format(d))        #描点
    

    显示:

    1 : 96732238800.35297
    
    4 : 94112406641.67743
    
    10 : 75874846680.09282
    
    final.png

    很明显
    degree=10的时候,代价函数最小,但是图像可以看出defree=10已经过拟合了。

    0x06 完整代码

    import numpy as np
    import matplotlib.pyplot as plt
    ##可视化输入数据
    x,y=[],[]
    
    for sample in open("/home/lee/Desktop/ml/1.hv/place.csv",'r'):
        area,value = sample.split(",")
        print(area,value)
        x.append(float(area))
        y.append(float(value))
    
    
    x,y = np.array(x),np.array(y)
    
    x=(x-x.mean())/x.std()
    
    plt.figure()
    plt.scatter(x,y,c='g',s=6)
    plt.show()
    ## 取点训练
    
    x0=np.linspace(-2,4,100)
    ## 多项式子的次数
    # 模型预测函数
    def get_model(deg):
        return lambda input_x = x0:np.polyval(np.polyfit(x,y,deg),input_x)
    
    #代价函数
    def get_cost(deg,input_x,input_y):
        return 0.5*((get_model(deg)(input_x)-input_y)**2).sum()
    
    test_set = (1,4,10)
    
    for d in test_set:
        print(get_cost(d,x,y))
    
    ##96732238800.35292
    #94112406641.67743
    #75874846680.0928
    
    plt.scatter(x,y,c='g',s=20)
    for d in test_set:
        plt.plot(x0,get_model(d)(),label="degree={}".format(d))
    
    plt.xlim(-2,4)
    plt.ylim(1e5,8e5)
    plt.legend()
    plt.show()
    

    相关文章

      网友评论

          本文标题:0#01 房价的思考

          本文链接:https://www.haomeiwen.com/subject/nxjlmftx.html