3.Scikit-Learn实现完整的机器学习项目

1       完整的机器学习项目

完成项目的步骤:

(1)    项目概述

(2)    获取数据

(3)    发现并可视化数据,发现规律。

(4)    为机器学习算法准备数据。

(5)    选择模型,进行训练。

(6)    微调模型。

(7)    给出解决方案。

(8)    部署、监控、维护系统。

1.1  使用真实数据

学习机器学习时,最好使用真实数据,而不是人工数据集。幸运的是,有上千个开源数据集 可以进行选择,涵盖多个领域。以下是一些可以查找的数据的地方:

流行的开源数据仓库: UC  Irvine    Machine       Learning       Repository Kaggle     datasets Amazon’s  AWS      datasets 准入口(提供开源数据列表) http://dataportals.org/ http://opendatamonitor.eu/ http://quandl.com/ 其它列出流行开源数据仓库的网页: Wikipedia’s      list  of    Machine       Learning      datasets Quora.com   question Datasets subreddit

1.2  项目目标

你的第一个任务是利用加州普查数据,建立一个加州房价模型。然后根据其它指标,预测任何街区的的房价中位数。采用有监督的学习,这是一个多变量(街区人口,收入中位数)回归任务。因为不需要对数据变动做出快速适应,所以采用批量学习(离线学习)。

1.3  选择性能目标

选择性能指标:预测值和实际值之间的差距作为系统预测误差,通常用均方根误差(m个实际值与预测值之差的平方,除以m的平均值,再开根号,得到均方根误差),平均绝对偏差(实际值与预测值之差的绝对值的平均值)。K阶闵氏范数(向量模的k次方之后,在开k次方根),切比雪夫范数(向量中最大的)。

1.4  核实假设

确定最终的目标是获得准确的房屋价格,做投资评估,而不是给房屋价格进行分类高中低。不同的需求采用不同的分析方法和模型。

1.5  获取代码和数据

(1)   获取代码和数据

https://github.com/ageron/handson-ml下载代码和数据,复制到路径D:\Project\python\handson-ml-master。

(2)   在window上安装python和git用于模拟linux开发环境,设置环境变量

$ export HOME="/d/project/python/handson-ml-master"

$ export ML_PATH="$HOME/ml"

$ mkdir -p $ML_PATH

(3)   安装库模块和依赖,采用国内豆瓣的镜像,国外的容易失败。pip是python自带的包管理器,可以通过命令下载模块和依赖。这样下载

pip3 install --upgrade matplotlib jupyter numpy pandas scipy scikit-learn -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

pip3安装默认路径是python的安装目录下的的依赖库路径D:\Python\Python37\Lib\site-packages。项目是无法加载这个路径的库的,所以需要用--target指定项目库路径

pip3 install --upgrade numpy -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com --target=D:\Project\python\handson-ml-master\venv\Lib\site-packages

也可以在pycharm上设置下载地址进行下载。具体见博客

https://www.cnblogs.com/bclshuai/p/12488341.html

模块

说明

Jupyter

Jupyter NoteBook 是个web应用程序,可以在网页上查看编辑运行程序,以文档化的形式展示代码,可以实时运行,图形化展示数据。用于数据清理和转换,数值魔力,统计建模,机器学习。文件后缀为.ipynb,启动notebook用jupyter notebook命令

Matplotlib

Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形可以生成绘图,直方图,功率谱,条形图,错误图,散点图等

numpy

Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵。提供了许多高级的数值编程工具,如:矩阵数据类型,矢量处理,以及精密的运算库

Pandas

是基于NumPy 的一种工具,为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。它是使Python成为强大而高效的数据分析环境的重要因素之一。

Scipy

Scipy是一个用于数学、科学、工程领域的常用软件包,可以处理插值、积分、优化、图像处理、常微分方程数值解的求解、信号处理等问题。它用于有效计算Numpy矩阵。

 

 

 

jupyter nbconvert --to script 02_end_to_end_machine_learning_project.ipynb

启动notebook的方法

有两种,原理都相同,启动jupyter的服务,进入目录,读取文件,运行文件。

(1)在cmd命令行输入jupyter notebook,会启动Jupyter   服务器,运行在终端上,监听8888端口。你可以用浏览器打 开       http://localhost:8888/ 。然后可以咋浏览器中点击new创建新的ipynb文件,进行编写代码和网页上测试运行。

