美文网首页
TensorFlow实战房价预测(新)

TensorFlow实战房价预测(新)

作者: oneoverzero | 来源:发表于2019-08-28 21:00 被阅读0次

    以下内容主要参考:
    https://www.bilibili.com/video/av54557524/?p=32

    import pandas as pd 
    import numpy as np 
    
    
    
    '''
    ##############################################################################################
    ########################                   分析数据                   ########################
    ##############################################################################################
    from mpl_toolkits import mplot3d
    
    # import pandas as pd 
    import matplotlib.pyplot as plt 
    
    df1 = pd.read_csv('data1.csv', names=['square', 'bedrooms', 'price'])
    
    
    # 数据归一化
    def normalize_feature(df):
        return df.apply(lambda column: (column - column.mean()) / column.std())
    
    df = normalize_feature(df1)
    
    fig = plt.figure()  # 先通过plt创建一张空的图片
    ax = plt.axes(projection='3d') # 告诉plt我们将要创建一个3d对象
                                   # 这一步会建立一个三维坐标系,但到目前为止这个图依旧是空的
    ax.set_xlabel('square')
    ax.set_ylabel('bedrooms')
    ax.set_zlabel('price')
    # scatter3D的前3个数据分别填充x,y,和z轴的数据
    # 参数c是为了给不同的点赋予不同的颜色深度,这里颜色深度具体为多少,我们设置其根据price \
    # 的大小来设定:price越大,颜色就越深
    # cmap指定要用什么颜色去绘制散点
    ax.scatter3D(df['square'], df['bedrooms'], df['price'], c=df['price'], cmap='Reds')
    plt.show()
    '''
    
    
    
    ##############################################################################################
    ########################                   处理数据                   ########################
    ##############################################################################################
    # 这一步的目的是为了得到能够输入到模型中的标准的数据格式
    
    def normalize_feature(df):
        return df.apply(lambda column: (column - column.mean()) / column.std())
    
    
    df = normalize_feature(pd.read_csv('data1.csv', names=['square', 'bedrooms', 'price']))
    
    # 创建一个n行1列全为1的数据框
    # len(df)返回df的长度(在这里为行数)
    # 这里是以字典的形式创建的,其中 ones 是对应的标题,value才是真正的值
    ones = pd.DataFrame({'ones': np.ones(len(df))})
    
    # 将全1数据合并到已有的数据框里
    df = pd.concat([ones, df], axis=1) # 这里是根据列合并
    # 如何根据axis判断是在哪一维合并:左手准则。大拇指指向自己,\
    # axis = 0, 1, 2分别对应x轴,y轴和z轴
    
    # 将DataFrame中的数据表示成矩阵的形式
    X_data = np.array(df[df.columns[0:3]]) # 注意区间是左闭右开的
    y_data = np.array(df[df.columns[-1]]).reshape(len(df), 1)
    
    # print(X_data.shape, type(X_data))
    # print(y_data.shape, type(y_data))
    '''
    输出:
    (47, 3) <class 'numpy.ndarray'>
    (47, 1) <class 'numpy.ndarray'>
    '''
    
    
    
    
    ##############################################################################################
    ########################                   创建模型                   ########################
    ##############################################################################################
    import tensorflow as tf 
    
    alpha = 0.01  # 设置学习率
    epoch = 500   # 设置总共要训练的轮数
    
    #-------------- 创建一个线性回归模型 --------------#
    # 首先定义模型中要用到的一些数据
    X = tf.placeholder(tf.float32, X_data.shape)   # 输入X,形状为[47, 3]
    y = tf.placeholder(tf.float32, y_data.shape)   # 输入Y,形状为[47, 1]
    # 权重变量W,形状为[3, 1]
    W = tf.get_variable('weights',(X_data.shape[1], 1), initializer=tf.constant_initializer())
    
    # 假设模型的表达式为:h(x) = w0 * x0 + w1 * x1 + w2 * x2,其中x0恒为1,用来计算偏置项
    # 将该表达式用矩阵乘法来表示
    y_pred = tf.matmul(X, W) # 得到的y_pred的形状为[47, 1]
    
    #------------- 接下来要考虑损失函数和梯度下降策略 -------------#
    # 这里损失函数用L2损失:
    # 注意tf.matmul(a, b, transpose_a=True)表示矩阵a的转置乘以矩阵b,在这里即为 [1, 47] x [47, 1]
    # 因此最终loss_op得到的是一个数
    loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred - y), transpose_a=True)
    # 这里采用随机梯度下降优化器,设置学习率为alpha
    opt = tf.train.GradientDescentOptimizer(learning_rate=alpha)
    
    # 定义每一步的训练目标:最小化loss函数
    train_op = opt.minimize(loss_op)
    
    
    
    
    ##############################################################################################
    ########################                     训练                     ########################
    ##############################################################################################
    # 创建会话
    with tf.Session() as sess:
        # 初始化全局变量
        sess.run(tf.global_variables_initializer())
        # 开始训练模型
        # 这里因为数据集比较小(只有47个样本),所以每次都用全部的数据进行训练
        for e in range(1, epoch + 1):
            sess.run(train_op, feed_dict={X: X_data, y: y_data})
            if e % 10 == 0:
                loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: y_data})
                log_str = "Epoch %d \t Loss=%.4g \t Model: y = %.4gx1 + %.4gx2 + %.4g"
                print(log_str % (e, loss, w[1], w[2], w[0]))
    

    输出结果为:

    Epoch 10         Loss=0.4116     Model: y = 0.0791x1 + 0.03948x2 + 3.353e-10
    Epoch 20         Loss=0.353      Model: y = 0.1489x1 + 0.07135x2 + -5.588e-11
    Epoch 30         Loss=0.3087     Model: y = 0.2107x1 + 0.09676x2 + 3.912e-10
    Epoch 40         Loss=0.2748     Model: y = 0.2655x1 + 0.1167x2 + -1.863e-11
    Epoch 50         Loss=0.2489     Model: y = 0.3142x1 + 0.1321x2 + 1.77e-10
    Epoch 60         Loss=0.2288     Model: y = 0.3576x1 + 0.1436x2 + -4.47e-10
    Epoch 70         Loss=0.2131     Model: y = 0.3965x1 + 0.1519x2 + -8.103e-10
    Epoch 80         Loss=0.2007     Model: y = 0.4313x1 + 0.1574x2 + -6.985e-10
    Epoch 90         Loss=0.1908     Model: y = 0.4626x1 + 0.1607x2 + -4.936e-10
    Epoch 100        Loss=0.1828     Model: y = 0.4909x1 + 0.1621x2 + -6.147e-10
    Epoch 110        Loss=0.1763     Model: y = 0.5165x1 + 0.162x2 + -7.87e-10
    Epoch 120        Loss=0.1709     Model: y = 0.5397x1 + 0.1606x2 + -5.821e-10
    Epoch 130        Loss=0.1664     Model: y = 0.5609x1 + 0.1581x2 + -9.08e-10
    Epoch 140        Loss=0.1625     Model: y = 0.5802x1 + 0.1549x2 + -9.965e-10
    Epoch 150        Loss=0.1592     Model: y = 0.5979x1 + 0.1509x2 + -9.756e-10
    Epoch 160        Loss=0.1564     Model: y = 0.6142x1 + 0.1465x2 + -4.144e-10
    Epoch 170        Loss=0.1539     Model: y = 0.6292x1 + 0.1416x2 + -1.001e-10
    Epoch 180        Loss=0.1518     Model: y = 0.643x1 + 0.1364x2 + -3.236e-10
    Epoch 190        Loss=0.1498     Model: y = 0.6559x1 + 0.131x2 + -6.286e-11
    Epoch 200        Loss=0.1481     Model: y = 0.6678x1 + 0.1255x2 + 2.119e-10
    Epoch 210        Loss=0.1466     Model: y = 0.6789x1 + 0.1199x2 + -1.956e-10
    Epoch 220        Loss=0.1452     Model: y = 0.6892x1 + 0.1142x2 + -1.758e-10
    Epoch 230        Loss=0.1439     Model: y = 0.6989x1 + 0.1085x2 + -4.307e-11
    Epoch 240        Loss=0.1428     Model: y = 0.708x1 + 0.1029x2 + 3.376e-10
    Epoch 250        Loss=0.1418     Model: y = 0.7165x1 + 0.09736x2 + 2.841e-10
    Epoch 260        Loss=0.1408     Model: y = 0.7245x1 + 0.09189x2 + 3.295e-10
    Epoch 270        Loss=0.14       Model: y = 0.732x1 + 0.08653x2 + -8.033e-11
    Epoch 280        Loss=0.1392     Model: y = 0.7391x1 + 0.08128x2 + 1.141e-10
    Epoch 290        Loss=0.1385     Model: y = 0.7458x1 + 0.07616x2 + 1.321e-10
    Epoch 300        Loss=0.1378     Model: y = 0.7522x1 + 0.07118x2 + 5.087e-10
    Epoch 310        Loss=0.1372     Model: y = 0.7582x1 + 0.06634x2 + 7.398e-10
    Epoch 320        Loss=0.1367     Model: y = 0.7639x1 + 0.06165x2 + 6.845e-10
    Epoch 330        Loss=0.1362     Model: y = 0.7693x1 + 0.0571x2 + 8.423e-10
    Epoch 340        Loss=0.1357     Model: y = 0.7744x1 + 0.0527x2 + 9.252e-10
    Epoch 350        Loss=0.1353     Model: y = 0.7793x1 + 0.04845x2 + 1.104e-09
    Epoch 360        Loss=0.1349     Model: y = 0.784x1 + 0.04435x2 + 1.145e-09
    Epoch 370        Loss=0.1346     Model: y = 0.7884x1 + 0.0404x2 + 1.631e-09
    Epoch 380        Loss=0.1343     Model: y = 0.7926x1 + 0.03658x2 + 1.446e-09
    Epoch 390        Loss=0.134      Model: y = 0.7966x1 + 0.03291x2 + 1.429e-09
    Epoch 400        Loss=0.1337     Model: y = 0.8004x1 + 0.02938x2 + 1.694e-09
    Epoch 410        Loss=0.1334     Model: y = 0.8041x1 + 0.02598x2 + 1.697e-09
    Epoch 420        Loss=0.1332     Model: y = 0.8076x1 + 0.02271x2 + 2.125e-09
    Epoch 430        Loss=0.133      Model: y = 0.8109x1 + 0.01957x2 + 2.292e-09
    Epoch 440        Loss=0.1328     Model: y = 0.8141x1 + 0.01655x2 + 2.913e-09
    Epoch 450        Loss=0.1326     Model: y = 0.8171x1 + 0.01366x2 + 3.412e-09
    Epoch 460        Loss=0.1325     Model: y = 0.82x1 + 0.01087x2 + 3.749e-09
    Epoch 470        Loss=0.1323     Model: y = 0.8228x1 + 0.008204x2 + 3.499e-09
    Epoch 480        Loss=0.1322     Model: y = 0.8254x1 + 0.005641x2 + 3.663e-09
    Epoch 490        Loss=0.1321     Model: y = 0.828x1 + 0.003183x2 + 4.2e-09
    Epoch 500        Loss=0.132      Model: y = 0.8304x1 + 0.0008239x2 + 4.138e-09
    

    TensorBoard可视化数据流图:

    首先创建数据流图需要的events文件:

    # 在Session会话中写入如下代码:(第9行)
    with tf.Session() as sess:
        # 初始化全局变量
        sess.run(tf.global_variables_initializer())
    
        #----------------------- 用Tensorboard进行可视化 ------------------------#
        # 首先要创建FileWriter实例,将其放置在当前目录下
        # summaty接收两个参数:保存目录及要保存的是哪个会话
        writer = tf.summary.FileWriter("./summary/linear-regression-1/", sess.graph)
        # 开始训练模型
        # 这里因为数据集比较小(只有47个样本),所以每次都用全部的数据进行训练
        for e in range(1, epoch + 1):
            sess.run(train_op, feed_dict={X: X_data, y: y_data})
            if e % 10 == 0:
                loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: y_data})
                log_str = "Epoch %d \t Loss=%.4g \t Model: y = %.4gx1 + %.4gx2 + %.4g"
                print(log_str % (e, loss, w[1], w[2], w[0]))
    
    # 记得最后要关闭writer
    # 这样程序执行完之后就会生成一个events文件,供TensorBoard使用
    writer.close()
    

    为数据流图加上名字作用域:

    ##############################################################################################
    ########################                   创建模型                   ########################
    ##############################################################################################
    import tensorflow as tf 
    
    alpha = 0.01  # 设置学习率
    epoch = 500   # 设置总共要训练的轮数
    
    #-------------- 创建一个线性回归模型 --------------#
    # 首先定义模型中要用到的一些数据
    with tf.name_scope('input'):
        X = tf.placeholder(tf.float32, X_data.shape, name='X')   # 输入X,形状为[47, 3]
        y = tf.placeholder(tf.float32, y_data.shape, name='y')   # 输入Y,形状为[47, 1]
    with tf.name_scope('hypothesis'):
        # 权重变量W,形状为[3, 1]
        W = tf.get_variable('weights',(X_data.shape[1], 1), initializer=tf.constant_initializer())
    
        # 假设模型的表达式为:h(x) = w0 * x0 + w1 * x1 + w2 * x2,其中x0恒为1,用来计算偏置项
        # 将该表达式用矩阵乘法来表示
        y_pred = tf.matmul(X, W, name='y_pred') # 得到的y_pred的形状为[47, 1]
    
    #------------- 接下来要考虑损失函数和梯度下降策略 -------------#
    # 这里损失函数用L2损失:
    # 注意tf.matmul(a, b, transpose_a=True)表示矩阵a的转置乘以矩阵b,在这里即为 [1, 47] x [47, 1]
    # 因此最终loss_op得到的是一个数
    with tf.name_scope('loss'):
        loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred - y), transpose_a=True)
    with tf.name_scope('train'):
        # 这里采用随机梯度下降优化器,设置学习率为alpha
        opt = tf.train.GradientDescentOptimizer(learning_rate=alpha)
    
        # 定义每一步的训练目标:最小化loss函数
        train_op = opt.minimize(loss_op)
    

    这样创建出来的数据流图就会显示我们定义的节点的名称,使数据流图更具有可读性。

    在当前目录生成events文件之后:

    • 如果是在Windows环境下,直接在vscode的控制台输入以下命令:

      tensorboard --logdir ./ --host localhost
      

      其中--logdir指定用当前目录,--host指定用localhost

      之后会生成一个链接,按Ctrl + 鼠标左键即可打开该链接,然后便可以看到生成的数据流图。

    使用Matplotlib可视化损失函数

    with tf.Session() as sess:
        # 初始化全局变量
        sess.run(tf.global_variables_initializer())
    
        #----------------------- 用Tensorboard进行可视化 ------------------------#
        # 首先要创建FileWriter实例,将其放置在当前目录下
        # summaty接收两个参数:保存目录及要保存的是哪个会话
        writer = tf.summary.FileWriter("./summary/linear-regression-1/", sess.graph)
    
        # 记录损失值,以方便可视化损失函数
        loss_data = []
    
        # 开始训练模型
        # 这里因为数据集比较小(只有47个样本),所以每次都用全部的数据进行训练
        for e in range(1, epoch + 1):
            _, loss, w = sess.run([train_op, loss_op, W], feed_dict={X: X_data, y: y_data})
            # 记录每一轮损失值变化情况
            loss_data.append(float(loss))
            if e % 10 == 0:
                loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: y_data})
                log_str = "Epoch %d \t Loss=%.4g \t Model: y = %.4gx1 + %.4gx2 + %.4g"
                print(log_str % (e, loss, w[1], w[2], w[0]))
    
    # 记得最后要关闭writer
    # 这样程序执行完之后就会生成一个events文件,供TensorBoard使用
    writer.close()
    
    import matplotlib.pyplot as plt 
    import seaborn as sns 
    sns.set(context='notebook', style='whitegrid', palette='dark')
    
    ax = sns.lineplot(x='epoch', y='loss', data=pd.DataFrame({'loss': loss_data, 'epoch': np.arange(epoch)}))
    ax.set_xlabel('epoch')
    ax.set_ylabel('loss')
    plt.show()
    

    用这种方法有一个很大的缺点:首先需要把所有要可视化的量都记录下来,当要可视化的变量非常多时,这种方法会非常麻烦。

    附:数据集的链接及提取码
    链接:https://pan.baidu.com/s/11fHYCGZ30EVoCgINUxBL6g
    提取码:ie95

    相关文章

      网友评论

          本文标题:TensorFlow实战房价预测(新)

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