机器学习-线性回归-python scikit-learn 房价预测


前言

本教程在anaconda中的notebook进行实现,python版本3.10.9。
线性回归-房价数据,scikit-learn。

实验数据可在最上方的链接下载,如下图所示:
在这里插入图片描述

1.引入基本库

#导入所需要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression

2.读入数据

#sklearn中的california_housing数据,这里只做展示,相关教程可到sklearn中进行学习。
X, y = fetch_california_housing(return_X_y=True)
#真实数据,本实验主要针对该数据进行训练
cal_data = pd.read_csv('housing.csv')

为更好地扩展实验内容,在接下来的实验中,将采用真实数据cal_data 进行模型训练。

有关真实数据cal_data 数据的信息

  1. longitude,经度:房子向西多远的量度;越往西,数值越高
  2. latitude,纬度:衡量房子往北多远的尺度;越往北,数值越高
  3. housing_median_age:街区内房屋年龄的中位数;较低的数字代表较新的建筑
  4. total_rooms:一个街区内的房间总数
  5. total_bedrooms:一个街区内的卧室总数
  6. population,人口:居住在一个街区内的总人数
  7. households,住户:一个街区的住户总数,即居住在一个家庭单位内的一群人
  8. median_income:街区内住户收入中位数(以万美元计)
  9. median_house_value:街区内住户的房屋价值中位数(以美元计算)
  10. oceanProximity:房子靠近海洋/海洋的位置

3.划分数据集,并查看缺失值

数据分成训练集和测试集。这是因为在数据分析和处理的过程中,可能会出现“数据泄露”,即不希望模型看到将要测试的数据。在模型训练时使用训练集,在模型评估时使用测试集。

from sklearn.model_selection import train_test_split
train_data, test_data = train_test_split(cal_data, test_size=0.1,random_state=20)
#检查数据中的缺失值
train_data.isnull().sum()

4.分析数据集中的特征关系

#检查特征之间的相关性,并进行热力图可视化
correlation = train_data.iloc[:,0:9].corr()#读取0-8列数据
plt.figure()
sns.heatmap(correlation,annot=True,cmap='crest')

在这里插入图片描述

绘制地理特征
既然有了经纬度,我们来画一下。它可以帮助我们知道某些房子在地图上的位置

plt.figure(figsize=(12,7))
sns.scatterplot(data = train_data, x='longitude', y='latitude')

在这里插入图片描述

画一下,地理位置对应的房价中位数对应图。

plt.figure(figsize=(12,7))
sns.scatterplot(data = train_data, x='longitude', y='latitude', hue='median_house_value')

在这里插入图片描述
再按照房子靠近海洋/海洋的位置进行可视化

plt.figure(figsize=(12,7))
sns.scatterplot(data = train_data, x='longitude', y='latitude', hue='ocean_proximity', 
                size='median_house_value')

在这里插入图片描述

5.划分出Y标签,并去除缺失值

training_input_data = train_data.drop('median_house_value', axis=1)
training_labels = train_data['median_house_value']

缺失值在现实世界的数据集中是不可避免的,所以知道如何处理它们是很好的。
在处理缺失值时,有三种选择:

  1. 完全移除它们
  2. 用不同的策略填充它们,如mean, median, frequency或constant。
  3. 让他们保持原样。大多数机器学习模型无法识别缺失值,因此它们无法处理缺失值,但有些模型不受缺失值的影响,例如基于树的算法。因为现在使用的是线性模型,所以这不是一个选择。
    Sklearn提供了一个名为“SimpleImputer”的函数来填充缺失的值。这里将用相关特征的平均值填充这些值,还可以使用中位数或最常见的值。
from sklearn.impute import SimpleImputer
num_feats = training_input_data.drop('ocean_proximity', axis=1)
def handle_missing_values(input_data):
  mean_imputer = SimpleImputer(strategy='mean')
  num_feats_imputed = mean_imputer.fit_transform(input_data)
  num_feats_imputed = pd.DataFrame(num_feats_imputed, 
                            columns=input_data.columns, index=input_data.index )
  return num_feats_imputed
num_feats_imputed = handle_missing_values(num_feats)
num_feats_imputed.isnull().sum()

在这里插入图片描述

6.编码分类特征

分类特征是具有分类值的特征。我们数据集中的一个例子是’ ocean_proximity ',它具有以下值。

training_input_data['ocean_proximity'].value_counts()

在这里插入图片描述
有很多方法可以处理分类特性,但在这个项目中,我们只看3种技术,即简单的Python映射、普通编码和一个热编码。Label和One Hot可以在Sklearn中轻松实现。
映射很简单。我们创建一个分类值及其相应数值的字典。然后,我们把它映射到分类特征上。
下面是它是如何实现的。

