机器学习完整流程

目录

1.项目概述

1.1.划定问题

1.2.选择性能指标

1.3.核实假设

2.获取数据

2.1.创建工作空间

2.2.下载数据

2.3.快速查看数据结构

2.4.创建测试集

3.数据探索并可视化数据,发现规律

3.1.查找关联

3.2.属性组合试验

4.为机器学习模型学习准备数据

4.1.数据清洗

4.2.处理文本和类别属性

4.3.自定义转换器

4.4.特征缩放

4.5.转换流水线

5.选择模型,进行训练

5.1.在训练集上训练和评估

5.2.交叉验证做更佳的评估

6.微调模型

6.1.网格搜索

6.2.随机搜索

6.3.集成方法

6.4.分析最佳模型和误差

6.5.用测试集评估系统

7.给出解决方案

8.部署、监控、维护系统


1.项目概述

数据的有哪些特征类别,将要建立的模型需要预测什么

1.1.划定问题

第一个问题就是项目的商业目标是什么,建立模型不是最终目的,建立模型的目的是公司的收益和将要处理的问题

第二个问题就是现有解决方案的性能,以便对将要建立的模型性能有个大概预期

 

1.2.选择性能指标

RMSE和MAE都是测量预测值和目标值两个向量距离的方法,有多种测量向量距离,或范式的方法:

欧几里得范数的平方和的根(RMSE),计算对应与e1范数的绝对值之和(MAE),又称为曼哈顿范数,测量列城市中的两点,沿着矩形边形行走的距离

范数的指数越高,就越关注大的值而忽略小的值,这就是RMSE比MAE对异常值更命案,但当异常值是指数分布(类似正太分布),RMSE表现会更高

范数(norm):它常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小

回归问题的常用性能指标是均方根误差(RMSE),均方根误差测量的是系统预测的标准差

当异常值较多时,可以用到平均绝对误差(MAE,Mean Absolute Error)

1.3.核实假设

最后,最好列出并核对迄今作出的假设,这样可以尽早发现问题,例如,你的系统输出会传入下游机器学习系统,我们的假设会被下游机器学习系统当作输入使用,如果下游系统实际需要的是分类值(高,中,低),这就是你就需要假设分类问题,而不是回归问题

2.获取数据

2.1.创建工作空间

安装相关工具,准备相关初始数据

2.2.下载数据

import os
import tarfile
import pandas as pd
from six.moves import urllib
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):
'''在工作空间创建一个目录,下载tar文件,然后解压出csv文件'''
	if	not	os.path.isdir(housing_path):
		os.makedirs(housing_path)
		tgz_path = os.path.join(housing_path, "housing.tgz")
		urllib.request.urlretrieve(housing_url,	tgz_path)
		housing_tgz	= tarfile.open(tgz_path)
		housing_tgz.extractall(path=housing_path)
		housing_tgz.close()

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

2.3.快速查看数据结构及其可视化

data.head()
data.info()
data.value_counts
data.describe

import	matplotlib.pyplot	as	plt
housing.hist(bins=50,	figsize=(20,15))
plt.show()

2.4.创建测试集

分割数据:如果查看了测试集,就会根据测试集的规律来选择某个机器学习类型,再当你使用测试集来评估误差时,就会导致过于乐观,而实际部署的系统表现就会差,这称为数据透视偏差。

创建测试集很简单,只是简单从数据集内随机抽取一部分数据即可,一般是数据集的20%,放到一边:

import numpy as np
def	split_train_test(data,test_ratio):  #scikit-learn提供列此方法
	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")
16512	train	+	4128	test

3.数据探索并可视化数据,发现规律

3.1.查找关联

标准相关系数:standard correlation coeficent,又称为皮尔逊相关系数。使用corr(两类)或corr_matrix(1和其他)方法,相关系数范围是-1~1,1表示正相关,即x大y大,-1表示负相关,x大y小,为0表示没有相关

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))

3.2.特征组合试验

将多个特征组合为一个特征,如将单价和数量组合为总价

data['总价']=data['单价']*data['数量']

4.为机器学习模型学习准备数据

4.1.数据清洗

4.11.首先需要将数据集的标签和样本拆分,使用drop删掉标签

housing=strat_train_set.drop("median_house_value",axis=1)
housing_labels=strat_train_set["median_house_value"]

