kaggel入门比赛_HousePrices

@update 2016.11.28,自己尝试了一些缺失值填补的方法,调sklearn写了一些特征变换和特征选择的算法

下一步:继续特征规约,开始模型调参

kaggle入门系列比赛HousePrices,该比赛是一个经典的回归问题,预测房价,这个比赛我用来熟悉kaggle,熟悉基本的数据挖掘流程,主要是特征工程,包括常见的缺失值填补,categorial特征的处理,其实主要就是熟悉用python的pandas包对数据进行预处理。

第一次尝试的过程我主要是参考了Regularized Linear Models这篇kernel,它对数据的处理就是一些最基本的做法,作为入门、熟悉基本流程是很好的一篇kernel。

一.处理数据,准备建模

1.数据变换

特征中的属性分为两种,定性的和定量的。对定量的属性我们可以有很多种距离度量方式。而对定性的属性我们一般用标签来表示之,这对于常见的机器学习算法而言是不好处理的,常见的做法是转化为数值属性,但是如何转化?如何单纯的转化为数字的话会影响一些以距离度量为依据的算法的准确性。一般我们使用pandas的get_dummies()将其每个属性值转化为一个二元属性维度,值对应为0/1,但这也存在一个问题,就是当原始定性属性的属性值过多时。
all_data = pd.get_dummies(all_data) #直接对整个DataFrame中所有类别属性做dummies
对于定量属性,一个可能需要的操作就是规范化。但规范化不是必须的,当所使用的算法不是依据距离属性作为度量时,不需要做归一化。
在上述提到的Regularized Linear Models的做法中,值得一提的是通过对数据的绘图(也可以通过scipy包的)发现预测属性是偏态分布的。这种偏态分布(数据不均衡)会影响算法准确性,作者通过对偏态数据做log变换改善数据倾斜度。
skewed_feats = train[numeric_feats].apply(lambda x: skew(x.dropna())) #compute skewness<pre name="code" class="python">all_data[skewed_feats] = np.log1p(all_data[skewed_feats])

@2016.11.28:对categorical的处理也就是get_dummies了,目前没有用到别的优化。

值得一提的是,虽然log变换使数据趋于正态分布,这种优化是针对于线性回归的(因为线性回归后续的一些检验是基于正态分布假设的),但是我在实践中发现对tree-based的模型,也是通过log变换会使得分提高,why?

2.缺失值填补

常见的缺失值填补方法,见这篇数据挖掘之缺失值填补常见手段

我们首先尝试一个最基本的填补方法,即均值填补

all_data = all_data.fillna(all_data.mean())

@2016.11.28:缺失值处理的几种常见方法:

1.删除带缺失值的数据:适用于数据量足够大的时候;
2.均值/众数填补:简单常用;
3.建立模型,如线性回归,随机森林:利用的是属性之间的相关性,如果属性之间相关性过高,则该属性没有意义,而若相关性过低,无法准确预测该缺失值。一般情况下介于两者之间
4.当作特殊情况,取特殊值填入:适用于缺失值很多,或缺失值本身有一定意义的情况。
对HousePrices的处理,我使用了上述2、3、4三种,对如Alley这样的用的是4,对一些与输出相关性高的features使用3,剩下的使用2。在这样的处理下最后得分有提升。虽然理论解释有待考证。

3.维度规约

特征维度过高可能会引起维数灾难,原因在于:1,这些特征之间可能存在多重共线性,从而导致空间的不稳定;2,高维空间本身具有稀疏性,一维正态分布有68%的值落于正负标准差之间,而在十维空间上只有0.02%;三是由于过多的属性 会使挖掘需要很长时间。当前这些现象对不同的算法而言也是不同的,比如对L1(Lasso)而言,大量属性时效果很好,因为它可以有效忽略掉噪声变量,而对一些模型而言过多的属性则容易过拟合。

@2016.11.28:做到这一步我就迷幻了,因为我试了好几种维度变换的方法,都是提交的得分效果变差... 一度导致我不想做下去,可能自己对这方面的理论缺失,经验又太少,做起来有点迷茫吧,anyway,还是要继续,于是今晚看了一些kernel,发现几乎没有对features做类似PCA这样的维度变换的,不造为什么。

关于特征选择倒是有人做,我试了一下添加了两个合成特征,提交结果还是有提升哒,更神奇的是有一个合成的features[1stFlr_2ndFlr_Sf = ['1stFlrSF'] + ['2ndFlrSF']]。它居然在训练好的lasso模型上系数是最高的,所以说领域知识,或者说特征工程真的很重要的。

下一步可以试一下特征选择,比如说利用random forest的特征重要度,kernel上大部分都是用lassocv自动完成特征选择,but anyway还是xgboost性能好些吧。


@update2016.11.29:试了一下模型选择,sklearn.feature_selection中的RFECV和SelectFromModel,前者是利用模型的准确度(具体可以选择sklearn提供的scoring标准)来递归的减少特征直到选出最优特征子集,后者则是根据模型中的estimator.feature_importances_属性(所以输入的模型必须有这个属性)来选择特征子集。我大概试了下两者的性能都不好,其中我又SelectFromModel结合RandomForest试了下,简直可怕,看代码和输出:

from sklearn.model_selection import cross_val_score
import numpy as np
def rmse_cv(model,X_train,y):
    rmse= np.sqrt(-cross_val_score(model, X_train, y, scoring="neg_mean_squared_error", cv=3,n_jobs=-1))
    return(rmse)
from sklearn.feature_selection import SelectFromModel
# u can see from 'SelectFromModel' that this method use model result to select features, 'Wrapper'
# estimator: a supervised model with fit() method
def fea_sel_tree(train_x,train_y,estimator):
    estimator = estimator.fit(train_x,train_x)
    print 'feature importances in this model',
    print sorted(estimator.feature_importances_,reverse=True)
    model = SelectFromModel(estimator,prefit = True)
    after_sel = model.transform(train_x)
    return pd.DataFrame(after_sel)
import xgboost as xgb
from sklearn.ensemble import RandomForestRegressor
esti = RandomForestRegressor(n_estimators=360, max_depth=2,n_jobs=-1,random_state=0)
train_after = fea_sel_tree(alldata_newfea.iloc[:1460],y,esti)
model_xgb = xgb.XGBRegressor(n_estimators=360, max_depth=2, learning_rate=0.1)
print rmse_cv(model_xgb,train_after.iloc[:1460],y)
输出:(可怕
feature importances in this model [0.98394303690584572, 0.0095377084732799645, 0.0065192546208747695, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
rmse: [ 0.28251422  0.300882    0.28558193]  #注:正常的rmse至少是0.13左右的吧

直接加了个特征选择降这么多,可怕,但是其实从feature importance可以看出来,290多个features直接只剩3个了,各种不靠谱。

于是我在想,可能model的参数不太靠谱,于是我想先不加特征规约了,先model调参吧。

# 上述完整代码参见:点击打开链接

二.Modeling

#具体的建模过程

@2016.11.28:model部分基本上一直坚信xgboost - -,但是没有调参,下一步可以进行,不过感觉调参真是一条艰难的道路- -

然后下一步可能可以试一下集成模型,这也是个调参的坑啊。。。我还没想好要不要从HousePrices的坑里爬出来,找一个数据量稍微大点的坑扑进去- -

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章