Boston Housing数据集包含有关波士顿不同房屋的信息。该机器学习数据集中有506个样本和13个特征变量。目标是使用给定的特征预测房屋价格的价值。我们将从scikit-learn本身导入这个机器学习数据集。
让我们从导入一些Python库开始。
import numpy as np import pandas as pd #Visualization Libraries import seaborn as sns import matplotlib.pyplot as plt #To plot the graph embedded in the notebook %matplotlib inline
现在我们需要从sklearn导入模块
#imports from sklearn library from sklearn import datasets from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split, cross_val_score from sklearn.metrics import mean_squared_error
从sklearn导入机器学习数据集
#loading the dataset direclty from sklearn boston = datasets.load_boston()
sklearn返回类似字典的对象,属性是:' data ',要学习的数据,' target ',回归目标,' DESCR ',数据集的完整描述,' filename',波士顿的物理位置csv数据集。我们可以从以下操作中获得。
print(type(boston)) print('\n') print(boston.keys()) print('\n') print(boston.data.shape) print('\n') print(boston.feature_names)
如上所述,有4个键值['data','target','feature_names','DESCR']。数据有506行和13个特征变量。请注意,这不包括目标变量。此外,还提取列的名称。使用boston.DESCR` 可以看到有关机器学习数据集的特征和更多的详细信息
print(boston.DESCR)
在应用任何EDA或机器学习模型之前,我们必须将其转换为panda dataframe,这可以通过调用boston.data上的dataframe来实现。我们还将目标变量从boston.target添加到dataframe,Python代码如下:
bos = pd.DataFrame(boston.data, columns = boston.feature_names) bos['PRICE'] = boston.target print(bos.head())
数据预处理
在加载数据之后,最好查看数据中是否有缺失值。我们使用.isnull()来计算每个特征缺失值的数量
bos.isnull().sum()
正如在描述中也提到的那样,数据集中没有空值,这里我们也可以看到相同的值。
print(bos.describe())
探索性数据分析
探索性数据分析是训练机器学习模型之前非常重要的一步。在这里,我们将使用可视化来理解目标变量与其他特征的关系。
让我们首先绘制目标变量的分布。我们将使用matplotlib库中的直方图绘图函数。
sns.set(rc={'figure.figsize':(11.7,8.27)}) plt.hist(bos['PRICE'], bins=30) plt.xlabel("House prices in $1000") plt.show()
从图中可以看出,价格的分布是正态的,很少有异常值。大部分的房子都在20 - 24范围(in $1000 scale)
现在,我们创建一个相关矩阵来衡量变量之间的线性关系。可以通过使用来自pandas dataframe 库的corr函数来形成相关矩阵。我们将使用seaborn库中的热图函数绘制相关矩阵。
#Created a dataframe without the price col, since we need to see the correlation between the variables bos_1 = pd.DataFrame(boston.data, columns = boston.feature_names) correlation_matrix = bos_1.corr().round(2) sns.heatmap(data=correlation_matrix, annot=True)
相关系数的范围从-1到1.如果该值接近1,则意味着两个变量之间存在强正相关。当它接近-1时,变量具有强负相关性。
注意
- 通过查看相关矩阵,我们可以看到RM与PRICE (0.7)具有强正相关性,其中LSTAT与PRICE (-0.74)具有强负相关。
- 选择线性回归模型的特征的一个重点是检查多重共线性。RAD,TAX的特征相关系数为0.9,这些特征对彼此强相关。这会影响机器学习模型。具有相关性-0.75的特征DIS和AGE也是如此。
但是现在我们将保留所有特征。
plt.figure(figsize=(20, 5)) features = ['LSTAT', 'RM'] target = bos['PRICE'] for i, col in enumerate(features): plt.subplot(1, len(features) , i+1) x = bos[col] y = target plt.scatter(x, y, marker='o') plt.title("Variation in House prices") plt.xlabel(col) plt.ylabel('"House prices in $1000"')
注意
- 随着RM值线性增加,价格上涨。几乎没有异常值,数据似乎上限为50。
- 随着LSTAT的增加,价格趋于下降。虽然它看起来并不完全沿着一条直线。
由于很难用多个特征进行可视化,我们将首先用一个变量预测房价,然后转向具有所有特征的回归。
由于您看到'RM'与房价的正相关,我们将使用此变量。
X_rooms = bos.RM y_price = bos.PRICE X_rooms = np.array(X_rooms).reshape(-1,1) y_price = np.array(y_price).reshape(-1,1) print(X_rooms.shape) print(y_price.shape)
这些都具有[506,1]的维度
将数据拆分为训练和测试集
由于我们需要测试我们的机器学习模型,我们将数据分成训练和测试集。我们用80%的样品训练模型,并用剩余的20%进行测试。我们这样做是为了评估机器学习模型在看不见的数据上的表现。
要拆分据,我们使用scikit-learn库提供的train_test_split函数。
X_train_1, X_test_1, Y_train_1, Y_test_1 = train_test_split(X_rooms, y_price, test_size = 0.2, random_state=5) print(X_train_1.shape) print(X_test_1.shape) print(Y_train_1.shape) print(Y_test_1.shape)
训练的输出为[404,1],测试数据的大小为[102,1]。
训练和测试机器学习模型
在这里,我们使用scikit-learn的LinearRegression来训练我们的训练模型并在测试集上进行检查。并检查训练数据集上的模型性能。
reg_1 = LinearRegression() reg_1.fit(X_train_1, Y_train_1) y_train_predict_1 = reg_1.predict(X_train_1) rmse = (np.sqrt(mean_squared_error(Y_train_1, y_train_predict_1))) r2 = round(reg_1.score(X_train_1, Y_train_1),2) print("The model performance for training set") print("--------------------------------------") print('RMSE is {}'.format(rmse)) print('R2 score is {}'.format(r2)) print("\n")
# model evaluation for test set y_pred_1 = reg_1.predict(X_test_1) rmse = (np.sqrt(mean_squared_error(Y_test_1, y_pred_1))) r2 = round(reg_1.score(X_test_1, Y_test_1),2) print("The model performance for training set") print("--------------------------------------") print("Root Mean Squared Error: {}".format(rmse)) print("R^2: {}".format(r2)) print("\n")
在输出变量上绘制模型拟合线。
prediction_space = np.linspace(min(X_rooms), max(X_rooms)).reshape(-1,1) plt.scatter(X_rooms,y_price) plt.plot(prediction_space, reg_1.predict(prediction_space), color = 'black', linewidth = 3) plt.ylabel('value of house/1000($)') plt.xlabel('number of rooms') plt.show()
所有变量的回归模型
现在我们将创建一个考虑数据集中所有特征的模型。该过程几乎相同,也是评估模型,但在这种情况下,在2D空间中无法实现可视化。
步骤完全相同。
X = bos.drop('PRICE', axis = 1) y = bos['PRICE'] X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2, random_state=42) reg_all = LinearRegression() reg_all.fit(X_train, y_train) # model evaluation for training set y_train_predict = reg_all.predict(X_train) rmse = (np.sqrt(mean_squared_error(y_train, y_train_predict))) r2 = round(reg_all.score(X_train, y_train),2) print("The model performance for training set") print("--------------------------------------") print('RMSE is {}'.format(rmse)) print('R2 score is {}'.format(r2)) print("\n")
# model evaluation for test set y_pred = reg_all.predict(X_test) rmse = (np.sqrt(mean_squared_error(y_test, y_pred))) r2 = round(reg_all.score(X_test, y_test),2) print("The model performance for training set") print("--------------------------------------") print("Root Mean Squared Error: {}".format(rmse)) print("R^2: {}".format(r2)) print("\n")
通过绘制原始房价和预测房价之间的散点图,我们可以看到我们的模型是如何预测的。
plt.scatter(y_test, y_pred) plt.xlabel("Actual House Prices ($1000)") plt.ylabel("Predicted House Prices: ($1000)") plt.xticks(range(0, int(max(y_test)),2)) plt.yticks(range(0, int(max(y_test)),2)) plt.title("Actual Prices vs Predicted prices")