4.12.大多数机器学习算法不能处理缺失值,因此先创建一个函数来处理特征值缺失

housing.dropna(subset=["total_bedrooms"])  #删除缺失值所在行
housing.drop("total_bedrooms",	axis=1)  #删除整个属性
median	=	housing["total_bedrooms"].median()  
housing["total_bedrooms"].fillna(median)  #填充缺失,0或中位数或平均数

 scikit-learn提供列缺失值处理方法Imputer

from sklearn.preprocessing import Imputer
imputer = Imputer(strategy="median")  #实例化Imputer
imputer.fit(housing_num)  #使用fit方法,将Imputer实例拟合到训练数据

#Imputer计算出了houseing_num样本集所有特征的中位数,现在即将现在只有某个特征存在缺失值,但不能保证其他特征不存在缺失值,所以需要进一步扩充到其他特征,即使用转换器,结果返回一个包含转换值的普通数组

imputer.statistics_
array([	-118.51	,	34.26	,	29.	,	2119.	,	433.	,	1164.	,	408.	,	3.5414])
housing_num.median().values
array([	-118.51	,	34.26	,	29.	,	2119.	,	433.	,	1164.	,	408.	,	3.5414])
X = imputer.transform(housing_num)
#可以将其放回到DataFrame中
housing_tr = pd.DataFrame(X,	columns=housing_num.columns)

4.2.处理文本和类别属性

文本属性不能计算中位数等数学涵义,而机器学习大多时间需要和数值打交道,所以我们需要将文本属性转换为数值

scikit-learn为文本转数值的任务提供了一个转换器LabelEncoder,使用算法会认为两个邻近的值比疏远的值更相近,但在文本/类别属性来说,显然是错误的,要解决这类问题,可以给每个属性创建一个二元分类,即只存在0类和1类,因为只有一个编码为1(热),其余编码为0(冷),这称作独热编码One-HotEncoding,scikit-learn提供了一个编码器OneHotEncoder,用于将整数分类值转换为独热向量,注意:fit_transform()用于2D数组,所以需要先转换,使用LabelBinarizer可以同时实现两步(从文本到整数分类,再从整数分类到独热向量)

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])  #单列,产生一维数组

from sklearn.preprocessing import OneHotEncoder  
encoder = OneHotEncoder()  #fit_transform只能编码2D数组,所以需要reshape重置
housing_cat_1hot=encoder.fit_transform(housing_cat_encoded.reshape(-1,1))
housing_cat_1hot  #输出结果是一个scipy稀疏矩阵,而非numpy数组
<16513x5	sparse	matrix	of	type	''
				with	16513	stored	elements	in	Compressed	Sparse	Row	format>

from sklearn.preprocessing import LabelBinarizer
encoder	= LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(housing_cat)
housing_cat_1hot  #返回的结果是一个密集的numpy数组,设置参数sparse_output=True可以转为稀疏矩阵
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]])

4.3.自定义转换器

scikit-learn有很多有用的转换器,但有时候还是需要自己手动写转换器,比如自定义的数据清理和特征组合,需要让自制的转换器和scikit-learn的组件(如流水线)一起工作,因为scikit-learn是依赖鸭子类型的(不是继承),所以只需要执行三个方法:

fit(),返回self,transfrom和fit_transform,通过添加TransformerMixin作为基类,可以很容易得到最后一个

from sklearn.base import BaseEstimator,TransformerMixin
rooms_ix,bedrooms_ix,population_ix,household_ix	=3,4,5,6
class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
    def	__init__(self,	add_bedrooms_per_room=True):  #超参数add_bedrooms_per_room								
        self.add_bedrooms_per_room = add_bedrooms_per_room
				def	fit(self, X, y=None):
				    return	self		#	nothing	else	to	do
				def	transform(self,	X,	y=None):
					rooms_per_household =X[:,rooms_ix]/X[:,household_ix]
					population_per_household = X[:,population_ix]/X[:,household_ix]
					if self.add_bedrooms_per_room:
						bedrooms_per_room	=	X[:,	bedrooms_ix]	/	X[:,	rooms_ix]
					return np.c_[X,rooms_per_household,oppulation_per_household,bedrooms_per_room]														
					else:
					   return np.c_[X,rooms_per_household,population_per_household]
