EDA(Exploratory Data Analysis)

全名数据探索性分析知乎参考文档

1.Look at data to see what it seems to say.

2.Uncover underlying structures.

3.Isolate important variables.

4.Detect outliers and other anomalies.

5.Suggest suitable models for conventional statistics.

绘图:时序图(周期性)、直方图(分布)、折线图、箱线图(查看异常)、小提琴图(箱线图进阶版,可以查看分布密度)

量化:基本统计信息(均值、方差)、取值范围,分布

数据挖掘笔记 - 图1

数据层——描述层——解读层——结论层

数据理解

目的:探索数据,了解数据,主要在EDA阶段完成。

1.定性数据:描述性质

  1. a)定类:按名称分类——血型、城市
  2. b)定序:有序分类——成绩(A B C)

2.定量数据:描述数量

  1. a)定距:可以加减——温度、日期
  2. b)定比:可以乘除——价格、重量

数据清洗

目的: 提高数据质量,点各地算法用错误数据建模的风险

1.特征变换:模型无法处理或不适合处理

  1. a) 定性变量编码:Label EncoderOnehot EncoderDistribution Encoder
  2. b) 标准化和归一化:Z分数标准化(标准正态分布)、min-max归一化;

2.缺失值处理:增加不确定性,可能会导致不可靠输出

  1. a)不处理:少量样本缺失;
  2. b) 删除:大量样本缺失;
  3. c) 补全:(同类)均值/中位数/众数补全;高维映射(one-hot);模型预测;最近邻补全;矩阵补全(R-SVD)

3.异常值处理:减少脏数据

  1. a) 简单统计: 如:describe() 的统计描述;散点图等;
  2. b) 3$\partial $法则(正态分布)/箱线图删除/截断;
  3. c) 利用模型进行离群点检测:聚类、K近邻、One Class SVMIsolation Forest

4.其他: 删除无效列/更改dtypes/删除列中的字符串/将时间戳从字符串转换为日期时间格式等

特征构造

目的:增强数据表达,添加先验知识

1.统计特征:

  1. a) 计数、求和、比例、标准差;

2.时间特征:

  1. a) 绝对是件、相对时间、节假日、双休日;

3.地理信息:

  1. a) 分桶;

4.非线性变换:

  1. a) log/平方、根号;

5.数据分桶;

  1. a) 等频/等距分桶、Best-KS分桶、卡方分桶;

6.特征组合/特征交叉

特征选择

目的:平衡预测能力和计算复杂度;降低噪声,增强模型预测性能。

1.过滤式(Filter) :先用特征选择方法对初识特征进行过滤然后再训练学习器,特征选择过程与后续学习器无关。

  1. a) Relief/方差选择/相关系数/卡方检验/互信息法

2.包裹式 (Wrapper) :直接把最终将要使用的学习器的性能作为衡量特征子集的评价准则,其目的在于为给定学习器选择最有利于其性能的特征子集。

  1. a) Las Vegas Wrapper(LVM)

3.嵌入式(Embedding) :结合过滤式和包裹式方法,将特征选择与学习器训练过程融为一体,两者在同一优化过程中完成,即学习器训练过程中自动进行了特征选择。

  1. a) LR+L1或决策树

类别不平衡

缺点:少类别提供信息太少,没有学会如何判别少数类。

1.扩充数据集;

2.尝试其他评价指标: AUC等;

3.调整θ值;

4.重采样: 过采样/欠采样:

5.合成样本: SMOTE;

6.选择其他模型:决策树等;

7.加权少类 别的样本错分代价:

8.创新:

  1. a)将大类分解成多个小类:
  2. b) 将小类视为异常点,并用异常检测建模。

删除异常值

这个代码是直接删除数据,这个如果要使用,不要对测试集用哈。下面看看power这个特征的分布也不错了,所以就没再进一步处理power,至于其他的数值型是不是需要截尾,需要自己决策。

  1. def outliers_proc(data, col_name, scale=3):
  2. """
  3. 用于清洗异常值,默认用 box_plot(scale=3)进行清洗
  4. :param data: 接收 pandas 数据格式
  5. :param col_name: pandas 列名
  6. :param scale: 尺度
  7. :return:
  8. """
  9. def box_plot_outliers(data_ser, box_scale):
  10. """
  11. 利用箱线图去除异常值
  12. :param data_ser: 接收 pandas.Series 数据格式
  13. :param box_scale: 箱线图尺度,
  14. :return:
  15. """
  16. iqr = box_scale * (data_ser.quantile(0.75) - data_ser.quantile(0.25))
  17. val_low = data_ser.quantile(0.25) - iqr
  18. val_up = data_ser.quantile(0.75) + iqr
  19. rule_low = (data_ser < val_low)
  20. rule_up = (data_ser > val_up)
  21. return (rule_low, rule_up), (val_low, val_up)
  22. data_n = data.copy()
  23. data_series = data_n[col_name]
  24. rule, value = box_plot_outliers(data_series, box_scale=scale)
  25. index = np.arange(data_series.shape[0])[rule[0] | rule[1]]
  26. print("Delete number is: {}".format(len(index)))
  27. data_n = data_n.drop(index)
  28. data_n.reset_index(drop=True, inplace=True)
  29. print("Now column number is: {}".format(data_n.shape[0]))
  30. index_low = np.arange(data_series.shape[0])[rule[0]]
  31. outliers = data_series.iloc[index_low]
  32. print("Description of data less than the lower bound is:")
  33. print(pd.Series(outliers).describe())
  34. index_up = np.arange(data_series.shape[0])[rule[1]]
  35. outliers = data_series.iloc[index_up]
  36. print("Description of data larger than the upper bound is:")
  37. print(pd.Series(outliers).describe())
  38. fig, ax = plt.subplots(1, 2, figsize=(10, 7))
  39. sns.boxplot(y=data[col_name], data=data, palette="Set1", ax=ax[0])
  40. sns.boxplot(y=data_n[col_name], data=data_n, palette="Set1", ax=ax[1])
  41. return data_n

模型选择

参数调优

网格搜索