三只猫的故事

序幕

一些大学说,机器学习应该仅保留给世界上真正的巫师,这些巫师被拖入计算机科学和离散数学领域,以至于他们的脸可以用作点矩阵打孔卡,并且在阅读机器时可以赋予生命并随后进入聊天室,他们认为选择的编程语言是过去的过犯和过犯(例如使用Perl)的唯一方式。
但是,其他一些流派意识到,机器学习作为一个概念已经存在了很长时间,以至于仅对定义的一次Google快速搜索就会使您的浏览器泛滥成灾,这些图书馆坚持不懈地要求您提供最坏的证据来证明概念,并且在经过五个工作日的计算并且最多只有三个半融化的RAM棒之后,充其量只能发挥作用。
我们认为后期大量的一部分,所以如果你希望这是智力,勾心斗角的故事奇妙,和专the-”嗯,其实”我很伤心地说,这个故事将主要真气为你还有你的十二度学位和证书 但是,如果您对半教育背景的人如何承担挑战的挑战感到好奇,欢迎加入我们!

设置,战术,目标

我们的故事始于15名学生的精致课。 一些学生来自计算机科学共和国,另一些来自数学王国。 如果您很奇怪或(不完全)感到无聊,那么在此之后不久,您可能会发现他们的博客没那么受人欢迎。
在这篇文章中成为焦点的三个推特是@ applelover1,@ davidangeles和我自己(@jphiggins)。 您会看到我们都分成了团队,就像今天在媒体上展示的许多团队一样,我们不是一个团队,而是一群善于散布好想法的聪明人。 这意味着我们每个人都想出了三种不同的模型,并且由于只有一个团队可以写课程的帖子,而不是用我的模型引起人们的关注,我想在这里铲除我们所有人的观点,以说明不同的心态。
第一个是@ applelover1,他是一个非常聪明的人,在数学王国中是一个强大的专制者,但是只在情感上或至少通过计算概念的证明才编码。 他很明智,却对拥有原创想法感到紧张,这意味着,如果他必须参加100米长的短跑比赛,他将进行采访,跟踪并最终克隆Usain Bolt的尸体以完成工作。
第二个是@davidangeles,即将在数学王国被封为爵士,他还向计算机科学共和国缴税。 这意味着他很清楚读取API并读取错误日志的繁琐过程,因为某些实现强烈地尖叫着您正在用肮脏的二维数组而不是光荣的DataFrame触摸光荣的金色外壳。
最后是我自己,我是计算机科学共和国的逃亡者,恳求在数学王国中奴役农奴。 这并不意味着我是一个巫师,就像我是一个怪异的人一样,他在胡须上爬下一座山,向您介绍了Arch Linux的奇妙之处。
我们三个人一起受到了我们教授的挑战,他们要创建一个模型,至少要在他的比赛中打败他的分数,因为他向我们教授了高级概念和解释数据或缺乏数据的方法。

继续吧

我们直接跳入事物的肉和土豆,从头开始。 我们了解到了五个征服房地产市场的模型:线性回归,套索,LARS,多项式回归,然后是仅有的一个具有深度和吸引力的模型:决策树回归。

我们开始研究如何使用混杂的事物,因为我们只被告知有关德鲁伊和幸福的故事。 看到学习的不幸副作用是想了解更多,所以我们三个人都将数字领域整合到博客,API和其他资源中,这些资源可以告诉我们决策树如何真正发挥作用。 对于那些对我们发现的结果感到好奇的人,我尝试总结一下自己的理解:决策树将采用您建议的统计比较的建议方法/算法,并将所述方法以每种可能的组合(或某些方法组合为置换)进行处理。非关联性)您告诉它要查看的功能。 然后,它将开始在每个节点上形成“决策”,这些决策在目标特征上具有一定程度的明显差异(对于我们更简单的人来说,这是“ y值”)。 看到每个节点都将使我们更接近一片叶子,而每个叶子都将告诉我们从遍历的节点的冗长调查表中应该得到什么。 在“分类”设置中,这当然是我们最期待的类别。 与回归相比,它有些琐碎,因为我们要处理大量的价值观。 在这个项目中,我们的任务是找到无法跌破一美分价值的房价,但是在实践中它的连续性足以引起问题,因此,该树将为我们提供最能代表其价格的某种平均值我们决定的总和。

这些箱形图是用爱(也称为R)制成的。

混乱的散点图,但它显示了地下室不出售的范围。 否则,存在一些显着的相关性。

有趣的是,无车库的价格范围和外观类似于无地下室。 但是在这里,我们可以观察到强大的集群,直到达到3个车库大小。

在统计知识上我很危险,以至于不能认识到相关性将以某种方式成为主要因素,因此我着手开始研究这些因素,并找出哪些相关性系数最高的人至少具有朴素的基础。开始。 对于数字因素,这还不错:

  |功能| 相关| 
