一个端到端的机器学习项目全纪录(加州房价预测)

本文详述了一个端到端的机器学习项目,通过分析和处理加州房价数据,包括数据探索、特征工程、模型训练与优化。文章讨论了如何处理缺失值、分类属性、数据缩放,并使用了多种模型,如线性回归、决策树和随机森林,最后通过网格搜索找到最佳超参数。
摘要由CSDN通过智能技术生成

1 导入数据

import pandas

使用DataFrames里的head()看看前五行是什么样子的:

housing_data = pandas.read_csv(r'C:\Users\Administrator\Desktop\PHD\Machine learning\housing.csv')
housing_data.head()
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value ocean_proximity
0 -122.23 37.88 41.0 880.0 129.0 322.0 126.0 8.3252 452600.0 NEAR BAY
1 -122.22 37.86 21.0 7099.0 1106.0 2401.0 1138.0 8.3014 358500.0 NEAR BAY
2 -122.24 37.85 52.0 1467.0 190.0 496.0 177.0 7.2574 352100.0 NEAR BAY
3 -122.25 37.85 52.0 1274.0 235.0 558.0 219.0 5.6431 341300.0 NEAR BAY
4 -122.25 37.85 52.0 1627.0 280.0 565.0 259.0 3.8462 342200.0 NEAR BAY
housing_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
 #   Column              Non-Null Count  Dtype  
---  ------              --------------  -----  
 0   longitude           20640 non-null  float64
 1   latitude            20640 non-null  float64
 2   housing_median_age  20640 non-null  float64
 3   total_rooms         20640 non-null  float64
 4   total_bedrooms      20433 non-null  float64
 5   population          20640 non-null  float64
 6   households          20640 non-null  float64
 7   median_income       20640 non-null  float64
 8   median_house_value  20640 non-null  float64
 9   ocean_proximity     20640 non-null  object 
dtypes: float64(9), object(1)
memory usage: 1.6+ MB

从这里我们注意到两个事情:

  1. 数据集中包含20640个实例,另外要注意在total_bedrooms这个属性里只有20433个非空值,意味着207个区域缺失该特征(很关键),后面必须进行相应的处理。
  2. 除了ocean_proximity之外,其他属性都是数字,而ocean_proximity的类型是object,意味着它可以是任何的python对象,但因为我们看了excel,知道它是个文本属性。且有几个文本是重复的,意味着它可能是一个分类属性。

因此得出当前两个待办事项

  • total_bedrooms属性里的空缺值处理
  • 分类属性→数字化处理
housing_data["ocean_proximity"].value_counts()
<1H OCEAN     9136
INLAND        6551
NEAR OCEAN    2658
NEAR BAY      2290
ISLAND           5
Name: ocean_proximity, dtype: int64

使用describe()方法可以显示述数值属性的摘要

housing_data.describe()
longitude latitude housing_median_age total_rooms total_bedrooms population households median_income median_house_value
count 20640.000000 20640.000000 20640.000000 20640.000000 20433.000000 20640.000000 20640.000000 20640.000000 20640.000000
mean -119.569704 35.631861 28.639486 2635.763081 537.870553 1425.476744 499.539680 3.870671 206855.816909
std 2.003532 2.135952 12.585558 2181.615252 421.385070 1132.462122 382.329753 1.899822 115395.615874
min -124.350000 32.540000 1.000000 2.000000 1.000000 3.000000 1.000000 0.499900 14999.000000
25% -121.800000 33.930000 18.000000 1447.750000 296.000000 787.000000 280.000000 2.563400 119600.000000
50% -118.490000 34.260000 29.000000 2127.000000 435.000000 1166.000000 409.000000 3.534800 179700.000000
75% -118.010000 37.710000 37.000000 3148.000000 647.000000 1725.000000 605.000000 4.743250 264725.000000
max -114.310000 41.950000 52.000000 39320.000000 6445.000000 35682.000000 6082.000000 15.000100 500001.000000

另外一种快速了解数据类型的方法是绘制每个数值属性的直方图,可以直接在整个数据集上调用hist()方法,绘制每个属性的直方图

%matplotlib inline 
#使用jupyter自己的图形后端
import matplotlib.pyplot
housing_data.hist(bins = 50, figsize = (20,15)) #bins代表区间分布段
matplotlib.pyplot.show()

在这里插入图片描述
从直方图中要注意以下几点:

  1. median_income看起来单位不像是USD,经核实,数据已按比例缩小,且下限为0.5,上限为15,单位“万美元”
  2. house_median_age和median_house_value也被设置了上限,而median_house_value是本次学习的目标属性,可能有大问题发生
  3. 这些属性被缩放的比例不同
  4. 很多分布都不对称,在中位数右侧要远比左侧远

接下来要创建测试集

Scikit-learn提供了一些函数,可以通过很多方式将数据集分成多个子集,最简单的就是train_test_split,它的random_state参数使得可以设置随机生成器种子;并且如果把行数相同的多个数据一次性发给它,它会根据相同的索引将其拆分。

import numpy
def split_train_test(data, test_ratio):
    #随机排序然后按照比例切片
    shuffled_indices = numpy.random.permutation(len(data))
    test_setting_size = int(len(data) * test_ratio)  
    test_indices = shuffled_indices[:test_setting_size]
    train_indices = shuffled_indices[test_setting_size:]
    return data.iloc[train_indices], data.iloc[test_indices]
#样本数据切割为训练集和测试集,随机种子=42
from sklearn.model_selection import train_test_split   #scikit_learb提供的函数
train_set, test_set = train_test_split(housing_data, test_size = 0.2, random_state = 42) 
print(len(train_set), len(test_set))
16512 4128

上面说的都是纯随机的情形,但被告之,要预测房价中位数,收入中位数是一个非常重要的属性,因此我们想确保在收入属性上,测试集能够代表整个数据集中各种不同类型的收入层次。但由于median_income是一个连续的数值属性,因此在这里我们将创建一个收入的分类属性。

经过观察直方图,发现大多收入数值聚集在1.5~6左右,但也有一部分远远超过了6。分层的原则要保证每一层都要有数量足够的实例,不然实例不足的层,其重要程度可能会被错误的估计。也就是说,层不能分的太多,而每一层都要足够大。
下面创建五个收入类别属性(用1~5做标签),0-1.5是类别1,以此类推

#对收入进行分层,创建5个收入类别属性,标签分别为1~5
housing_data["income_cat"] = pandas.cut(housing_data["median_income"], 
                                    bins = [0., 1.5, 3.0, 4.5, 6., numpy.inf], labels = [1, 2, 3, 4 ,5]) 

housing_data["income_cat"].hist()

在这里插入图片描述
现在可以根据类别分层抽样来,使用Scikit-learn的StratifiedShuffleSplit类

from sklearn.model_selection import StratifiedShuffleSplit
split = StratifiedShuffleSplit(n_splits = 1, test_size = 0.2, random_state = 42)
for train_index, test_index in split.split(housing_data, housing_data["income_cat"]):
    
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值