(2)在pycharm的terminal窗口输入jupyter notebook,也会启动服务,一台电脑只能启动一个服务,所以要关闭之前的cmd窗口。

 

 

 

打开工程目录

 

 

 

打开文件件01_the_machine_learning_landscape.ipynb,然后点击运行按钮,单步执行代码,会获取数据画出图形。

 

 

 

1.5.1         下载数据

一般是要连接数据库获取数据,本文直接从github下载一个数据压缩包,里面是CSV数据库文件。

(1)下载数据文件

import   os

import   tarfile from   six.moves     #压缩文件处理

import   urllib # url下载操作

DOWNLOAD_ROOT      =       "https://raw.githubusercontent.com/ageron/handson-ml/master/" HOUSING_PATH      =     "datasets/housing" HOUSING_URL     =       DOWNLOAD_ROOT      +     HOUSING_PATH      +       "/housing.tgz"

def fetch_housing_data(housing_url=HOUSING_URL,housing_path=HOUSING_PATH):                           

if     not  os.path.isdir(housing_path):                                                            os.makedirs(housing_path)#如果不存在则创建数据目录                          

tgz_path =     os.path.join(housing_path,      "housing.tgz")#产生tgz文件路径     urllib.request.urlretrieve(housing_url,  tgz_path)#下载压缩文件                          

housing_tgz =     tarfile.open(tgz_path)#打开压缩文件                       housing_tgz.extractall(path=housing_path)#解压压缩文件                       

housing_tgz.close()

(2)读取数据

import pandas as pd

def load_housing_data(housing_path=HOUSING_PATH):
    csv_path = os.path.join(housing_path, "housing.csv")
    return pd.read_csv(csv_path)

#%%

housing = load_housing_data()
housing.head()

(3)查看数据

#%%查看字段定义属性

housing.info()

#%%查看字段ocean_proximity有那些值,每个值的统计分布

housing["ocean_proximity"].value_counts()

#%%查看数据表中每个字段的平均值,最大最小值,分布区间等

housing.describe()

#%%matplotlib  inline
#指定matplotlib使用jupyter的后端渲染图片
%matplotlib inline
import matplotlib.pyplot as plt
#画出每个属性的柱状图
housing.hist(bins=50, figsize=(20,15))
save_fig("attribute_histogram_plots")
plt.show()

1.6  创建测试集

选用机器模型不能按照测试集的数据归类选择模型,否则容易测试正常,实际应用很糟。测试集需要保持固定性,不同次训练测试,测试集的内容不变,需要采用固定的随机因子进行采样。

(1)   随机采样,每次获取到的测试都不一样。

#随机采样,用于说明
def split_train_test(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    test_indices = shuffled_indices[:test_set_size]
    train_indices = shuffled_indices[test_set_size:]
    return data.iloc[train_indices], data.iloc[test_indices]

#%%随机采样

train_set, test_set = split_train_test(housing, 0.2)
print(len(train_set), "train +", len(test_set), "test")

 

(2)   固定的随机种子采样。随机采样每次采集的测试都不同,可以第一次采集后保存,或者采用固定的随机种子采样。

#%%
#不同次训练测试,测试集的内容不变,需要采用固定的随机因子进行采样。
# to make this notebook's output identical at every run
np.random.seed(42)

 

(3)   数据id哈希值计算采样。如果数据集更新,或者进行了顺序调整,则又会产生不同的测试集。可以根据每条记录的id值计算出哈希值,最后一个字节小于51(256的20%)的作为测试集数据,这样无论数据集怎么调整变化,只要每条记录的id值不变,最后都可以获取到相同的数据集。id可以有很多种。

#%%通过id计算来采样

from zlib import crc32

def test_set_check(identifier, test_ratio):
    return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio))
    return data.loc[~in_test_set], data.loc[in_test_set]

#%% md

The implementation of `test_set_check()` above works fine in both Python 2 and Python 3. In earlier releases, the following implementation was proposed, which supported any hash function, but was much slower and did not support Python 2:

#%%采用id的hash值来采样

import hashlib

def test_set_check(identifier, test_ratio, hash=hashlib.md5):
    return hash(np.int64(identifier)).digest()[-1] < 256 * test_ratio