|:------------- || -----------:|
| OverallQual | 0.7909816 | <<
| GrLivArea | 0.7086245 | <<
|车库车| 0.6404092 | <<
|车库区| 0.6234314 | <<
| TotalBsmtSF | 0.6135806 | <<
| X1stFlrSF | 0.6058522 |
|全浴| 0.5606638 |
| TotRmsAbvGrd | 0.5337232 | <<
|年构建| 0.5228973 |
| YearRemodAdd | 0.5071010 |
| GarageYrBlt | 0.4863617 |
| MasVnrArea | 0.4774930 |
|壁炉| 0.4669288 |
| BsmtFinSF1 | 0.3864198 |
|正面| 0.3517991 |
| WoodDeckSF | 0.3244134 |
| X2ndFlrSF | 0.3193338 |
| OpenPorchSF | 0.3158562 |
|半浴| 0.2841077 |
|土地面积| 0.2638434 |
| BsmtFullBath | 0.2271222 |
| BsmtUnfSF | 0.2144791 |
| BedroomAbvGr | 0.1682132 |
| ScreenPorch | 0.1114466 |
|泳池区| 0.0924035 |
| MoSold | 0.0464322 |
| X3SsnPorch | 0.0445837 |
| bsmtFinSF2 | -0.0113781 |
| BsmtHalfBath | -0.0168442 |
| MiscVal | -0.0211896 |
| LowQualFinSF | -0.0256061 |
|已售出| -0.0289226 |
|总体条件| -0.0778559 |
| MSSubClass | -0.0842841 |
|封闭式门廊| -0.1285780 |
| KitchenAbvGr | -0.1359074 |

箭头指示我们为第一棵树选择的功能。 现在,您可能想知道为什么我们决定从列表中删除X1stFlrSF和FullBath,因为直觉上您可能会认为我们会选择截止点以上的最高相关性。 但是,我们发现X1stFlrSF和TotalBsmtSF共享相当高的相关系数(0.81),因此为了最大程度地减少过量,我们删除了该系数。 在这种逻辑下,我们应该删除GarageCars和GarageArea,但是当其中一个丢掉时,结果得分会恶化,因此它们都保留了下来。 FullBath的缺席我想向@ applelover1表示感谢,他当时很想参加“统计”工作,因此您在上面看到的列表不是他生成的。 因此,从未讨论过FullBath。

我们将要包含一些整洁的分类功能,但是每个类别之间的大小差异都很大,例如“外观质量”之类的东西,使我犹豫是否要购买ANOVA会给我们带来麻烦的任何东西,而不用将其浸入盐中。 因此,当时我们决定不使用任何分类功能。 (虽然是的,但“总体质量”量表是离散的,但在每个数字后面仍然具有内在价值,因此我们认为最好继续将其解释为数字。)

利用我们的一些功能,我们使用“ OverallQual”,“ TotalBsmtSF”,“ GrLivArea”,“ TotRmsAbvGrd”,“ GarageCars”和“ GarageArea”创建了决策树。 下面显示的第一棵树给出的均方误差为0.23693。 我们对此感觉很好!

婴儿的第一棵树

  housePrice_features = 
['OverallQual','TotalBsmtSF','GrLivArea',
'TotRmsAbvGrd','GarageCars','GarageArea']
X_test = test_data [housePrice_features]
X_train = housePrice_data [housePrice_features]
从sklearn.tree导入DecisionTreeRegressor
housePrice_model = DecisionTreeRegressor(random_state = 1)
housePrice_model.fit(X_train,y_train)

在班级排行榜上首次亮相后,我们注意到其他人已经通过简单的模型获得了相似或更好的结果。 最值得注意的是,我们看到大多数其他团队都选择使用所有功能。 我们质疑我们的以分析为中心的方法是否被误导了一点,但是我对此的立场是,我宁愿通过推理来反复添加新功能,而不是假定所有功能都可以带来一些好处。 团队同意,我们向前推进。

我想说的是,但是@ applelover1决定犯下叛国罪,并制定了一个单独的套索模型。 从松散的角度来看,这是一个模型,它带有大量公认的漂亮图片,但最后却没有模型,这是一个可爱的想法。 这将是两周之后,大量的“分析”其他代码,一个奇迹般的创造诞生了:0.11549。 奇怪的是,就像他“分析过的” 其他公共内核一样! 哦,它也不再是Lasso,而是夹在中间的Lasso-ElasticNet-KernelRidge-GradientBoost-XGBoost并告诉其播放效果很好。 (在此期间,我们接受了其中一些方面的教育。)以下证据证明存在这种大脚怪:

