机器学习之利用线性回归预测波士顿房价和可视化分析影响房价因素实战(python实现 附源码 超详细)

Posted showswoller

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习之利用线性回归预测波士顿房价和可视化分析影响房价因素实战(python实现 附源码 超详细)相关的知识,希望对你有一定的参考价值。

数据集和源码请点赞关注收藏后评论区留下QQ邮箱或者私信

线性回归是利用最小二乘函数对一个或多个因变量之间关系进行建模的一种回归分析,这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个变量的称为一元回归,大于一个变量的情况叫做多元回归。利用线性回归,我们可以预测一组特定数据是否在一定时期内增长或下降。

接下来以线性回归预测波士顿房价进行实战解析

线性回归代码如下

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

# 读数据
data = np.loadtxt(boston_house_price.csv', float, delimiter=",", skiprows=1)
X, y = data[:, :13], data[:, 13]
# Z-score归一化
for i in range(X.shape[1]):
    X[:, i] = (X[:, i] - np.mean(X[:, i])) / np.std(X[:, i])
# 划分训练集、测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 将训练集、测试集改为列向量的形式
y_train = y_train.reshape((-1, 1))
y_test = y_test.reshape((-1, 1))

# 初始化模型参数
def initialize_params(feature_num):
 
    w=np.random.rand(feature_num,1)
    b=0
    return w,b


def forward(X, y, w, b):
 
    num_train=X.shape[0]
    y_hat=np.dot(X,w)+b
    loss=np.sum((y_hat-y)**2)/num_train
    dw=np.dot(X.T,(y_hat-y))/num_train
    db=np.sum((y_hat-y))/num_train
    return y_hat,loss,dw,db

# 定义线性回归模型的训练过程
def my_linear_regression(X, y, learning_rate, epochs):

    loss_his=[]
    w,b=initialize_params(X.shape[1])
    for i in range(epochs):
        y_hat,loss,dw,db=forward(X,y,w,b)
        w+=-learning_rate*dw
        b+=-learning_rate*db
        loss_his.append(loss)
        if i%100==0:
            print("epochs %d loss %f"%(i,loss))
    return loss_his,w,b









# 线性回归模型训练
loss_his, w, b = my_linear_regression(X_train, y_train, 0.01, 5000)
# 打印loss曲线
plt.plot(range(len(loss_his)), loss_his, linewidth=1, linestyle="solid", label="train loss")
plt.show()
# 打印训练后得到的模型参数
print("w:", w, "\\nb", b)

# 定义MSE函数
def MSE(y_test, y_pred):
    return np.sum(np.square(y_pred - y_test)) / y_pred.shape[0]

# 定义R系数函数
def r2_score(y_test, y_pred):
    # 测试集标签均值
    y_avg = np.mean(y_test)
    # 总离差平方和
    ss_tot = np.sum((y_test - y_avg) ** 2)
    # 残差平方和
    ss_res = np.sum((y_test - y_pred) ** 2)
    # R计算
    r2 = 1 - (ss_res / ss_tot)
    return r2

# 在测试集上预测
y_pred = np.dot(X_test, w) + b
# 计算测试集的MSE
print("测试集的MSE: :.2f".format(MSE(y_test, y_pred)))
# 计算测试集的R方系数
print("测试集的R2: :.2f".format(r2_score(y_test, y_pred)))

损失值随训练次数的变化图如下 可以看出符合肘部方法 

 

 接下来可视化分析影响房价的因素

"""
各个字段的含义:
    CRIM     犯罪率
    ZN       住宅用地所占比例
    INDUS    城镇中非商业用地所占比例
    CHAS     是否处于查尔斯河边
    NOX      一氧化碳浓度
    RM       住宅房间数
    AGE      1940年以前建成的业主自住单位的占比
    DIS      距离波士顿5个商业中心的加权平均距离
    RAD      距离高速公路的便利指数
    TAX      不动产权税
    PTRATIO  学生/教师比例
    B        黑人比例
    LSTAT    低收入阶层占比
    MEDV     房价中位数
"""

可视化结果如下 

 

 

 

 可视化部分代码如下

import  pandas as pd
import  numpy as np
import  seaborn as sns
import  matplotlib.pyplot as plt
df=pd.read_csv(boston_house_price.csv',encoding='utf-8')
print(df.head())
df.describe()
df['medv'].hist()
sns.boxplot(x=df['medv'])#有点问题 要加个x传参
plt.scatter(df['rm'],df['medv'])
def box_plot_outliers(df,s):
    q1,q3=df[s].quantile(0.25),df[s].quantile(0.75)
    iqr=q3-q1
    low,up=q1-1.5*iqr,q3+1.5*iqr
    df=df[(df[s]>up)|(df[s]<low)]
    return df
df_filter=box_plot_outliers(df,'rm')
df_filter.mean()

plt.scatter(df['dis'],df['medv'])
plt.scatter(df['rad'],df['medv'])
plt.scatter(df['b'],df['medv'])
df.corr()
plt.style.use('figure.figsize':(15,10))
df.hist(bins=15)
sns.boxplot(data=df)
plt.figure(figsize=(12,22))
for i in range(13):
    plt.subplot(4,4,(i+1))
    plt.scatter(df.iloc[:,i],df['medv'])
    plt.title('-price scatter'.format(df.columns[i]))
    plt.xlabel(df.columns[i])
    plt.ylabel('boston house price')
plt.show()
plt.tight_layout()

数据集和源码请点赞关注收藏后评论区留下QQ邮箱或者私信

线性回归模型之波士顿房价预测

作者介绍

周新龙,男,西安工程大学电子信息学院,2019级研究生,张宏伟人工智能课题组
研究方向:机器视觉与人工智能
电子邮件:402850713@qq.com

一、波士顿房价数据集介绍

波士顿房价数据集统计的是20世纪70年代中期波士顿郊区房价的中位数,统计了城镇人均犯罪率、不动产税等共计13个指标,506条房价数据,通过统计出的房价,试图能找到那些指标与房价的关系。
数据集中的每一行数据都是对波士顿周边或城镇房价的情况描述,下面对数据集变量进行说明,方便大家理解数据集变量代表的意义。
CRIM: 城镇人均犯罪率
ZN: 住宅用地所占比例
INDUS: 城镇中非住宅用地所占比例
CHAS: 虚拟变量,用于回归分析
NOX: 环保指数
RM: 每栋住宅的房间数
AGE: 1940 年以前建成的自住单位的比例
DIS: 距离 5 个波士顿的就业中心的加权距离
RAD: 距离高速公路的便利指数
TAX: 每一万美元的不动产税率
PTRATIO: 城镇中的教师学生比例
B: 城镇中的黑人比例
LSTAT: 地区中有多少房东属于低收入人群
MEDV: 自住房屋房价中位数(也就是均价)

二、实验步骤

1.数据分析

首先导入数据集,对数据进行分析:

import  pandas as pd
import numpy as np
from sklearn.datasets import load_boston  # 导入数据集
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator
boston = load_boston()
print(boston.feature_names)  # 查看boston数据集特征变量
print(boston.data.shape)  # 分析数据集样本总数,特征变量总数
v_bos = pd.DataFrame(boston.data)  # 查看波士顿数据集前5条数据,查看这13个变量数据情况
print(v_bos.head(5))

根据程序输出结果,查看数据集数据样本总数,与特征变量个数;以及通过数据集前5条数据,查看13个特征变量数据情况。

2.可视化处理特殊异常特征信息值(共14幅散点图)

然后对自变量进行特征分析,并画出散点图,分析特征变量与房价之间的相关性,把不相关的数据进行剔除。

x = boston['data']  # 导入特征变量
y = boston['target']  # 导入目标变量房价
 name = boston['feature_names']
            for i in range(13):
                plt.figure(figsize=(10, 7))
                plt.grid()
                plt.scatter(x[:, i], y, s=5)  # 横纵坐标和点的大小
                plt.title(name[i])
                print(name[i], np.corrcoef(x[:i]), y)
            plt.show()

经过分析“房价特征信息图”,将房价大于或者等于50的数据视为异常数据,在划分训练集和测试集之前我们需要先把这些数据从数据集中进行剔除。

plt.figure(figsize=(20, 15))
            y_major_locator = MultipleLocator(5)  # 把y轴的刻度间隔设置为10,并存在变量里
            ax = plt.gca()  # ax为两条坐标轴的实例
            ax.yaxis.set_major_locator(y_major_locator)  # 把y轴的主刻度设置为5的倍数
            plt.ylim(0, 51)
            plt.grid()
            for i in range(len(y)):
                plt.scatter(i, y[i], s=20)
            plt.show()

同样通过分析“各个特征信息散点图”,我们可以看到有些特征信息与房价的相关性比较大,有些特征信息与房价的相关性很小,因此需要将不相关特征信息进行剔除,只保留与房价相关性最大的特征信息。

3.导入线性回归模型进行训练

接着通过上述散点图分析,对异常数据进行处理,完成数据的预处理。
最后通过导入线性回归模型搭建波士顿房价预测模型

import numpy as np
from skimage.metrics import mean_squared_error
from sklearn import linear_model
from sklearn.linear_model import LinearRegression  # 导入线性模型
from sklearn.datasets import load_boston  # 导入数据集
from sklearn.metrics import r2_score    # 使用r2_score对模型评估
from sklearn.model_selection import train_test_split  # 导入数据集划分模块
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt2
# 线性回归模型
lf = LinearRegression()
lf.fit(x_train, y_train)  # 训练数据,学习模型参数
y_predict = lf.predict(x_test)  # 预测

# 与验证值作比较
error = mean_squared_error(y_test, y_predict).round(5)  # 平方差
score = r2_score(y_test, y_predict).round(5)  # 相关系数

三、实验结果分析

fig = plt.figure(figsize=(13, 7))
plt.rcParams['font.family'] = "sans-serif"
plt.rcParams['font.sans-serif'] = "SimHei"
plt.rcParams['axes.unicode_minus'] = False  # 绘图
plt.plot(range(y_test.shape[0]), y_test, color='red', linewidth=1, linestyle='-')
plt.plot(range(y_test.shape[0]), y_predict, color='blue', linewidth=1, linestyle='dashdot')
plt.legend(['真实值', '预测值'])
plt.title("学号", fontsize=20)
error = "标准差d=" + str(error)+"\\n"+"相关指数R^2="+str(score)
plt.xlabel(error, size=18, color="black")
plt.grid()
plt.show()

r2_score()函数可以表示特征模型对特征样本预测的好坏,即确定系数。
根据预测值和真实值的对比图,如果其中线性回归模型的决定系数为0.60,说明线性关系可以解释房价的60%。

plt2.rcParams['font.family'] = "sans-serif"
plt2.rcParams['font.sans-serif'] = "SimHei"
plt2.title('学号', fontsize=24)
xx = np.arange(0, 40)
yy = xx
plt2.xlabel('* truth *', fontsize=14)
plt2.ylabel('* predict *', fontsize=14)
plt2.plot(xx, yy)
plt2.scatter(y_test, y_predict, color='red')
plt2.grid()
plt2.show()

其中,每个点的横坐标表示同一类房屋真实价格,纵坐标表示线性回归模型根据特征预测的结果,当二者值完全相等的时候就会落在红色实线上。所以模型预测得越准确,则点离红色实线越近。

附完整代码(2部分)

第一部分:数据分析及可视化

import  pandas as pd
import numpy as np
from sklearn.datasets import load_boston  # 导入数据集
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator

"""
第一步:首先认识波士顿数据集,分析查看数据集样本总数,特征变量总数。
第二步:然后画出波士顿数据集所有特征变量的散点图,并分析特征变量与房价的影响关系。
"""
boston = load_boston()
print(boston.feature_names)  # 查看boston数据集特征变量
print(boston.data.shape)  # 分析数据集样本总数,特征变量总数
v_bos = pd.DataFrame(boston.data)  # 查看波士顿数据集前5条数据,查看这13个变量数据情况
print(v_bos.head(5))
x = boston['data']  # 导入特征变量
y = boston['target']  # 导入目标变量房价
student = input('房价特征信息图--0;各个特征信息图--1: ')  # 输入0代表查看影响房价特征信息图,输入1代表查看各个特征信息图
if str.isdigit(student):
    b = int(student)
    if (b <= 1):
        print('开始画图咯...', end='\\t')
        if (b == 0):
            plt.figure(figsize=(20, 15))
            y_major_locator = MultipleLocator(5)  # 把y轴的刻度间隔设置为10,并存在变量里
            ax = plt.gca()  # ax为两条坐标轴的实例
            ax.yaxis.set_major_locator(y_major_locator)  # 把y轴的主刻度设置为5的倍数
            plt.ylim(0, 51)
            plt.grid()
            for i in range(len(y)):
                plt.scatter(i, y[i], s=20)
            plt.show()
        else:
            name = boston['feature_names']
            for i in range(13):
                plt.figure(figsize=(10, 7))
                plt.grid()
                plt.scatter(x[:, i], y, s=5)  # 横纵坐标和点的大小
                plt.title(name[i])
                print(name[i], np.corrcoef(x[:i]), y)
            plt.show()
    else:
        print('同学请选择0或者1')

else:
    print('同学请选择0或者1')

第二部分:利用线性回归模型预测波士顿房价

import numpy as np
from skimage.metrics import mean_squared_error
from sklearn import linear_model
from sklearn.linear_model import LinearRegression  # 导入线性模型
from sklearn.datasets import load_boston  # 导入数据集
from sklearn.metrics import r2_score    # 使用r2_score对模型评估
from sklearn.model_selection import train_test_split  # 导入数据集划分模块
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt2

boston = load_boston()
x = boston['data']  # 影响房价的特征信息数据
y = boston['target']  # 房价
name = boston['feature_names']

# 数据处理
unsF = []  # 次要特征下标
for i in range(len(name)):
    if name[i] == 'RM' or name[i] == 'PTRATIO' or name[i] == 'LSTAT' or name[i] == 'AGE' or name[i] == 'NOX' or name[i] == 'DIS' or name[i] == 'INDUS':
        continue
    unsF.append(i)
x = np.delete(x, unsF, axis=1)  # 删除次要特征

unsT = []  # 房价异常值下标
for i in range(len(y)):
    if y[i] > 50:  # 对房价影响较小的特征信息进行剔除
        unsT.append(i)
x = np.delete(x, unsT, axis=0)  # 删除样本异常值数据
y = np.delete(y, unsT, axis=0)  # 删除异常房价

# 将数据进行拆分,一份用于训练,一份用于测试和验证
# 测试集大小为30%,防止过拟合
# 这里的random_state就是为了保证程序每次运行都分割一样的训练集和测试集。
# 否则,同样的算法模型在不同的训练集和测试集上的效果不一样。
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=0)

# 线性回归模型
lf = LinearRegression()
lf.fit(x_train, y_train)  # 训练数据,学习模型参数
y_predict = lf.predict(x_test)  # 预测

# 与验证值作比较
error = mean_squared_error(y_test, y_predict).round(5)  # 平方差
score = r2_score(y_test, y_predict).round(5)  # 相关系数

# 绘制真实值和预测值的对比图
fig = plt.figure(figsize=(13, 7))
plt.rcParams['font.family'] = "sans-serif"
plt.rcParams['font.sans-serif'] = "SimHei"
plt.rcParams['axes.unicode_minus'] = False  # 绘图
plt.plot(range(y_test.shape[0]), y_test, color='red', linewidth=1, linestyle='-')
plt.plot(range(y_test.shape[0]), y_predict, color='blue', linewidth=1, linestyle='dashdot')
plt.legend(['真实值', '预测值'])
plt.title("学号", fontsize=20)
error = "标准差d=" + str(error)+"\\n"+"相关指数R^2="+str(score)
plt.xlabel(error, size=18, color="black")
plt.grid()
plt.show()

plt2.rcParams['font.family'] = "sans-serif"
plt2.rcParams['font.sans-serif'] = "SimHei"
plt2.title('学号', fontsize=24)
xx = np.arange(0, 40)
yy = xx
plt2.xlabel('* truth *', fontsize=14)
plt2.ylabel('* predict *', fontsize=14)
plt2.plot(xx, yy)
plt2.scatter(y_test, y_predict, color='red')
plt2.grid()
plt2.show()

以上是关于机器学习之利用线性回归预测波士顿房价和可视化分析影响房价因素实战(python实现 附源码 超详细)的主要内容,如果未能解决你的问题,请参考以下文章

线性回归模型之波士顿房价预测

02-06 普通线性回归(波斯顿房价预测)+特征选择

机器学习之路: python 线性回归LinearRegression, 随机参数回归SGDRegressor 预测波士顿房价

机器学习梯度下降法应用波士顿房价预测

《用Python玩转数据》项目—线性回归分析入门之波士顿房价预测

机器学习保姆级入门案例-波士顿房价预测