机器学习代码经验整合

该文档是诸位同事机器学习代码学习的经验整合,主要流程为:

  1. 导入工具包及数据
  2. Features 及其缺失值处理
  3. 建模

具体内容如下:

1.import 工具包

将各类工具包导入进工程。

  • 新模块说明:matplotlib

      %matplotlib inline
    

    IPython 内置了一套非常强大的指令系统,又被称作魔法命令,使得在IPython环境中的操作更加得心应手。matplotlib 支持输出多种格式的图形图像,并且可以使用多种 GUI 界面库交互式地显示图表。使用%matplotlib命令可以将 matplotlib 的图表直接嵌入到 Notebook之中,或者使用指定的界面库显示图表,它有一个参数指定 matplotlib 图表的显示方式。inline表示将图表嵌入到Notebook中。

  • 新模块:seaborn

比 Matplotlib 上手简单,Seaborn本质上使用Matplotlib作为核心库(就像Pandas对NumPy一样)。seaborn有以下几个优点:

默认情况下就能创建赏心悦目的图表。
创建具有统计意义的图。
能理解 pandas 的 DataFrame 类型

  • 新模块说明:SciPy

scipy 包包含许多专注于科学计算中的常见问题的工具箱。它的子模块对应于不同的应用,比如插值、积分、优化、图像处理、统计和特殊功能等。
scipy 可以与其他标准科学计算包相对比,比如 GSL (C和C++的GNU科学计算包), 或者Matlab的工具箱。scipy是Python中科学程序的核心程序包;这意味着有效的操作numpy数组,因此,numpy和scipy可以一起工作。

  • 新模块说明:sklearn

在这个案例中用到了 preprocessing 中的 StandardScaler

标准化预处理数据包括:

preprocessing.scale(X, axis=0, with_mean=True, with_std=True, copy=True):
将数据转化为标准正态分布(均值为0,方差为1)
preprocessing.minmax_scale(X, feature_range=(0, 1), axis=0, copy=True):
将数据在缩放在固定区间,默认缩放到区间 [0, 1]
preprocessing.maxabs_scale(X, axis=0, copy=True):
数据的缩放比例为绝对值最大值,并保留正负号,即在区间 [-1.0, 1.0] 内。唯一可用于稀疏数据 scipy.sparse 的标准化
preprocessing.robust_scale(X, axis=0, with_centering=True, with_scaling=True, copy=True):
通过 Interquartile Range (IQR) 标准化数据,即四分之一和四分之三分位点之间

它们对应的标准化预处理类:

class preprocessing.StandardScaler(copy=True, with_mean=True, with_std=True):
标准正态分布化的类
属性:scale_:ndarray,缩放比例mean_:ndarray,均值var_:ndarray,方差n_samples_seen_:int,已处理的样本个数,调用partial_fit()时会累加,调用fit()会重设
class preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True):
将数据在缩放在固定区间的类,默认缩放到区间 [0, 1]
属性:min_:ndarray,缩放后的最小值偏移量scale_:ndarray,缩放比例data_min_:ndarray,数据最小值data_max_:ndarray,数据最大值data_range_:ndarray,数据最大最小范围的长度
class preprocessing.MaxAbsScaler(copy=True):
数据的缩放比例为绝对值最大值,并保留正负号,即在区间 [-1.0, 1.0] 内。可以用于稀疏数据 scipy.sparse
属性:scale_:ndarray,缩放比例max_abs_:ndarray,绝对值最大值n_samples_seen_:int,已处理的样本个数
class preprocessing.RobustScaler(with_centering=True, with_scaling=True, copy=True):
通过 Interquartile Range (IQR) 标准化数据,即四分之一和四分之三分位点之间
属性:center_:ndarray,中心点scale_:ndarray,缩放比例
class preprocessing.KernelCenterer:
生成 kernel 矩阵,用于将 svm kernel 的数据标准化(参考资料不全)

以上几个标准化类的方法:

fit(X[, y]):根据数据 X 的值,计算标准化缩放的比例
transform(X[, y, copy]):用之前设置的比例标准化 X
fit_transform(X[, y]):根据 X 设置标准化缩放比例并标准化
partial_fit(X[, y]):累加性的计算缩放比例
inverse_transform(X[, copy]):将标准化后的数据转换成原数据比例
get_params([deep]):获取参数
set_params(**params):设置参数