后现代普罗米修斯

 套索= make_pipeline( 
RobustScaler(),
Lasso(alpha = 0.0005,random_state = 1))#似乎合理
ENet = make_pipeline(
RobustScaler(),
ElasticNet(alpha = 0.0005,l1_ratio = .9,random_state = 3))
KRR = KernelRidge(alpha = 0.6,kernel ='polynomial',
度= 2,coef0 = 2.5)
GBoost = GradientBoostingRegressor(n_estimators = 3000,
learning_rate = 0.05,max_depth = 4,max_features ='sqrt',
min_samples_leaf = 15,min_samples_split = 10,loss ='huber',
random_state = 5)
model_xgb = xgb.XGBRegressor(colsample_bytree = 0.4603,
gamma = 0.0468,learning_rate = 0.05,max_depth = 3,
min_child_weight = 1.7817,n_estimators = 2200,reg_alpha = 0.4640,
reg_lambda = 0.8571,子样本= 0.5213,silent = 1,random_state = 7,
nthread = -1)
model_lgb = lgb.LGBMRegressor(objective ='regression',num_leaves = 5,
learning_rate = 0.05,n_estimators = 720,max_bin = 55,
bagging_fraction = 0.8,bagging_freq = 5,feature_fraction = 0.2319,
feature_fraction_seed = 9,bagging_seed = 9,min_data_in_leaf = 6,
min_sum_hessian_in_leaf = 11)
stacked_averaged_models = StackingAveragedModels(
base_models =(ENet,GBoost,KRR),
meta_model =套索)
ensemble = stacked_pred * 0.70 + xgb_pred * 0.15 + lgb_pred * 0.15

过渡时期

在那令人恐惧的数据科学中,我和科学怪人@davidangeles获得了GridSearch的神圣知识。 我们不再像原来那样制作for循环,以尝试通过不同的参数组合进行迭代! 上课时间和业余时间我们在Kaggle投入了不同的组合。 由于仅需要很少的6个小时的公共访问处理,我们就不得不替换搜索中的网格内容。 我们尝试使用类别参数(例如“条件”和“分隔符”),然后更改路线并开始细化连续参数(例如“ min_samples_split”)。 由于@davidangeles深信我们微不足道的功能已使我们开始步入平稳状态,因此我同意添加“ YearBuilt”,“ YearRemodAdd”,“ SaleType”,“ SaleCondition”和“ LandContour”。 前两个是具有高相关系数的,但后来添加了后者,因为它们是我们认为与房屋价值真正相关的特征。 有了这些添加,GridSearch的工作就必须重新开始。

但是,我很傻,不知道接下来会发生什么。 我没有从失去第一个队友到新功能和新方法的警报中汲取教训,我也给他们失去了@davidangeles。 他认为,纯粹坚持使用奇妙的DecisionTree与其他小组相比会使我们受挫,在这方面他是正确的。 我想优化一棵树,看看它在这种环境下如何运作。 因此,他离开并研究了自己的内核,现在我们已经学会了使用各种增强功能。

管道和PCA修饰了我的树,与其他工具所实现的神话般的准确性相比,它们做的事情仅是更多。 随着班级竞赛的最后期限临近,我接受了一个严峻的现实,那就是如果我想缩小差距,我要么需要自己做一棵树,要么使用已经这样做的助推器。 因此,我将AdaBoost牢固地放置在原始树曾经站立过的地方。 由于AdaBoost需要进行300次迭代,因此GridSearch不再能够像以前那样拥有足够的泊位,进度变慢了,新想法的喧闹声像在Kaggle网页上滚动提交的滚动图标一样无声。

最终果园

 功能= ['OverallQual','TotalBsmtSF','GrLivArea', 
'TotRmsAbvGrd','GarageCars','GarageArea','YearBuilt',
'YearRemodAdd','SaleType','SaleCondition','LandContour']
num_features = [col
用于X.dtypes.keys()中的col
如果[dtype(“ int64”),dtype(“ float64”)]中的X.dtypes [col]和
col!=“ Id”]
cat_features = [X.dtypes.keys()中col的col
如果X.dtypes [col]不在[dtype(“ int64”),dtype(“ float64”)]]中
num_pipe = pipeline.make_pipeline(
impute.SimpleImputer(strategy =“ median”),
preprocessing.StandardScaler())
cat_pipe = pipeline.make_pipeline(
impute.SimpleImputer(strategy =“ most_frequent”),
preprocessing.OneHotEncoder(handle_unknown =“ ignore”))
Roomba = compose.make_column_transformer(
(num_pipe,num_features),
(cat_pipe,cat_features))
型号= pipeline.make_pipeline(
Roomba,
分解。PCA(n_components = min(* X.shape),svd_solver =“ full”),
AdaBoostRegressor(base_estimator =
DecisionTreeRegressor(criterion =“ mae”,
splitter =“ best”,
max_depth =无,
max_features =“ auto”,
min_samples_split = 0.085,
random_state = 42),
n_estimators = 300,
random_state = 42))

最后,我能理解的最好的是0.16547,@ davidangeles 0.16039(与上面类似,但是使用GradientBoost),以及@ applelover1仍然具有与前面提到的相同的分数。 我们学到东西了吗? 是的 我们学到了深入,高级的东西吗? 至于能够雇用现成的决胜局和决策者,这是绝对的。