Tensorflow多元线性回归之波士顿房价预测

我没有找到波士顿的数据集
找到了另一个房价的数据集
另一个房价数据集
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看出来特征是二维数组,而标签是一维数组
可以看出来特征是二维数组,而标签是一维数组
可以看出来特征是二维数组,而标签是一维数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
大致意思:
一道菜可能需要1000克水,5克盐
所以水前面的系数会小,盐前面的系数会大,我现在考虑的是线性回归,即多个特征的线性组合
为了避免这种情况
我们可以使用归一化
即将原始值限制在0到1之间
1000克水去掉5克,可能没什么影响
但是5克盐去掉5克,就不行了
所以要从自身比例出发,而不是绝对值,故而归一化

在这里插入图片描述
在这里插入图片描述
上面的式子错了
大错特错
举个例子
最小值2,最大值 3
中间值2.5
2.5/(3-2)=2.5
正确的应该是分子也要减去min

没有归一化之前这些参数都是nan

在这里插入图片描述
在这里插入图片描述
由上图可知只训练一个样本就发生了这么大的变化,是怎么做到的??
我之前以为线性回归的导数就只是系数了,所以不理解这么大 的变化
那是一元是这样,多元就不一样了
遇事要动笔,光想没用
在这里插入图片描述
输入数据归一化之后都是在0到1之间
标签数据是在100000到1600000之间
这就是为什么损失函数可以这么大
我是这么想的
因为假设的模型是多元线性回归
所以是y=w1x1+w2x2+…+b的形式
现在归一化之后xi都是纯小数,而w是标准差为0.1的正太分布的初始值,所以也是个不大的值,个位数
这样的话求均方误差肯定很大,都上亿了

所以我把标准数据除以了100000
在这里插入图片描述

问题:
训练的时候用的归一化,那测试单个样本的时候怎么用归一化
个人猜测:
如果用的是最大最小值归一化
比如图像
最大值255最小值0,这样的化还可以
如果是均值平均化
那就假设训练集和测试集是满足同一分布,即有相同的均值和方差

在这里插入图片描述

代码如下:


```python
import tensorflow as tf
import numpy as np
import time
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.utils import shuffle

'''
本来要来弄波士顿房价数据集,但是我找不到免费的csv格式,所以就找了另一个类似的数据集也是房价的
https://www.jianshu.com/p/928b95645757
'''

#读取数据文件
df=pd.read_csv("data/kc_train.csv")#第一行数据读不到,其他行可以

# print(df.describe())
# print(df)

#获取df的值
df=df.values
#转换为numpy的数组格式
df=np.array(df)
print(df)
print("df的形状为:",df.shape)
print(df[1,:])

'''
归一化操作,这个非常重要,没有这个结果就会报nan
'''
for i in range(2,14):
    # df[:,i]=df[:,i]/(df[:,i].max()-df[:,i].min())
    df[:,i]=(df[:,i]-df[:,i].min())/(df[:,i].max()-df[:,i].min())
    # print(i)#输出2到13
print("----------------------------------------")
print(df[1,:])
print(df)
x_data=df[:,2:]#从第三列到最后一列都是特征
y_data=df[:,1]#第二列是房屋价格,第一列是日期,我没有要这个数据
y_data=y_data/100000

# print(x_data.shape)#(9999, 12)说明是二维数组
# print(y_data.shape)#(9999,)说明是一维数组,由于是一维数组,所以谈不上是列向量还是行向量
# print(y_data.T)#由于是一维数组,所以没有转置一说,所以跟没转置一样
# print(y_data)
# print(x_data)

x=tf.placeholder(tf.float32,shape=[None,12],name="X")
y=tf.placeholder(tf.float32,shape=[None,1],name="Y")

#定义一个命名空间,方便管理
with tf.name_scope("Model"):
    w=tf.Variable(tf.random_normal([12,1],stddev=0.1),name="W")
    b=tf.Variable(1.0,name="B")
    def model(x,w,b):
        # return tf.multiply(x,w)+b#由于是矩阵相乘,所以不能用multiply
        return tf.matmul(x,w)+b
    pred=model(x,w,b)



#迭代次数
train_epoch=3
#学习率
learning_rate=0.05     #学习率大了会报nan,如0.5

with tf.name_scope("Loss_Function"):
    loss_function=tf.reduce_mean(tf.pow(y-pred,2))#顾名思义,求2次冥

#选择梯度下降优化器
optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)

#声明一个会话
sess=tf.Session()
#初始化变量
init=tf.global_variables_initializer()
sess.run(init)

#执行训练
for epoch in range(train_epoch):
    loss_sum=0
    for xs,ys in zip(x_data,y_data):
        #之所以要reshape是因为解包之后的是一维数组,而输入和输出要求二维
        xs=xs.reshape(1,12)
        ys=ys.reshape(1,1)
        # print("w的值为:",sess.run(w))
        # print("b的值为:",sess.run(b))
        # 这里根据zip函数,应该用的是训练一次用一个样本,即SGD,随机梯度下降,但是好像又不是随机,因为是按顺序一个个拿,反正是一次一个样本
        _,loss1=sess.run([optimizer,loss_function],feed_dict={x:xs,y:ys})
        loss_sum=loss_sum+loss1
    #打乱数据顺序
    xs1,ys1=shuffle(x_data,y_data)#xsl和ysl本身没什么用,这里就是把xdata和ydata一致的打乱
    #根据zip函数在for循环中的表现,这里是全部样本训练一遍后输出依次当前权重和偏置值
    b0temp=b.eval(session=sess)
    w0temp=w.eval(session=sess)
    loss_average=loss_sum/len(y_data)
    # plt.plot(x_data,x_data*w0temp+b0temp,\
    #          color="r",linewidth=3)
    print("epoch",epoch+1,"loss:",loss_average,"w:",w0temp,"b",b0temp)


n=np.random.randint(9999)
print(n)
x_test=x_data[n]      #这里是测试,用的训练的数据,x_data是归一化之后的数据,所以很合理。实际中如果有测试集的化,应该也得先归一化然后再输入到模型中。
x_test=x_test.reshape(1,12)
predict=sess.run(pred,feed_dict={x:x_test})
print("预测值为:",predict)
real=y_data[n]
print("真实值为:",real)

#用图形来演示拟合程度,取前100个点
num=100
xx=np.arange(1,num+1)
x_test=x_data[0:num]
x_test=x_test.reshape(-1,12)
predict=sess.run(pred,feed_dict={x:x_test})
plt.plot(xx,y_data[:num],label='target')      #目标取值
plt.plot(xx,predict[:num],label='preds')        #预测取值
plt.legend(loc='upper right')  #线条显示位置
plt.show()

在这里插入图片描述
上面就是归一化前和归一化后的数据
上面就是归一化前和归一化后的数据
上面就是归一化前和归一化后的数据
在这里插入图片描述
预测效果不怎么样
原因出在哪?下图打印了训练集中的预测值和实际值的比较
我觉得就是模型太简单,可能模型本身就不是线性的
后面碰到再来改
在这里插入图片描述




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值