2.读入数据

   train = pd.read_csv("../input/train.csv")

设置数据格式:
如下为为设置显示的浮点数位数,保留三位小数。

   pd.set_option('display.float_format', lambda x: '%.3f' % x)

建议可以将 .csv 文件用 excel 打开,后续可作数据上的人为调整,观察不同的调整对代码结果的影响。

3.检查是否有重复数据,并去除 ID 列
检查是否有重复数据:

    idsUnique = len(set(train.Id))
    idsTotal = train.shape[0]
    idsDupli = idsTotal - idsUnique
    print("There are " + str(idsDupli) + " duplicate IDs for " + str(idsTotal) + " total entries")

其中, train.shape 返回的是(1460,80),即行列的数目; train.shape[0] 返回的是行的数目。

在本数据集中没有重复数据,然而如果在其他数据集中要做重复数据的处理,建议使用 DataFrame.drop_duplicates(subset=None, keep='first', inplace=False) Return DataFrame with duplicate rows removed, optionally only considering certain columns.

其中, 如上几个参数解释如下:
subset : column label or sequence of labels, optional.Only consider certain columns for identifying duplicates, by default use all of the columns。选择要作用于的列。
keep : {‘first’, ‘last’, False}, default ‘first’.first : Drop duplicates except for the first occurrence. last : Drop duplicates except for the last occurrence. False : Drop all duplicates.
inplace : boolean, default False. Whether to drop duplicates in place or to return a copy. 如果选的是 True 则在原来 dataframe 上直接修改,否则就返回一个删减后的 copy。

去除 ID 列数据:

    train.drop("Id", axis = 1, inplace = True)

其中几个参数的意思分别是:
“ID” 为列名。
axis = 1 表明是列;如果是 0 ,则表明是行。
inplace = True:凡是会对原数组作出修改并返回一个新数组的,往往都有一个 inplace可选参数。如果手动设定为True(默认为False),那么原数组直接就被替换。

数据处理

1.观察数据并去除异常值。

  • 观察数据
    可以先直接观察一下目标问题的数据,包括个数、平均值、标准差、最小值、最大值、分位数等;还可以利用直方图,画出数据分布情况;通过观察直方图,可以看出数据并不是完全符合正态分布曲线,有偏度和峰度;通过观察散点图或盒图,可以注意到有异常值。

    #describe statistics summary
    df_train['SalePrice'].describe
    
    # histogram
    sns.distplot(df_train['SalePrice'])
    
    # skewness and kurtosis
    print("Skewness: %f" % df_train['SalePrice'].skew)
    
    # scatter plot
    plt.scatter(train.GrLivArea, train.SalePrice, c = "blue", marker = "s")
    plt.title("Looking for outliers")
    plt.xlabel("GrLivArea")
    plt.ylabel("SalePrice")
    plt.show()
    
scatter.png
  • 去除异常值

    train = train[train.GrLivArea < 4000] # 去除右侧的异常点
    

判断异常值并根据情况进行处理,注意:
偏离太多的异常值可以删除;
偏离但是仍然符合分布的异常值可以保留;
处理异常值要考虑清楚 trade-off,是否值得花力气处理;

2.对 target feature 进行 log transform
对 target feature 也就是此处的 sale price 进行 log transform,将有偏度的分布转换为正态分布,有利于后续分析。

matplotlib.rcParams['figure.figsize'] = (12.0, 6.0)
prices = pd.DataFrame({"price":train["SalePrice"], "log(price + 1)":np.log1p(train["SalePrice"])})
prices.hist()#直方图
image.png

左:log(feature+1) 转换后,右:转换前

要注意的是建议采用 log(1+x)的形式:

  • take log 的作用:
    Small values that are close together are spread further out.
    Large values that are spread out are brought closer together.
natural log.png
  • take log(1+x) 的作用:
    朴素贝叶斯中,防止变量之前从未出现的时候,出现的概率为 0 ,出现数学计算的错误。

3.数据 features 及其缺失值处理

3.1 categorical 数据填充:选最低等级或最常出现的值
处理不可使用中位数或平均数或 most common value 进行填充的 feature 的缺失值。

