一个完整机器学习实战的总结

目录

    • 写在前面
    • 1、赛题理解
      • 常见的回归评价标准
      • 常见的分类评价标准
    • 2、数据分析
      • 总的粗略概况
      • 分析nan与缺省值
      • 观看y值的分布
      • 分析类别特征和数字特征
      • 选取合适特征存储格式减小内存占用
    • 3、特征工程
    • 4、建模调参
    • 5、模型融合

写在前面

这个实战是阿里天池数据比赛上的一个题目,虽然以该题目为背景但将从机器学习过程的通解层面进行分析。
零基础入门数据挖掘 - 二手车交易价格预测
本文将从下面五个方面完整总结完成这个题目的过程
1、赛题理解
2、数据分析
3、特征工程
4、建模调参
5、模型融合

1、赛题理解

针对一个传统的机器学习,首先应该明确是分类还是回归问题,明确针对该问题的评价标准。

常见的回归评价标准

# coding=utf-8
import numpy as np
from sklearn import metrics
from sklearn.metrics import r2_score
# MAPE需要自己实现
def mape(y_true, y_pred):
    return np.mean(np.abs((y_pred - y_true) / y_true))

y_true = np.array([1.0, 5.0, 4.0, 3.0, 2.0, 5.0, -3.0])
y_pred = np.array([1.0, 4.5, 3.8, 3.2, 3.0, 4.8, -2.2])

# MSE
print('MSE:',metrics.mean_squared_error(y_true, y_pred))
# RMSE
print('RMSE:',np.sqrt(metrics.mean_squared_error(y_true, y_pred)))
# MAE
print('MAE:',metrics.mean_absolute_error(y_true, y_pred))
# MAPE
print('MAPE:',mape(y_true, y_pred))
# R2-score
print('R2-score:',r2_score(y_true, y_pred))

常见的分类评价标准

import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score
from sklearn import metrics
## accuracy
y_pred = [0, 1, 0, 1]
y_true = [0, 1, 1, 1]
print('ACC:',accuracy_score(y_true, y_pred))
## Precision,Recall,F1-score
print('Precision',metrics.precision_score(y_true, y_pred))
print('Recall',metrics.recall_score(y_true, y_pred))
print('F1-score:',metrics.f1_score(y_true, y_pred))
## AUC
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print('AUC socre:',roc_auc_score(y_true, y_scores))

2、数据分析

总的粗略概况

将特征分为数字特征和类别特征两类

    a=Train_data.head(5)	#浏览前5行
    b=Train_data.info()		#类型
    c=Train_data.describe()	#数字特征
    print(a,b,c)

分析nan与缺省值

某些数据包含‘-’表示nan,其info类型为object,应首先将其替换为nan,
再用删除填充等方法解决

    # nan可视化
    missing = Train_data.isnull().sum()
    print(missing)
    missing = missing[missing > 0]
    missing.sort_values(inplace=True)
    missing.plot.bar()
    plt.show()

    # 可视化看下缺省值
    msno.matrix(Train_data.sample(250))
    plt.show()
    msno.bar(Train_data.sample(1000))
    plt.show()

观看y值的分布

有时需要对y进行变换使其更加适合模型,如对数变化

    plt.hist(Train_data['price'], orientation='vertical', histtype='bar', color='red')
    plt.show()

分析类别特征和数字特征

类别特征偏斜过大如10000个1一个0的一列特征,几乎可认为该特征无总用可以删除,数字特征偏峰度过大的可以通过对数等方法解决

    # 类别特征nunique分布
    for cat_fea in categorical_features:
        print(cat_fea + "的特征分布如下:")
        print("{}特征有个{}不同的值".format(cat_fea, Train_data[cat_fea].nunique()))
        print(Train_data[cat_fea].value_counts())

    # 数字特征偏峰度
    for col in numeric_features:
        print('{:15}'.format(col),
              'Skewness: {:05.2f}'.format(Train_data[col].skew()),
              '   ',
              'Kurtosis: {:06.2f}'.format(Train_data[col].kurt())
              )

选取合适特征存储格式减小内存占用

def reduce_mem_usage(df):
    """ iterate through all the columns of a dataframe and modify the data type
        to reduce memory usage.
    """
    start_mem = df.memory_usage().sum()
    print('Memory usage of dataframe is {:.2f} B'.format(start_mem))

    for col in df.columns:
        col_type = df[col].dtype

        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')

    end_mem = df.memory_usage().sum()
    print('Memory usage after optimization is: {:.2f} B'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    return df

3、特征工程

思维风暴般的选择关联度大切不至于过拟合欠拟合的特征尤为重要
常见的特征工程包括:
1、异常处理:
通过箱线图(或 3-Sigma)分析删除异常值;
BOX-COX 转换(处理有偏分布);
2、长尾截断;
特征归一化/标准化:
标准化(转换为标准正态分布);
归一化(抓换到 [0,1] 区间);
3、数据分桶:
等频分桶;
等距分桶;
Best-KS 分桶(类似利用基尼指数进行二分类);
卡方分桶;
4、缺失值处理:
不处理(针对类似 XGBoost 等树模型);
删除(缺失数据太多);
插值补全,包括均值/中位数/众数/建模预测/多重插补/压缩感知补全/矩阵补全等;
分箱,缺失值一个箱;
5、特征构造:
构造统计量特征,报告计数、求和、比例、标准差等;
时间特征,包括相对时间和绝对时间,节假日,双休日等;
地理信息,包括分箱,分布编码等方法;
非线性变换,包括 log/ 平方/ 根号等;
特征组合,特征交叉;
仁者见仁,智者见智。
6、特征筛选
过滤式(filter):先对数据进行特征选择,然后在训练学习器,常见的方法有 Relief/方差选择发/相关系数法/卡方检验法/互信息法;
包裹式(wrapper):直接把最终将要使用的学习器的性能作为特征子集的评价准则,常见方法有 LVM(Las Vegas Wrapper) ;
嵌入式(embedding):结合过滤式和包裹式,学习器训练过程中自动进行了特征选择,常见的有 lasso 回归;
7、降维
PCA/ LDA/ ICA;
特征选择也是一种降维

4、建模调参

可以使用sklearn中一些常用机器学习模型或者配合nn模型

from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
from lightgbm.sklearn import LGBMRegressor
train_X,test_X,train_y,test_y = train_test_split(train_X_all,train_y_all,test_size=0.3,random_state=3)

models = [LinearRegression(),
          RandomForestRegressor(30),
          GradientBoostingRegressor(),
          LGBMRegressor(n_estimators = 100)]

result=[]
for model in models:
    model_name = str(model).split('(')[0]
    model.fit(X=train_X, y=train_y)
    result.append(model.predict(test_X))
    scores = cross_val_score(model, X=train_X, y=train_y, verbose=0, cv = 5)
    print(model_name,':',scores)
    print(model_name + ' is finished')
df=pd.DataFrame(result)

在此介绍了三种常用的调参方法如下:

贪心算法
网格调参
贝叶斯调参

5、模型融合

模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。

简单加权融合:
回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);
分类:投票(Voting)
综合:排序融合(Rank averaging),log融合
stacking/blending:
构建多层模型,并利用预测结果再拟合预测。
boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):
多树的提升方法

你可能感兴趣的:(一个完整机器学习实战的总结)