#%% md

If you want an implementation that supports any hash function and is compatible with both Python 2 and Python 3, here is one:

#%%

def test_set_check(identifier, test_ratio, hash=hashlib.md5):
    return bytearray(hash(np.int64(identifier)).digest())[-1] < 256 * test_ratio

#%%

housing_with_id = housing.reset_index()   # adds an `index` column
train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "index")

 

(4)   经纬度计算值采样。如果没有id值,可以根据字段经纬度去计算判断。

housing_with_id["id"] = housing["longitude"] * 1000 + housing["latitude"]
train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "id")

(5)   Scikit-Learn自带的采样函数train_test_split它有一个  random_state      参数,可以设定前面讲过的随机生成器种子;第二,你可 以将种子传递给多个行数相同的数据集,可以在相同的索引上分割数据集

#%%使用sklearn的train_test_split函数进行采样分类

from sklearn.model_selection import train_test_split

train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

#%%

 

(6)   分层采样。先把人按照不同的收入区间进行分类,再根据不同区间内的人数比例进行采样。男女比例是3:1,则在男生里面选择75%的人,女生里面选择25%的人。


housing["income_cat"] = np.ceil(housing["median_income"] / 1.5)
# Label those above 5 as 5
housing["income_cat"].where(housing["income_cat"] < 5, 5.0, inplace=True)
```

#%%按照收入进行分类,每个收入区间有多少人

housing["income_cat"] = pd.cut(housing["median_income"],
                               bins=[0., 1.5, 3.0, 4.5, 6., np.inf],
                               labels=[1, 2, 3, 4, 5])

#%%

housing["income_cat"].value_counts()

#%%

housing["income_cat"].hist()

#%%根据每个区间人数按照比例进行分层采样。

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, housing["income_cat"]):
    strat_train_set = housing.loc[train_index]
    strat_test_set = housing.loc[test_index]

#%%

1.7  经纬度数据可视化

画出经纬度图像,查看规律。

housing.plot(kind="scatter",   x="longitude",    y="latitude", alpha=0.4,                        s=housing["population"]/100, label="population",                        c="median_house_value",      cmap=plt.get_cmap("jet"),       colorbar=True, ) plt.legend()

 

 

 

1.8  查找关联性

因为数据集并不是非常大,你可以很容易地使用       corr()     方法计算出每对属性间的标准相关系 数(standard correlation   coefficient,也称作皮尔逊相关系数):

corr_matrix =     housing.corr()

(1)查看各属性与median_house_value的相关性:

>>> corr_matrix["median_house_value"].sort_values(ascending=False)

median_house_value                      1.000000

median_income                                                          0.687170

total_rooms                                                                        0.135231 housing_median_age                      0.114220

households                                                                                0.064702 total_bedrooms                                                    0.047865

population                                                                          -0.026699

longitude                                                                                   -0.047279

latitude                                                                                      -0.142826

 

(2)用Pandas的scatter_matrix    函数画出主要属性的图像

from      pandas.tools.plotting import   scatter_matrix

attributes      =     ["median_house_value",  "median_income",       "total_rooms",                                                                                               "housing_median_age"] scatter_matrix(housing[attributes],       figsize=(12,  8))

1.9  组合属性关联性测试

创建一些关联属性,例如每个房子的房间数,每个房间的床数,每个房子的人口数。

housing["rooms_per_household"]  =       housing["total_rooms"]/housing["households"] housing["bedrooms_per_room"]    =       housing["total_bedrooms"]/housing["total_rooms"] housing["population_per_household"]=housing["population"]/housing["households"]

 

重新计算关联关系,得到新的关联性排列,rooms_per_household变成第三关联参数,即每个房子的房间数

>>> corr_matrix  =     housing.corr()

>>> corr_matrix["median_house_value"].sort_values(ascending=False) median_house_value                                                                1.000000 median_income                                                                        0.687170

rooms_per_household                                                             0.199343

total_rooms                                                                               0.135231 housing_median_age                                                                0.114220

households                                                                                0.064702 total_bedrooms                                                                         0.047865 population_per_household                                                       -0.021984

population                                                                                 0.026699

longitude                                                                                   -0.047279

latitude                                                                                      -0.142826

bedrooms_per_room                                                                 -0.260070

Name:   median_house_value, dtype:    float64

 

1.10         数据训练准备

1.10.1      数据转换函数

创建一些数据转换函数,方便地进行重复数据转换,可以用于其他项目。

1.10.2      数据清洗缺失值记录

去除处理

数据中有些属性没有,会对训练造成影响,处理方法有

(1)   去掉缺失的记录

housing.dropna(subset=["total_bedrooms"])                           #     选项1

(2)   去掉整个属性列

housing.drop("total_bedrooms",    axis=1)                                            #       选项2

(3)   用0,平均值,中位数去填充

median  =     housing["total_bedrooms"].median() housing["total_bedrooms"].fillna(median)                              #     选项3

 

Scikit-Learn      提供了一个方便的类来处理缺失值:Imputer

(1)   新建一个Imputer对象

(2)   imputer.fit()计算中位数

(3)   imputer.transform()缺省值替换为中位数

#%%创建缺失值处理对象

try:
    from sklearn.impute import SimpleImputer # Scikit-Learn 0.20+
except ImportError:
    from sklearn.preprocessing import Imputer as SimpleImputer

imputer = SimpleImputer(strategy="median")

#%% md

Remove the text attribute because median can only be calculated on numerical attributes:

#%%只有数值才能计算中位数,去除文本变量ocean_proximity

housing_num = housing.drop('ocean_proximity', axis=1)
# alternatively: housing_num = housing.select_dtypes(include=[np.number])

#%%拟合运算

imputer.fit(housing_num)

#%%imputer 计算出了每个属性的中位数,并将结果保存在了实例变量  statistics_    中。

imputer.statistics_

#%% md

Check that this is the same as manually computing the median of each attribute:

#%%

housing_num.median().values

#%% md

Transform the training set:

#%%处理数据,缺省值替换为中位数

X = imputer.transform(housing_num)

 

 

1.11         Scikit-Learn  的  API     设计

接口一致性

(1)   估计器(timator)。imputer就是一个估计器,基于数据集对一些参数进行估计的对象为估计器。

(2)   转换器transformer。对数据集进行转化换。通过transferm()方法

(3)   预测器(predictor)。根据给出的数据集做出预测。有一个redict()方法。

1.12         处理文本和类别属性

需要将文本属性转换为数字属性,方便计算。

Scikit-Learn 为这个任务提供了一个转换器    LabelEncoder     :

>>> from      sklearn.preprocessing import   LabelEncoder

>>> encoder =     LabelEncoder()

>>> housing_cat  =     housing["ocean_proximity"] #获取属性列

>>> housing_cat_encoded =     encoder.fit_transform(housing_cat) #转换为数字

>>> housing_cat_encoded#输出展示

array([1, 1,    4,    ...,   1,    0,    3])

1.12.1      文本转换方法

(1)   单文本转换。

from      sklearn.preprocessing import   LabelEncoder >>>     encoder       =LabelEncoder()

housing_cat_encoded =     encoder.fit_transform(housing_cat)

(2)   多文本列转换。

housing_cat_encoded =     housing_cat.factorize()

(3)   独热编码OneHotEncoder

列中有很多个值:’1H    OCEAN'       'INLAND'     'ISLAND'     'NEAR       BAY'     'NEAR   OCEAN',把列转换为一个矩阵,只有值与对应位置的值相等才为1,其他都等于0。例如INLAND对的行为[0,1,0,0,0]

>>> from      sklearn.preprocessing import   OneHotEncoder >>> encoder       =     OneHotEncoder() #新建编码对象

>>> housing_cat_1hot      =       encoder.fit_transform(housing_cat_encoded.reshape(-1,1)) #进行转换

>>> housing_cat_1hot#返回一个矩阵

 <16513x5   sparse    matrix   of    type '<class   'numpy.float64'>'                     with       16513    stored    elements       in    Compressed Sparse       Row       format>

 

housing_cat_1hot.toarray() #转换为数组n行5列的二维数组。

(4)LabelBinarizer实现一步执行这两个转换(从文本分类到整数分类,再从整 数分类到独热向量):

>>> from      sklearn.preprocessing import   LabelBinarizer >>>   encoder       =     LabelBinarizer()

>>> housing_cat_1hot=encoder.fit_transform(housing_cat)

输出结果和(3)中的相同。

array([[0,      1,    0,    0,    0],                                            

[0,   1,    0,    0,    0],                                            

[0,   0,    0,    0,    1],                                            

...,                                            

[0,   1,    0,    0,    0],                                            

[1,   0,    0,    0,    0],                                            

[0,   0,    0,    1,    0]])

(5)CategoricalEncoder实现多文本列转换

#from    sklearn.preprocessing import   CategoricalEncoder   #     in       future    versions of    Sci kit-Learn

cat_encoder =     CategoricalEncoder()

housing_cat_reshaped      =     housing_cat.values.reshape(-1,      1)

housing_cat_1hot      =       cat_encoder.fit_transform(housing_cat_reshaped) housing_cat_1hot

1.13         特征缩放

数据的取值范围不同,例如总房间数分布范围是6到39320,而收入中位数只分布在0到15,机器学习算法的性能会不好。所以需要将所有属性缩放为相同的度量。有两种常见的方法可以让所有的属性有相同的量度:

线性函数归一化(Min-Max scaling:线性函数归一化(许多人称其为归一化(normalization))很简单:值被转变、重新缩放, 直到范围变成  0     到   1。我们通过减去最小值,然后再除以最大值与最小值的差值,来进行归 一化。Scikit-Learn       提供了一个转换器       MinMaxScaler    来实现这个功能

标准化(standardization):首先减去平均值(所以标准化值的平均值总是      0),然后除以方差,使得到 的分布具有单位方差。Scikit-Learn     提供了一个转换 器 StandardScaler    来进行标准化。

1.14         转换流水线

1.14.1      多个转换合成一个流水线

Scikit-Learn 提供 了类   Pipeline,将多个转换合成一个流水线,按照顺序执行。

from      sklearn.pipeline  import   Pipeline from       sklearn.preprocessing import   StandardScaler

num_pipeline      =     Pipeline([                                                     ('imputer',     Imputer(strategy="median")),                                                  ('attribs_adder',   CombinedAttributesAdder()),                                                  ('std_scaler', StandardScaler()),                                                       ])

housing_num_tr  =     num_pipeline.fit_transform(housing_num)

 

1.14.2      FeatureUnion将多个流水线转换为同一个流水线

from      sklearn.pipeline  import   FeatureUnion

num_attribs  =     list(housing_num) cat_attribs  =     ["ocean_proximity"]

#流水线1

num_pipeline      =     Pipeline([('selector',       DataFrameSelector(num_attribs)),                                                  ('imputer',     Imputer(strategy="median")),                                                  ('attribs_adder',   CombinedAttributesAdder()),                                                  ('std_scaler', StandardScaler()),                           ])

#流水线2

cat_pipeline =     Pipeline([('selector',   DataFrameSelector(cat_attribs)),                                                   ('label_binarizer', LabelBinarizer()),])

#合并流水线

full_pipeline =     FeatureUnion(transformer_list=[                                                   ("num_pipeline", num_pipeline),                                                    ("cat_pipeline",  cat_pipeline),                           ])

#运行流水线

housing_prepared      =     full_pipeline.fit_transform(housing)

 

1.15         选择并训练模型

1.15.1      采用线性回归模型去拟合

(1)模型训练

from      sklearn.linear_model import   LinearRegression

housing_labels    =     strat_train_set["median_house_value"].copy()#训练集的房屋中位数原始值

lin_reg   =     LinearRegression()

lin_reg.fit(housing_prepared,  housing_labels)

(2)取前五个值验证预测值

>>> some_data    =     housing.iloc[:5]#取前5个训练值

>>>some_labels =     housing_labels.iloc[:5]#取前五个原始值

>>>some_data_prepared  =     full_pipeline.transform(some_data) #转换

>>> print("Predictions:\t", lin_reg.predict(some_data_prepared)) #模型预测

Predictions:  [      303104.               44800.          308928.        294208.        368704.]

>>> print("Labels:\t\t",     list(some_labels))#目标原始值展示

Labels:  [359400.0,    69700.0,       302100.0,     301300.0,     351900.0]

(3)采用均方差验证预测值和原始值之间的差异

>>> from      sklearn.metrics   import   mean_squared_error

>>> housing_predictions  =     lin_reg.predict(housing_prepared) #获取预测值

>>> lin_mse =     mean_squared_error(housing_labels,       housing_predictions) #求均方差

>>> lin_rmse       =     np.sqrt(lin_mse)

 >>>lin_rmse

68628.413493824875

均方差太大,欠拟合。

1.15.2      决策树回归模型训练

(1)模型训练

from      sklearn.tree  import   DecisionTreeRegressor

tree_reg =     DecisionTreeRegressor()

tree_reg.fit(housing_prepared, housing_labels)

(2)均方差验证

>>> housing_predictions  =     tree_reg.predict(housing_prepared)

 >>>     tree_mse      =     mean_squared_error(housing_labels,       housing_predictions)

 >>>     tree_rmse     =     np.sqrt(tree_mse)

>>> tree_rmse 0.0

均方差为0,这里用的是训练集去验证,过拟合,用测试集去测试更好。

 

1.15.3      使用交叉验证做更佳的评估

K折交叉验证(K-fold  cross-validation)上述的训练方法并不是很好,一般是将训练集分成K个子集,1个子集做测试集,其他K-1个子集做训练集,做K次训练和验证。

(1)模型训练

from      sklearn.model_selection   import   cross_val_score

 scores  =     cross_val_score(tree_reg, housing_prepared,       housing_labels,   scoring="neg_mean_squared_error",    cv=10)

rmse_scores =     np.sqrt(-scores)

(2)定义一个显示评分的函数

def  display_scores(scores):

print("Scores:",      scores)               

print("Mean:", scores.mean()) ...                           

print("Standard      deviation:",  scores.std())

 

(3)调用函数显示评分

display_scores(tree_rmse_scores) Scores:   [      74678.4916885                 64766.2398337                 69632.86942005        69166.67693232                                                                71486.76507766        73321.65695983        71860.04741226        71086.32691692                                                                76934.2726093                 69060.93319262]

 Mean:  71199.4280043 Standard  deviation:     3202.70522793

(4)   线性模型的10折交叉验证对比

lin_scores     =     cross_val_score(lin_reg,   housing_prepared,       housing_labels,

                                                                                                                                                                                                           scoring="neg_mean_squared_error",    cv=10)

>>> lin_rmse_scores  =     np.sqrt(-lin_scores)

 >>>     display_scores(lin_rmse_scores)

 Scores: [      70423.5893262                 65804.84913139        66620.84314068        72510.11362141                                                                66414.74423281        71958.89083606        67624.90198297              67825.36117664                                                                72512.36533141        68028.11688067]

Mean:    68972.377566 Standard    deviation:     2493.98819069

线性模型比决策树模型的均值和方差更小。决策树模型过拟合很严重,它的性能比线性回归模型还差。

1.15.4      随机森林模型

随机森林是通过用特 征的随机子集训练许多决策树。在其它多个模型之上建立模型称为集成学习(Ensemble Learning)

>>> from      sklearn.ensemble import   RandomForestRegressor

>>> forest_reg     =     RandomForestRegressor()

>>> forest_reg.fit(housing_prepared,    housing_labels)

>>> forest_rmse 22542.396440343684

>>> display_scores(forest_rmse_scores) Scores: [      53789.2879722                 50256.19806622        52521.55342602        53237.44937943                                                                52428.82176158        55854.61222549        52158.02291609        50093.66125649                                                                53240.80406125       52761.50852822]

 Mean:  52634.1919593 Standard  deviation:     1576.20472269

 

1.16         模型微调

对模型的参数进行调整,优化模型,减少误差。手动调整参数效率低而且不容易获得较优的参数。可以采用下面几种方法来获取最优参数。

1.16.1      网格检索GridSearchCV

将参数可能的取值放入一个参数数组中,每个参数有几个值,如下面的参数网格,{'n_estimators': [3,   10,  30], 'max_features':    [2,   4,    6,       8]}有3*4=12种组合。{'bootstrap':    [False],  'n_estimators':     [3,       10], 'max_features':    [2,   3,4]}+ 1*2*3=6种组合。一共有18组参数用来训练数据集。每组参数再采用5折交叉验证,则需要进行18*5=90论训练。

from      sklearn.model_selection   import   GridSearchCV

param_grid =     [      {'n_estimators':   [3,   10,  30], 'max_features':    [2,       4,    6,    8]}, {'bootstrap': [False],  'n_estimators':     [3,   10],       'max_features':    [2,   3,    4]},        ]

forest_reg     =     RandomForestRegressor()

grid_search  =     GridSearchCV(forest_reg,     param_grid, cv=5,                                                                                                                                                                                           scoring='neg_mean_squared_error')

grid_search.fit(housing_prepared, housing_labels)

#查看最优参数

>>> grid_search.best_params_

{'max_features':  6,    'n_estimators':     30}

#查看最佳估计器

>>> grid_search.best_estimator_

RandomForestRegressor(bootstrap=True,   criterion='mse',       max_depth=None,                                                                           max_features=6, max_leaf_nodes=None,    min_samples_leaf=1,                                                                       min_samples_split=2,       min_weight_fraction_leaf=0.0,                                                                            n_estimators=30, n_jobs=1,     oob_score=False,       random_state=None,                                                                       verbose=0,   warm_start=False)

#查看所有评分

>>> cvres      =     grid_search.cv_results_ ... for  mean_score, params  in       zip(cvres["mean_test_score"], cvres["params"]): ...                               print(np.sqrt(-mean_score),     params) ...

 64912.0351358 {'max_features':  2,    'n_estimators':     3}

55535.2786524   {'max_features':  2,    'n_estimators':     10}

52940.2696165   {'max_features':  2,    'n_estimators':     30}

60384.0908354   {'max_features':  4,    'n_estimators':     3}

52709.9199934   {'max_features':  4,    'n_estimators':     10}

50503.5985321   {'max_features':  4,    'n_estimators':     30}

59058.1153485   {'max_features':  6,    'n_estimators':     3}

52172.0292957   {'max_features':  6,    'n_estimators':     10}

49958.9555932   {'max_features':       6,    'n_estimators':  30} #最优参数

59122.260006     {'max_features':  8,    'n_estimators':     3}

52441.5896087   {'max_features':  8,    'n_estimators':     10}

50041.4899416   {'max_features':  8,    'n_estimators':     30}

62371.1221202   {'bootstrap':  False,     'max_features':    2,       'n_estimators':     3} 54572.2557534     {'bootstrap':  False,       'max_features':    2,    'n_estimators':     10} 59634.0533132       {'bootstrap':  False,     'max_features':    3,    'n_estimators':     3} 52456.0883904   {'bootstrap':  False,     'max_features':    3,       'n_estimators':     10} 58825.665239     {'bootstrap':  False,       'max_features':    4,    'n_estimators':     3} 52012.9945396       {'bootstrap':  False,     'max_features':    4,    'n_estimators':     10}

 

1.16.2      随机搜索RandomizedSearchCV

当超参数的搜索空间很大时,不适合用网格搜索,适合用RandomizedSearchCV,它不 是尝试所有可能的组合,而是通过选择每个超参数的一个随机值的特定数量的随机组合。通过设置搜索次数控制计算量。

 

1.17         用测试集评估系统

用网格检索的最优模型计算预测值和实际值进行比较,计算出误差和均方差。

final_model =     grid_search.best_estimator_

X_test    =     strat_test_set.drop("median_house_value", axis=1) #去除房价中位数的数据

y_test    =     strat_test_set["median_house_value"].copy()#实际值

X_test_prepared =     full_pipeline.transform(X_test)#测试集进行同等转换

final_predictions =     final_model.predict(X_test_prepared)#计算预测值

final_mse     =     mean_squared_error(y_test,    final_predictions) #误差

final_rmse    =     np.sqrt(final_mse)                  

#     =>  evaluates      to    48,209.6

 

1.18         启动、监控、维护系统

启动系统用于实际应用, 编写监控程序监测系统的系统,咋系统性能下降时给出报警。模型性能会下降,除非模型用新数据定期训练。你还要评估系统输入数据的质量,低质量的信号(比如失灵的传感器发送随机值, 或另一个团队的输出停滞),系统的表现会逐渐变差,但可能需要一段时间,系统的表现才 能下降到一定程度,触发警报。

自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

https://www.cnblogs.com/bclshuai/p/11380657.html

 

posted @ 2020-03-30 21:21  一字千金  阅读(1320)  评论(1编辑  收藏  举报