替换数据的依据
根据 label 判断该 feature 下缺失值最有可能是什么,就填入什么。

  train.loc[:, "Alley"] = train.loc[:, "Alley"].fillna("None")

其中 train.loc[:, "Alley"] means select every row of column "alley"., .fillna(XX) means fill na cell with XX.

具体来说,要深入去看原始数据集:

  • 如果 values 中有等级划分(优劣差等各等级;2、1、0 或 Y/N),一般选择最低等级的一类作为填充值。
  • 如果 values 中为类型划分,则选择该 features 下最经常出现的值作为填充值。

3.2 categorical 和 numerical 的 features 互换

原始数据中,有一些 categorical features 理应是 numerical,反之亦然,为了更好的预测结果,我们要将部分 categorical 和 numerical 的 features 做处理。这一步在其他示例中没有出现,但建议保留。

** 3.2.1 将 numerical features 转为 categories**

Some numerical features 事实上是类型值, 要把它们转化成类别。比如月份的数字本身无任何数值意义,所以转换为英文缩写。

train = train.replace({"MSSubClass" : {20 : "SC20", 30 : "SC30", 40 : "SC40", 45 : "SC45",  50 : "SC50", 60 : "SC60", 70 : "SC70", 75 : "SC75",  80 : "SC80", 85 : "SC85", 90 : "SC90", 120 : "SC120",  150 : "SC150", 160 : "SC160", 180 : "SC180", 190 : "SC190"}, 
"MoSold" : {1 : "Jan", 2 : "Feb", 3 : "Mar", 4 : "Apr", 5 : "May", 6 : "Jun", 7 : "Jul", 8 : "Aug", 9 : "Sep", 10 : "Oct", 11 : "Nov", 12 : "Dec"}})

3.2.2 将 category features 转为 ordered numbers

