多元线性回归:一个因变量y ,开始由多个自变量(x1,x2,...xn)来决定
假设我们要去预测一套房子的价格:(多因素觉得房价):
eg: 房子的面积, 几室几厅 ,房龄 ,周围配套,环境,政策 ,银行房贷利率等等。
考虑的因素越多,我们对房价就能预测得更准确.
简单理解多元线性回归:
多个变量对一个事物的影响,例如房价,房子面积这个单变量,就对房价影响大,两百平的大豪宅,肯定贵。我们的目标:就是找出这些变量对房价的影响所占的比例,比如:房屋面积对价格 的高低的影响占比多少比例。
下面是多元线性回归的推理和一个boston房价预测实例:
通过数据可视化:可以看出,房价低的地方犯罪率也比较高,有兴趣可以改一改程序,将每个因素之间联系分析它们之间的相关性。
way1: boston 房价预测: 自己实现 速度非常快
way2: 借助TensorFlow 实现 ,训练速度明显慢了很多,但是实现简单
数学模型:
求解过程:
实例: boston房价预测 多元线性回归
1: 数据挖掘: 对影响波士顿房价的因素进行分析。
2: 建模: 搭建一个波士顿房价预测模型(多元线性回归)
"""
波士顿房价数据集:
506 个样本:
每个样本:13个特征 标签 :该地区的平均房价
13个特征:
CRIM: 城镇人均犯罪率
ZN:住宅用地超过 25000 sq.ft. 的比例
INDUS: 城镇非零售商用土地的比例
CHAS: 边界是河流为1,否则0
NOX: 一氧化氮浓度
RM: 住宅平均房间数
AGE: 1940年之前建成的自用房屋比例
DIS:到波士顿5个中心区域的加权距离
RAD: 辐射性公路的靠近指数
TAX: 每10000美元的全值财产税率
PTRATIO: 城镇师生比例
LSTAT: 人口中地位低下者的比例
B: 城镇中的黑人比例
Label:
MEDV: 自住房的平均房价,单位:千美元
"""
本机环境:编写环境(Jupyter)
1:数据预处理:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
boston_housing = tf.keras.datasets.boston_housing
#数据加载
# 如果觉得训练集太小:可加参数 test_split=1 提取全部数据集作为训练数据
(train_x,train_y),(test_x,test_y) = boston_housing.load_data()
print("训练集shape: ",end='')
print(train_x.shape,train_y.shape)
print('测试集shape:',end='')
print(test_x.shape,test_y.shape)
num_train_x = train_x.shape[0] #训练集个数
num_test_x = test_x.shape[0] #测试集个数
data =np.hstack((train_x,train_y.reshape([num_train_x,1]))) #将数据合并
data =pd.DataFrame(data)
data.columns =['CRIM','ZN','INDUS','CHAS','NOX','RM','AGE','DIS','RAD','TAX','PT','B','LSTAT','MEDV']
#检查有没有数据中有没有空值
sum =data.isnull().any().sum()
print("空值个数:%d"%(sum))
#结合相关性变量,大体了解下数据的整体分布。
corr = data.corr()
print(corr)
#查看各个特征的散点分布 为了便于观察就选择 CRIM城镇人均犯罪率 与MEDV 自住房的平均房价的散点图
x =data.loc[:,['CRIM','MEDV']]
# 可选hist直方图 kde
pd.plotting.scatter_matrix(x, c=train_y,alpha=0.7,marker='o',hist_kwds={'bins':70}, s=70,figsize=(10,10), diagonal='kde')
2:机器学习 : 公式推导,自己写底层函数,矩阵求导,更新theta
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from time import time
boston_housing = tf.keras.datasets.boston_housing
#数据加载
# 如果觉得训练集太小:可加参数 test_split=1 提取全部数据集作为训练数据
(train_x,train_y),(test_x,test_y) = boston_housing.load_data()
#标准化 写了两个可选择 对训练结果影响有影响
def Data_Standard1(data):
"""
data: 标准化数据集
"""
mean = data.mean(axis=0)
std = data.std(axis=0)
res = (data -mean) /std
return res
def Data_Standard2(data):
"""
data: 标准化数据集
"""
minmize = data.min(axis =0)
maximum = data.max(axis =0)
data = (data-minmize) /(maximum -minmize)
return data
num_columns =train_x.shape[1] #获取特征个数
num_rows = train_x.shape[0] #训练数据个数
t =Data_Standard1(train_x) # 数据标准化处理
x0= np.ones((num_rows,1)) #扩充矩阵 x0一列都等于1,便于矩阵运算
traing_data = np.hstack((x0,t))
traing_label = train_y.reshape([num_rows,1]) # 将标签转成 m *1
#损失函数
def loss_Function(theta,x,y,m):
"""
theta: [ [θ0],[θ1],...[θn] ] shape : n*1 待求参数
x : 数据集 m *[x0,x1,x2,...xn] shape: m *(1+n)
y : 标签值 shape: m *1
m : 数据集个数
"""
# 均方差
Subtraction =np.dot(x,theta) -y
square = 1/(2*m)*np.dot(np.transpose(Subtraction) ,Subtraction)
return square
#梯度函数
def gradinet_Function(theta,x,y,m):
"""
w: [ θ[0],[θ1],[θ2],.. [θn]] shape : n*1 待求参数
x : 数据集 m *[x0,x1,...xn] shape: m *(n+1)
y : 标签值 shape: m *1
m : 数据集个数
"""
#参照矩阵求导公式
diff = np.dot(x,theta)-y
#print(diff.shape)
square =1/m*np.dot(np.transpose(x),diff)
return square
#设置超参数
traing_epochs = 3000 #训练轮数
learning_rate = 0.01
loss_history = []
#初始化训练参数 theta
#theta = np.random.normal(0,1,[num_columns+1,1])
theta = np.zeros([num_columns+1,1])
# 开始训练
start_Time = time()
for i in range(traing_epochs+1):
gradient = gradinet_Function(theta,traing_data,traing_label,num_rows) #计算当前位置梯度
theta = theta -learning_rate*gradient #更新参数
loss = loss_Function(theta,traing_data,traing_label,num_rows) #计算损失
loss_history.append(loss[0])
if i %500 ==0:
print("第%d 轮训练 , loss= %f "%(i,loss),end='')
print()
#print('theta:',theta)
duration =time() -start_Time
print("Train Finished take %5f "%(duration))
print('最后的结果%f',end='')
print(theta)
plt.plot(loss_history)
# 验证预测结果
num_test =test_x.shape[0] #获取测试集个数
n = np.random.randint(num_test) #产生一个随机数
test_x =Data_Standard1(test_x) #标准化测试集
#预测房价
print('在测试集中的预测:')
prediction = tf.matmul(test_x[n].reshape([1,13]),theta[1:14])+theta[0]
print(" 预测房价 =%f 实际房价= :%f"%(prediction ,test_y[n]))
print('在训练集中的预测:')
predict =np.matmul(traing_data[n].reshape([1,14]),theta)
print(" 预测房价: %f 实际房价: %f"%(predict,traing_label[n]))
3: 机器学习: 借助tensorflow实现
import tensorflow as tf
import numpy as np
import pandas as pd
from time import time
boston_housing = tf.keras.datasets.boston_housing
#test_split 提取全部数据集作为训练数据
(train_x,train_y),(test_x,test_y) = boston_housing.load_data()
#标准化 写了两个可选择 对训练结果影响有影响
def Data_Standard1(data):
"""
data: 标准化数据集
"""
mean = data.mean(axis=0)
std = data.std(axis=0)
res = (data -mean) /std
return res
def Data_Standard2(data):
"""
data: 标准化数据集
"""
minmize = data.min(axis =0)
maximum = data.max(axis =0)
data = (data-minmize) /(maximum -minmize)
return data
num_columns =train_x.shape[1] #获取特征个数
num_rows = train_x.shape[0] #训练数据个数
t =Data_Standard1(train_x) # 数据标准化处理
x0= np.ones((num_rows,1)) #扩充矩阵 x0一列都等于1,便于矩阵运算
traing_data = np.hstack((x0,t))
traing_label = train_y.reshape([num_rows,1]) # 将标签转成 m *1
#设置超参数
traing_epochs = 1000
learning_rate = 0.01
#初始化训练参数 theta
#theta = np.random.normal(0,1,[num_columns+1,1])
theta = tf.Variable(np.zeros([num_columns+1,1]) )
optimizer = tf.optimizers.SGD(learning_rate) #优化器
mse = tf.keras.losses.MeanSquaredError() # mse 均方差损失
loss_list = []
#开始训练
start_Time =time()
for epoch in range(traing_epochs+1):
with tf.GradientTape(persistent=True,watch_accessed_variables=True) as tape:
tape.watch([theta])
pred = tf.matmul(traing_data,theta)
loss = mse(pred,traing_label)
gradients = tape.gradient(target=loss,sources=[theta]) # 计算当前位置梯度
optimizer.apply_gradients(zip(gradients,[theta])) # 将计算的梯度更新
loss_list.append(loss)
if epoch% 100 == 0 :
print('epoch :%d loss: %f'%(epoch ,loss))
duration =time() -start_Time
print("Train Finished take %5f "%(duration))
print('最后的结果%f',end='')
print(theta)
plt.plot(loss_history)