attr_adder = CombinedAttributesAdder(add_bedrooms_per_room=False)
housing_extra_attribs = attr_adder.transform(housing.values)

4.4.特征缩放

数据要做的最重要转换之一就是特征缩放,当输入的数值属性度量值不同时,机器学习算法的性能都不会好,比如总房间数是6-33234,而收入中位数是0-15,有两种常见的方法可以让所有的属性有相同的度量:

线性函数归一化(Min-Max scaling)和标准化(standardization)

4.4.1归一化

归一化,normolization,即值被转变,重新缩放,知道值的范围在0-1之间,我们通过减去最小值,然后再除以最大值和最小值的差值来进行归一化,scikit-learn提供了一个转换器MinMxaScaler来实现这个功能,它有一个超参数feature_range,可以改变范围,让值不是在0-1

4.4.2标准化

标准化,standardization,即首先减去平均值(所以标准化值的平均值总是0),然后除以方差,使得到的分布具有单位方差,与归一化不同,标准化不会把值限定在某个范围,标准化的优点是受异常值的影响较小,scikit-learn提供了一个转换器StandardScaler来进行标准化

4.5.转换流水线

特征工程可能存在多个数据转换步骤,需要按一定顺序执行,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)

#Pipeline构造器需要定义一个表示步骤顺序的名称/估计器对的列表,除了最后一个估计器,其余都要是转换器(即他们都要由fit_transform方法),名字可以随便取
#当调用流水线的fit()方法,就会对所有转换器顺序调用fit_transform()方法,将每次调用的输出作为参数传递给下一个转换器调用,知道最后一个估计器,使用fit()方法

#这个例子中的最后一个估计器是standardScaler,它是一个转换器,因此流水线有一个transform()方法,可以顺序对数据做所有转换(它还有一个fit_transform方法可以使用,就不必调用fit后再调用transform方法)

 有了一个是对数值的流水线,还需要对分类值进行应用LabelBinarizer:如何将这么转换为流水线?scikit-learn提供了一个类featureUnion实现这个功能,给featureUnion一列转换器(可以是所有转换器),当调用它的transform方法,每个转换器的transform会被并行执行,等待输出,然后将输出合并起来,并返回结果,一个完整的处理数值和类别属性的流水线如下所示:

from sklearn.pipeline import FeatureUnion
num_attribs = list(housing_num)
cat_attribs = ["ocean_proximity"]
num_pipeline = Pipeline([
	 ('selector',	DataFrameSelector(num_attribs)),
	 ('imputer',	Imputer(strategy="median")),
	 ('attribs_adder',	CombinedAttributesAdder()),
	 ('std_scaler',	StandardScaler()),
	 ])

cat_pipeline = Pipeline([
	 ('selector',	DataFrameSelector(cat_attribs)),
	 ('label_binarizer',	LabelBinarizer()),
	 ])
full_pipeline = FeatureUnion(transformer_list=[
	 ("num_pipeline",	num_pipeline),
	 ("cat_pipeline",	cat_pipeline),	
			])

cat_pipeline = Pipeline([
	 ('selector',	DataFrameSelector(cat_attribs)),
	 ('cat_encoder',	CategoricalEncoder(encoding="onehot-dense")),
	 ])