将一些 categorical features 转换为 ordered numbers,

  1. 有明确分级的 feature,这些数值的顺序本身是有信息的,比如,"BsmtQual" : {"No" : 0, "Po" : 1, "Fa" : 2, "TA": 3, "Gd" : 4, "Ex" : 5};
  2. 分类关系中分级关系可以比较明确区分出来,如 Alley ,大多数人都偏好铺好的平整路面,而不是碎石路;LotShape,大多数人都偏好规整的 LotShape。反例则是比如 neighborhood 虽然可以反应出分级,毕竟大多数人喜欢的社区还是相似的,但是很难区分。
    train = train.replace({"Alley" : {"Grvl" : 1, "Pave" : 2},
                   "BsmtCond" : {"No" : 0, "Po" : 1, "Fa" : 2, "TA" : 3, "Gd" : 4, "Ex" : 5},
                ……)

3.3 Create new features
这一步在有些示例中并没有,但建议保留。
Then we will create new features, in 3 ways :

  1. Simplifications of existing features
  2. Combinations of existing features
  3. Polynomials on the top 10 existing features

3.3.1 简化 features 1 Simplifications of existing features*
第一种简化 features 的方法,即简化已有的 features 数据层级,比如如下将原来 9 级的数据(1–9)可以划分为 3 级(1–3)。

train["SimplOverallQual"] = train.OverallQual.replace(
                                                  {1 : 1, 2 : 1, 3 : 1, # bad
                                                   4 : 2, 5 : 2, 6 : 2, # average
                                                   7 : 3, 8 : 3, 9 : 3, 10 : 3 # good
                                                  })

3.3.2 简化 features 2 Combinations of existing features*

第二种简化 features 的方法,即将若干种紧密相关的 features 合并在一起。

具体语法(示例):

train["OverallGrade"] = train["OverallQual"] * train["OverallCond"]

可能用到的讲解视频 Multivariate Linear Regression - Features and Polynomial Regressions - Housing Prices Predicting , given by Andrew NG, Stanford University。要注意的是,采用这种方法要格外注意 scaling。

Features Choice.png

3.3.3 简化 features 3 Polynomials on the top 10 existing features*

寻找重要 features
Find most important features relative to target. 按照其他 features 和 SalePrice 的相关度 correlation 降序排列。

corr = train.corr()
corr.sort_values(["SalePrice"], ascending = False, inplace = True)

Features and Polynomial Regressions

关于这一步,个人的理解是:先将重要的 features 挑选出来,然后为了更好地拟合某个模型,将这些重要的模型做了一个 Polynomial Regressions 的处理。

代码示例:

train["OverallQual-s2"] = train["OverallQual"] ** 2
train["OverallQual-s3"] = train["OverallQual"] ** 3
train["OverallQual-Sq"] = np.sqrt(train["OverallQual"])

关于何时使用 polynomial,有如下三个 situations:

  • 理论需求。即作者假设这里会由曲线构成。
  • 人为观察变量。在做回归分析之前,要先做单变量或二变量观察。可以通过画简单的散点图来检验是否有曲线关系。
  • 对残差的观察。如果你试图将线性模型应用在曲线关系的数据上,那么散点图中间会在中间区域有整块的正值残差,然后在横坐标(X 轴即
    predictor)一末端有整块的负值残差;或者反之。这就说明了线性模型是不适用的。但我个人觉得,第三种方式只是不适用线性模型的若干种情况之一,非充要条件。

同样的,用到的讲解视频 Multivariate Linear Regression - Features and Polynomial Regressions - Housing Prices Predicting , given by Andrew NG, Stanford University。要注意的是,采用这种方法要格外注意 scaling。

有趣的是,执行了上述代码之后,重新将影响 SalePrice 的 features 排序后,新生成的 features 进入了 influential features top 10,可见 polynomial 是有意义的。

Features and Polynomial Regressions.png

3.4 numerical 数据缺失值填充

对 numerical features 中缺失的数据进行填充。

  • 区分出 numerical 和 categorical features 。

    categorical_features = train.select_dtypes(include = ["object"]).columns
    numerical_features = train.select_dtypes(exclude = ["object"]).columns
    numerical_features = numerical_features.drop("SalePrice")
    

    其中 object 是指 categorical features 的数据类型。

  • 填充缺失的数据。

对于 numerical features 中的缺失值,使用中位数或平均值作为填充值(>15% 数据量缺失的 features 可考虑不必填充)。

  #filling NA's with the median of the column:
  train_num = train_num.fillna(train_num.median())

或者
#filling NA's with the mean of the column:
all_data = all_data.fillna(all_data.mean())

4.对 numerical features 进行 log transfrom

对 skewed numerical features 取 Log 变换可以弱化异常值的影响。

skewness = train_num.apply(lambda x: skew(x))
skewness = skewness[abs(skewness) > 0.5]
skewed_features = skewness.index
train_num[skewed_features] = np.log1p(train_num[skewed_features])

Inspired by Alexandru Papiu's script. As a general rule of thumb, a skewness with an absolute value > 0.5 is considered at least moderately skewed. 要注意的是,此处取的偏度值为 0.5,在其他示例中,也可能采用不同的偏度值如 0.75。

5.对 categorical features 进行 get dummies 操作

Create dummy features for categorical values. Create dummy features for categorical values via one-hot encoding.

train_cat = [pd.get_dummies(train_cat)](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html)
OneHotEncoder.png

在回归分析中,dummy 变量(也被称为 indicator variable, design variable, Boolean indicator, categorical variable, binary variable, or qualitative variable)取值为 0 或 1,意味着是否会有可能影响输出的 categorical effect。Dummy 变量常用于分类互斥分类(比如吸烟者/非吸烟者)。

get_dummies 作用于 categorical features,举例来说明 get_dummies 的作用:

  • 在执行 get_dummies 操作之前,每一列都是一个feature,这一列内取值都是原始数据或处理后的原始数据,对于 feature MSSubClass 的取值可分为 SC20/SC60/ SC70...SC120...等,其中第 23 行的数据记录为 SC120。
  • 在执行 get_dummies 操作之后,每一列的列名依次变为每一个原来 feature 的取值,比如原来的 MSSubClass 列会拓展为 SC20/SC60/ SC70...SC120...等。以 SC120 举例,原来第 23 行记录为 SC120, 那么对应修改后新增的 SC120 列中第 23 行值为 1;原来若干行记录不是 SC120 的,对应变换后值为 0.

建模

  1. lasso
    1.1 parmaters:alpha
    1.2 建模 和 predict
    1.3 plot 检验结果

  2. xgboost
    2.1 parmaters:
    2.2 建模 和 predict
    2.3 plot 检验结果

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容