作者介绍

周新龙,男,西安工程大学电子信息学院,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()
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