cat_feats = training_input_data['ocean_proximity']
feat_map = {
      '<1H OCEAN': 0,
      'INLAND': 1,
      'NEAR OCEAN': 2,
      'NEAR BAY': 3, 
      'ISLAND': 4
}
cat_feats_encoded = cat_feats.map(feat_map)
cat_feats_encoded.head()

映射结果
One Hot Encoding

当类别没有任何顺序时,One Hot Encoding是最受欢迎的,这正是我们的分类特征的方式。这就是我所说的无序类别:如果你有3个城市,并分别用数字(1,2,3)对它们进行编码,机器学习模型可能会学习到城市1靠近城市2和城市3。由于这是一个错误的假设,如果城市特征在分析中起重要作用,该模型可能会给出不正确的预测。

另一方面,如果你有有序范围的特征,比如低、中、高,那么数字可能是一种有效的方法,因为你想保持这些范围的顺序。

在我们的例子中,海洋邻近特征并不是按任何顺序排列的。通过使用一个热点,将类别转换为二进制表示(1或0),并将原有的分类特征拆分为更多的特征,相当于类别的数量。

from sklearn.preprocessing import OneHotEncoder
def one_hot(input_data):
  one_hot_encoder = OneHotEncoder()
  output = one_hot_encoder.fit_transform(input_data)
  output = output.toarray()
  return output
  cat_feats = training_input_data[['ocean_proximity']]
cat_feats_hot = one_hot(cat_feats)
cat_feats_hot

在这里插入图片描述

7.缩放数字特征

在我们输入缺失值并将分类特征转换为数字之后,是时候缩放数字特征了。

但是为什么我们要缩放数值特征呢?大多数机器学习模型在给定较小的输入值时都能很好地工作,如果它们在相同的范围内则效果最好。

出于这个原因,有两种最常用的技术来扩展功能:

*归一化,将特征缩放到0到1之间的值。和
*标准化,其中特征被重新缩放为具有0平均值和单位标准差。当处理包含异常值的数据集(如时间序列)时,在这种特殊情况下,标准化是正确的选择。

这两种技术在Sklearn中都很容易实现,使用’ MinMaxScaler ‘进行规范化,使用’ StandardScaler '进行标准化。

#归一化数值特征
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
num_scaled = scaler.fit_transform(num_feats)
#标准化数值特征
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
num_scaled = scaler.fit_transform(num_feats)

8.将所有数据预处理步骤放入单个Pipeline中

拥有数据Pipeline可以无缝地运行数据处理:

  1. 创建具有所有数值预处理步骤的数值Pipeline(处理缺失值和标准化)
  2. 创建一个分类Pipeline来编码分类特征
  3. 将两个Pipeline合并为一个Pipeline
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
num_feats_pipe = Pipeline([('imputer', SimpleImputer(strategy='mean')), ('scaler', StandardScaler()) ])
cat_feats_pipe = Pipeline([('encoder', OneHotEncoder())])
num_list = list(num_feats)
cat_list = list(cat_feats)
final_pipe = ColumnTransformer([
   ('num', num_feats_pipe, num_list),    
   ('cat', cat_feats_pipe, cat_list) ])
training_data_preprocessed = final_pipe.fit_transform(training_input_data)

9.训练和评估模型

你可能听说过这样一个概念:机器学习只占整个ML项目的5%左右,其余的百分比用于数据处理。本文确实花了很多时间处理数据。这里使用sklearn中提供的线性回归模型。

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
reg_model = LinearRegression()
#训练模型
reg_model.fit(training_data_preprocessed, training_labels)
predictions = reg_model.predict(training_data_preprocessed)
#评估模型使用 mse 、rmse 
mse = mean_squared_error(training_labels, predictions)
rmse = np.sqrt(mse)#这里值为:68438.90242790822

也可以使用交叉验证将训练数据分成训练和验证的不同折叠或子集。通过对模型进行多次训练和验证,比如10次,最终会得到10个不同的分数,可以取平均值。请注意,预测是在看不见的子集上进行的,模型不会看到它正在评估的数据。

from sklearn.model_selection import cross_val_score
scoring = 'neg_root_mean_squared_error' 
scores = cross_val_score(reg_model, training_data_preprocessed, training_labels, scoring=scoring, cv=10)
scores = -scores
scores.mean()#这里值为:68493.74387894807

总结

该模型很简单,因此可以尝试其他复杂的模型,如随机森林、决策树或集成方法。因为我们将在下一个实验中讨论这些模型。另外,需要注意的是,大多数情况下,如果您有一个简单的数据集,简单模型将工作得很好,因为复杂模型可能会过拟合数据。此外,好的模型来自好的数据,所以最好花时间整理数据,而不是在模型中来回跳来跳去

  • 29
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值