本次分享来自UdacityMachineLearningAdvanced中的一个小项目。非常适合入门。它删除了繁琐的部分并保留了最关键和最基本的步骤。它可以有最清晰的机器学习的基本过程。理解。项目描述使用马萨诸塞州波士顿郊区的住房信息数据训练和测试模型,测试模型的性能和预测能力;项目分析数据集字段说明:RM:住宅平均房间数;LSTAT:被认为是该地区低收入阶层的比率;PTRATIO:镇上师生比;MEDV:房屋的中位价(目标特征,也就是我们要预测的值);其实现在回过头来看,前三个特征应该是挖掘后的组合特征,比如RM,在原始数据中通常会分成多个特征:一楼的房间,二楼的房间,厨房,人数卧室、地下室等,此处应为教学简化;MEDV对于我们要预测的值是一个回归问题。另外,数据集不大(小于500个数据点),小数据集上的回归问题。现在我初步考虑使用SVM。待会儿再看看当时的选择;ShowTimeStep1导入数据时的注意事项:如果数据在多个csv中(比如很多销售项目中,销售数据和店铺数据分离到两个csv中,类似于数据库中的两个表),一般是连接这里;trainingdata是和testdata相连的,这是为了后续数据处理的一致性,否则训练模型的时候会出现问题(比如用trainingdata训练的模型,预测test的时候errordimension不一致数据);观察数据量,数据量对于后续的选择算法、可视化方法等有比较大的影响,所以一般都会看一下;pandas内存优化,目前在项目中没有,但是在我最近的项目中很有用。简单的说就是通过特征字段的数据类型向下转换(比如int64到int8)减少内存的使用,这在这里很重要。当数据量很大时,很容易把个人电脑的内存存储撑爆;上面代码:#加载波士顿房屋数据集data=pd.read_csv('housing.csv')prices=data['MEDV']features=data.drop('MEDV',axis=1)#完成打印"Bostonhousingdatasethas{}datapointswith{}variableseach.".format(*data.shape)Step2分析数据载入数据后,不要急于使用各种处理方法,添加各种模型。先慢下来,对数据有个初步的了解,了解各个特征的统计值,分布,和目标特征的关系,最好是形象化,这样你会看到很多意想不到的东西;基本统计操作统计操作用于理解某个特征的总体值,其最大值和最小值,平均中位数,百分位数等,这些是理解一个领域最简单的手段;上面的代码:#目标:计算值的最小值minimum_price=np.min(prices)#prices.min#目标:计算值的最大值maximum_price=np.max(prices)#prices.max#目标:计算值的平均值mean_price=np.mean(prices)#prices.mean#goal:计算值的中位数median_price=np.median(prices)#prices.median#goal:计算值的标准差std_price=np.std(prices)#prices.stdfeatureObservation这里主要考虑每个特征与目标的关系,比如正相关或者负相关,通常是通过对业务的理解,这里延伸一点,机器学习项目一般来说,对业务越了解越容易得到好的结果,因为所谓的特征工程其实就是对业务的理解和挖掘的过程;比如这个问题中的三个特征:RM:房间数应该和房价明显正相关;LSTAT:Low收入比在一定程度上说明了社区的水平,所以应该是负相关的;PTRATIO:生师比越高,教育资源越稀缺,应该也是负相关的;上述三点也可以形象化,其实应该去验证,而不是仅仅依靠主观猜测。在某些情况下,主观感受与客观事实完全相反。这里需要注意;Step3数据划分,验证模型质量。通常的做法是进行cv,即交叉验证。其基本思想是将数据平均分成N个块,取N-1个块进行训练,对另一块进行预测,并将预测结果与实际结果进行比较。这个过程重复N次,直到每个区块都作为验证数据;上面的代码:#Tip:importtrain_test_splitfromsklearn.model_selectionimporttrain_test_splitX_train,X_test,y_train,y_test=train_test_split(features,prices,test_size=0.2,random_state=RANDOM_STATE)printX_train.shapeprintX_test.shapeprinty_train.shapeprinty_test.shapeStep4定义评价函数这里主要是根据问题来定义。比如分类问题用的最多的就是准确率(准确率和召回率也会用到,看业务场景中什么更重要),回归问题用RMSE(平均平方误差)等等。在实际项目中,往往需要根据业务特点自定义评价函数。这样更灵活;步骤5模型调整使用GridSearch搜索模型参数的最佳网格组合。注意这里要考虑数据量和可能的组合数,避免运行时间过长。上面代码:fromsklearn.model_selectionimportKFold,GridSearchCVfromsklearn.treeimportDecisionTreeRegressorfromsklearn.metricsimportmake_scorerdeffit_model(X,y):"""基于输入数据[X,y],有利于网格搜索找到最优决策树模型"""cross_validator=KFoldregressor=DecisionTreeRegressorparam{'max_depth':[1,2,3,4,5,6,7,8,9,10]}scoring_fnc=make_scorer(performance_metric)grid=GridSearchCV(estimator=regressor,param_grid=params,scoring=scoring_fnc,cv=cross_validator)#根据输入数据[X,y]进行网格搜索grid=grid.fit(X,y)#网格搜索后返回最优模型returngrid.best_estimator_可以看到当时选择的item是Decisiontreemodel,现在来看,树模型其实在这么小的数据集上还是比较容易overfit的,所以可以考虑改用SVM,也可以试试,我猜的效果SVM更好;学习曲线通过通过绘制和分析学习曲线,可以对模型的当前状态有一个基本的了解,如下图所示:可以看出,当超参数max_depth为1和3时,训练分数明显过低,说明此时模型欠拟合,而当max_depth为6和10时,很明显训练分数和验证分析差距过大,说明出现了过拟合,所以我们可以初步猜测优质参数在3和6之间,即4和5中的一个,其他参数也可以通过学习曲线进行可视化分析,判断是欠拟合还是过拟合,以及然后分别进行针对性处理;通过以上步骤,你可以非常简单明了的看到一个机器学习项目的全过程。再复杂的流程,也是这些简单步骤的一些延伸,更难的往往是对业务的理解。没有足够的了解,就很难得到好的结果。体现在特征工程部分的质量上。这里需要每一位合作伙伴努力奋斗,路漫漫其修远兮。项目链接可以通过nbviewer查看全文;项目源文件和数据集文件可通过GitHubBoston项目获取,欢迎Follow、Fork、Star;