#运行整个流水线
housing_prepared=full_pipeline.fit_transform(housing)
housing_prepared
array([[0.73225807,	-0.67331551,0.58426443,	...,0.,
0.,		0.],
	[-0.99102923,1.63234656,	-0.92655887,...,0.,
0.,0.],
[...]
housing_prepared.shape
(16513,	17)

 每一个子流水线都以一个选择转换器开始:通过选择对应的属性(数值或类)、丢弃其他的,来转换数据,并将输出DataFrame转换为numpy数组,scikit-learn没有工具来处理DataFrame,因此需要自定义一个简单的转换器

from sklearn.base	import	BaseEstimator,	TransformerMixin
class	DataFrameSelector(BaseEstimator,	TransformerMixin):
				def	__init__(self,	attribute_names):
								self.attribute_names	=	attribute_names
				def	fit(self,	X,	y=None):
								return	self
				def	transform(self,	X):
								return	X[self.attribute_names].values

5.选择模型,进行训练

5.1.在训练集上训练和评估

L1,Lasso回归和L2,岭回归是正则化项,又叫做罚项,是为了限制模型的参数,防止模型过拟合而加在损失函数后面的一项。

二、区别:

  1.L1是模型各个参数的绝对值之和。

   L2是模型各个参数的平方和的开方值。

  2.L1会趋向于产生少量的特征,而其他的特征都是0.

    因为最优的参数值很大概率出现在坐标轴上,这样就会导致某一维的权重为0 ,产生稀疏权重矩阵

     L2会选择更多的特征,这些特征都会接近于0。  

          最优的参数值很小概率出现在坐标轴上,因此每一维的参数都不会是0。当最小化||w||时,就会使每一项趋近于0

from sklearn.linear_model import LinearRegression
lin_reg	= LinearRegression()
lin_reg.fit(housing_prepared, housing_labels)  #完成线性回归模型

some_data=housing.iloc[: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]
#对比结果可知,预测结果并不准确,比如,69700比4480超过列50%,可以继续用scikit-learn的的mean_squared_error函数来计算下这个回归模型的RMSE(均方根误差):

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
#预测误差达到68628,这个一个欠拟合模型,意味着特征没有提供足够多的信息做一个好的预测,或者模型并不强大,修复一个欠拟合模型主要方法是选一个更佳强大的模型,或者给模型提供更好的特征,或者去除模型上的限制,而这个模型没有加限制(正则化),所以最后一个方法可以排除,可以试试更换一个更强大的模型,比如决策树DecisionTreeRegressor:

from sklearn.tree import DecisionTreeRegressor
tree_reg = DecisionTreeRegressor()
tree_reg.fit(housing_prepared,	housing_labels)

#计算均方根误差误差,误差为0,模型完美是不可能的,只能说明是过拟合的情况,需要进一步处理
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

5.2.交叉验证做更佳的评估

#评估决策树模型的一种方法是使用train_test_split函数来分割测试集,得到一个更小的训练集和验证集,另一中方法是使用交叉验证功能,如K折交叉验证(K-Fold cross-validation):它随机将训练集分成K个子集,称为‘折’,然后评估决策树模型K次,每次选择一个不用的‘折’来做评估,其他K-1个‘折’用来做训练集,返回一个包含10个评分的数组:
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)
def	display_scores(scores):
    print("Scores:",	scores)  #评分
    print("Mean:",	scores.mean())  #评分的准确性,它的平均值
    print("Standard	deviation:",	scores.std())  #评分的标准差

display_scores(tree_rmse_scores)

#交叉验证功能期望的是效用函数(越大越好),而不是损失函数(越低越好),因此得分函数实际上与MSE相反(效用函数是负的),所以sqrt计算的是‘-scores’

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  #比决策树的性能要好

#再继续尝试随机森林模型(RandomForestRegressor),随机森林是通过特征的随机子集训练多个决策树,在其他多个模型之上进行学习,称之为集成学习(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  #比线性模型和决策树的结果要好

#看起来随机森林结果比较好,有希望进一般规整,解决过拟合问题,可以通过简化模型,或给模型加限制(即规整化),或用跟多的数据,在深入规整随机森林之前可以先试试其他算法(支持向量机、神经网络什么的),不要在调参上花费太多时间,目标是先列出一各可能模型列表(2-5个)


#需要保存训练好的模型,要确认有超参数、训练参数,以及交叉验证评分和实际预测值,可以用python的pickle模型,也可以使用Scikit-learn提供的sklearn.externals.joblib,后者序列化大numpy数组更有优势

from sklearn.externals import joblib
joblib.dump(my_model, "my_model.pkl")  #保存
my_model_loaded	=joblib.load("my_model.pkl")  #打开

6.微调模型

假设我们已经完成列上几步的工作,我们有了一个保存有几个可能模型的列表,我们现在就需要对几个模型进行微调,最后确定最佳模型

6.1.网格搜索

使用scikit-learn提供的GridSearchCV进行网格搜索,只需要告诉GridSearchCV要试验哪些参数,要试验哪些参数值,GridSearchCV就能使用交叉验证试验所有可能超参数值的组合,例如,下面的代码搜索了RandomForestRegressor超参数组合

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}

