Kaggle实战1-机器学习算法与流程概述 + house-price example

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lyf52010/article/details/80784932

参考链接:https://blog.csdn.net/han_xiaoyang/article/details/50469334

 机器学习问题解决思路

上面带着代价走马观花过了一遍机器学习的若干算法,下面我们试着总结总结在拿到一个实际问题的时候,如果着手使用机器学习算法去解决问题,其中的一些注意点以及核心思路。主要包括以下内容:

  • 拿到数据后怎么了解数据(可视化)
  • 选择最贴切的机器学习算法
  • 定位模型状态(过/欠拟合)以及解决方法
  • 大量极的数据的特征分析与可视化
  • 各种损失函数(loss function)的优缺点及如何选择
  • 问题来了,过拟合咋办? 
    针对过拟合,有几种办法可以处理:

    • 增大样本量
    • 减少特征的量(只用我们觉得有效的特征)
    • 增强正则化作用(比如说这里是减小LinearSVC中的C参数) 
      正则化是我认为在不损失信息的情况下,最有效的缓解过拟合现象的方法。
    • l2正则化,它对于最后的特征权重的影响是,尽量打散权重到每个特征维度上,不让权重集中在某些维度上,出现权重特别高的特征。
    • 而l1正则化,它对于最后的特征权重的影响是,让特征获得的权重稀疏化,也就是对结果影响不那么大的特征,干脆就拿不着权重。
    特征工程 



****************************************************************************************

label本身并不平滑。为了我们分类器的学习更加准确,我们会首先把label给“平滑化”(正态化)

这一步大部分同学会miss掉,导致自己的结果总是达不到一定标准。

这里我们使用最有逼格的log1p, 也就是 log(x+1),避免了复值的问题。

记住哟,如果我们这里把数据都给平滑化了,那么最后算结果的时候,要记得把预测到的平滑数据给变回去。

按照“怎么来的怎么去”原则,log1p()就需要expm1(); 同理,log()就需要exp(), ... etc.

Step 3: 变量转化

类似『特征工程』。就是把不方便处理或者不unify的数据给统一了。

正确化变量属性

首先,我们注意到,MSSubClass 的值其实应该是一个category,

但是Pandas是不会懂这些事儿的。使用DF的时候,这类数字符号会被默认记成数字。

这种东西就很有误导性,我们需要把它变回成string

In [13]:
all_df['MSSubClass'].dtypes
Out[13]:
dtype('int64')
In [14]:
all_df['MSSubClass'] = all_df['MSSubClass'].astype(str)

变成str以后,做个统计,就很清楚了

In [15]:
all_df['MSSubClass'].value_counts()
Out[15]:
20     1079
60      575
50      287
120     182
30      139
70      128
160     128
80      118
90      109
190      61
85       48
75       23
45       18
180      17
40        6
150       1
Name: MSSubClass, dtype: int64

把category的变量转变成numerical表达形式

当我们用numerical来表达categorical的时候,要注意,数字本身有大小的含义,所以乱用数字会给之后的模型学习带来麻烦。于是我们可以用One-Hot的方法来表达category。

pandas自带的get_dummies方法,可以帮你一键做到One-Hot。

In [16]:
pd.get_dummies(all_df['MSSubClass'], prefix='MSSubClass').head()
Out[16]:
  MSSubClass_120 MSSubClass_150 MSSubClass_160 MSSubClass_180 MSSubClass_190 MSSubClass_20 MSSubClass_30 MSSubClass_40 MSSubClass_45 MSSubClass_50 MSSubClass_60 MSSubClass_70 MSSubClass_75 MSSubClass_80 MSSubClass_85 MSSubClass_90
Id                                
1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0
5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0

此刻MSSubClass被我们分成了12个column,每一个代表一个category。是就是1,不是就是0。

同理,我们把所有的category数据,都给One-Hot了

处理好numerical变量

就算是numerical的变量,也还会有一些小问题。

比如,有一些数据是缺失的:

In [18]:
all_dummy_df.isnull().sum().sort_values(ascending=False).head(10)
Out[18]:
LotFrontage     486
GarageYrBlt     159
MasVnrArea       23
BsmtHalfBath      2
BsmtFullBath      2
BsmtFinSF2        1
GarageCars        1
TotalBsmtSF       1
BsmtUnfSF         1
GarageArea        1
dtype: int64

可以看到,缺失最多的column是LotFrontage

处理这些缺失的信息,得靠好好审题。一般来说,数据集的描述里会写的很清楚,这些缺失都代表着什么。当然,如果实在没有的话,也只能靠自己的『想当然』。。

在这里,我们用平均值来填满这些空缺。

标准化numerical数据

这一步并不是必要,但是得看你想要用的分类器是什么。一般来说,regression的分类器都比较傲娇,最好是把源数据给放在一个标准分布内。不要让数据间的差距太大。

这里,我们当然不需要把One-Hot的那些0/1数据给标准化。我们的目标应该是那些本来就是numerical的数据:

先来看看 哪些是numerical的:

In [22]:
numeric_cols = all_df.columns[all_df.dtypes != 'object']
numeric_cols
Out[22]:
Index(['LotFrontage', 'LotArea', 'OverallQual', 'OverallCond', 'YearBuilt',
       'YearRemodAdd', 'MasVnrArea', 'BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF',
       'TotalBsmtSF', '1stFlrSF', '2ndFlrSF', 'LowQualFinSF', 'GrLivArea',
       'BsmtFullBath', 'BsmtHalfBath', 'FullBath', 'HalfBath', 'BedroomAbvGr',
       'KitchenAbvGr', 'TotRmsAbvGrd', 'Fireplaces', 'GarageYrBlt',
       'GarageCars', 'GarageArea', 'WoodDeckSF', 'OpenPorchSF',
       'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea', 'MiscVal',
       'MoSold', 'YrSold'],
      dtype='object')

计算标准分布:(X-X')/s

让我们的数据点更平滑,更便于计算。

注意:我们这里也是可以继续使用Log的,我只是给大家展示一下多种“使数据平滑”的办法。


猜你喜欢

转载自blog.csdn.net/lyf52010/article/details/80784932