cvres=grid_search.cv_results_  #返回最佳评分
for	mean_score,	params	in	zip(cvres["mean_test_score"],	cvres["params"]):
    print(np.sqrt(-mean_score),	params)

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)

#当不能确定超参数选取哪个范围的值的时候,最好的就是使用10的幂进行微调,如[0.01,0.1,1,10,100]
#当使用GridSearchCV是以refit=True(默认值)开始运行的,则一旦用交叉验证找到了最佳估计器,就会在整体训练集上重新训练,这样得到的才是正真的最佳估计器

#此处得到的MSE是42992,比默认参数的52634要好一些,这就是此模型的最佳参数的结果

6.2.随机搜索

当搜索的超参数值空间非常大时,用网格搜索则计算量非常大,这样是很浪费资源即不实际的,最好的办法是使用随机搜索RandomizedSearchCV,它不会搜索范围内的所有可能组合,而是随机抽取组合,可以设定搜索次数,控制计算量

 

6.3.集成方法

将表现最好的模型组合起来,组合(集成)之后的性能通常会比单独的模型表现更好(向随机森林比决策树表现更好),特别是单独模型的误差类型不同时

 

6.4.分析最佳模型和误差

通过分析最佳模型,常常可以获得对问题的更深的了解,随机森林RandomForestRegressor可以指出每个属性对于准确预测的相对重要性,有了这些信息,我们可以丢弃一些不那么重要的特征,还需要分析模型的误差,搞清楚为什么会有这些误差,以及如何改正问题(添加有用特征,去除无用特征,清洗异常值等方法改正)

feature_importances=grid_search.best_estimator_.feature_importances_
feature_importances
array([7.14156423e-02,6.76139189e-02,4.44260894e-02,
1.66308583e-02,1.66076861e-02,1.82402545e-02,
1.63458761e-02,3.26497987e-01,6.04365775e-02,
1.13055290e-01,7.79324766e-02,1.12166442e-02,
1.53344918e-01,8.41308969e-05,2.68483884e-03,
3.46681181e-03])
#将重要性和属性名放在一起
extra_attribs=["rooms_per_hhold","pop_per_hhold","bedrooms_per_room"]
cat_one_hot_attribs=list(encoder.classes_)
attributes=num_attribs	+	extra_attribs	+	cat_one_hot_attribs
sorted(zip(feature_importances,attributes),	reverse=True)
[(0.32649798665134971,	'median_income'),
(0.15334491760305854,	'INLAND'),
(0.11305529021187399,	'pop_per_hhold'),
...]

6.5.用测试集评估系统

调节完系统后,现在已经有了一个性能比较满意的模型了,现在就可以用测试集评估最后的模型了,:

1.从测试集得到预测值和标签,运行full_pipeline转换数据,调用transform,而不是fit_transform

2.用测试集评估模型

评估模型一般会比交叉验证的效果差一点,如果发生这种情况,不要去试图再调整超参数,因为这样不会让效果在未知的新数据表现的更好。然后就是项目的预上线阶段:需要展示你的方案(重点说明学到了什么,做到了什么,没做到什么,做过什么假设,系统的限制是什么),记录下所有事情,用漂亮的图表和容易记住的表达(比如,收入中位数是房价最重要的预测)

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

7.给出解决方案:部署、监控、维护系统

启动:在模型确定后,已经可以启动系统了,需要为实际生产做好准备,特别是接入输入数据源,并编写测试

监控:还需要编写监控代码,以固定时间间隔检测系统的实时表现,当发生下降时触发警报,能够捕获在系统崩溃或者性能下降,主要针对模型会随着数据演化而性能下降,除非模型用新数据定期训练

评估系统的表现需要对预测值采样并进行评估,这通常需要人工来进行,但也需要将评估流水线植入系统

评估系统的质量:有时因为低质量的信号(比如失灵的传感器发送随机值,或另一个团队的输出停滞),系统的表现会逐渐变差,但可能需要一段时间,系统的表现下降到一定程度需要发生警报,如果检测了系统的输入,可以尽早的发现问题,对于线上系统,检测输入数据是非常重要的

定期训练:自动化用新数据定期训练模型,不然训练模型间隔太长,系统的表现波动会比较严重,还需要定期保存系统快照,好能方便回滚到之前的工作状态

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(python,机器学习)