机器学习算法竞赛实战-数据探索
机器学习算法竞赛实战-数据探索
本文是《机器学习算法竞赛实战》的读书笔记2:在进行建模之前如何进行数据探索,了解数据的基本情况。通过系统的探索加深对数据的理解。
<!--MORE-->
数据探索
分析思路是什么
最好使用多种思路和方法来探索每个变量并比较结果。
分析方法有哪些
- 单变量可视化分析
- 多变量可视化分析
- 降维分析
明确分析目的
如果跳过数据探索阶段或者只做肤浅的分析工作,可能导致数据倾斜,出现异常值或者缺失值。
数据探索的目的:
- 用于回答业务问题,测试业务假设,生成进一步分析的假设
- 为后面的建模准备数据
7大必做事
数据探索阶段必须做的7件事:
- 数据集基本情况
- 重复值、缺失值、异常值处理
- 特征冗余:比如单位cm和m
- 是否存在时间信息:时间的相关性、趋势性、周期性等分析
- 标签分布:对于分类问题,是否存在类别分布不均衡;对于回归问题,是否存在异常值,整体分布如何,是否需要进行目标转换
- 训练集和测试集的分布:是否有测试集中存在的特征字段,但是训练集中没有
- 单变量/多变量分布:熟悉特征的分布情况,以及特征和标签的对应关系
数据描述信息
- df.describe:查看数据的分布,得到多个统计量信息
- df.head:查看前N条数据信息,默认前5条
- df.shape:数据集的形状,行列数
- df.info:快速获得对数据集的简单描述,比如每个变量的类型、数据集的大小和缺失值等情况
In 1:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from sklearn.model_selection import KFold # K折交叉验证
from sklearn.metrics import mean_squared_error #评价指标mse
from sklearn.preprocessing import OneHotEncoder # 独热码
import lightgbm as lgb # lgb模型
import warnings
warnings.filterwarnings("ignore")
导入数据:
In 2:
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")
展示特征字段的nunique和缺失值情况:
In 3:
train.head()
Out3:
字段的缺失值情况:
In 4:
train.isnull().sum()
Out4:
Id 0
MSSubClass 0
MSZoning 0
LotFrontage 259
LotArea 0
...
MoSold 0
YrSold 0
SaleType 0
SaleCondition 0
SalePrice 0
Length: 81, dtype: int64
In 5:
train["LotFrontage"].value_counts(normalize=True,dropna=True)
Out5:
60.0 0.119067
70.0 0.058285
80.0 0.057452
50.0 0.047460
75.0 0.044130
...
137.0 0.000833
141.0 0.000833
38.0 0.000833
140.0 0.000833
46.0 0.000833
Name: LotFrontage, Length: 110, dtype: float64
In 6:
train["LotFrontage"].value_counts(normalize=True)
Out6:
60.0 0.119067
70.0 0.058285
80.0 0.057452
50.0 0.047460
75.0 0.044130
...
137.0 0.000833
141.0 0.000833
38.0 0.000833
140.0 0.000833
46.0 0.000833
Name: LotFrontage, Length: 110, dtype: float64
字段唯一值情况
In 7:
stats = []
for col in train.columns:
stats.append((col, # 字段名称
train[col].nunique(), # 唯一值数目
train[col].isnull().sum() * 100 / train.shape[0], # 该字段的缺失值比例
train[col].value_counts(normalize=True,dropna=False).values[0] * 100, # 字段中每个值的占比,取最高的那个值
train[col].dtype # 字段类型
))
stats_df = pd.DataFrame(stats,
columns=["Feature","Unique_values","Percentage of missing values",
"Percentage of values in biggest category","type"])
# 某些字段的缺失值比例高达95%,可以直接删除
stats_df.sort_values("Percentage of missing values", ascending=False)[:10]
缺失值
使用柱状图直观显示缺失值分布情况:
In 8:
missing = train.isnull().sum()
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()
变量分析
- 单变量或者多变量分析
- 变量和标签间的相关性,并且进行假设检验
单变量分析
单变量分为:
- 标签
- 连续型
- 类别型
标签
In 9:
train["SalePrice"].describe()
Out9:
count 1460.000000
mean 180921.195890
std 79442.502883
min 34900.000000
25% 129975.000000
50% 163000.000000
75% 214000.000000
max 755000.000000
Name: SalePrice, dtype: float64
In 10:
# 可视化查看数据分布情况
plt.figure(figsize=(9,8))
sns.distplot(train["SalePrice"], color="g",bins=100, hist_kws={"alpha":0.4})
plt.show()
小结:数据呈现正态分布,向右倾斜,存在峰值。
对字段的取值进行取对数操作:
In 11:
# 取对数np.log
plt.figure(figsize=(9,8))
sns.distplot(np.log(train["SalePrice"]), color="b",bins=100, hist_kws={"alpha":0.4})
plt.show()
连续型
In 12:
# 可视化查看数据分布情况
plt.figure(figsize=(10,8))
sns.displot(
data=train,
x="LotArea",
kind="hist",
aspect=2
)
# plt.grid()
plt.show()
In 13:
# # 可视化查看数据分布情况
# plt.figure(figsize=(10,8))
# sns.displot(
# data=train,
# x="LotFrontage",
# kind="hist",
# aspect=2
# )
# # plt.grid()
# plt.show()
In 14:
# 可视化查看数据分布情况
plt.figure(figsize=(10,8))
sns.displot(data=train,x="MSSubClass",kind="hist",aspect=2)
plt.show()
In 15:
# # 可视化查看数据分布情况
# plt.figure(figsize=(10,8))
# sns.displot(data=train,x="MSSubClass",kind="hist",aspect=2)
# plt.show()
In 16:
plt.figure(figsize=(10,8))
sns.displot(data=train,x="OverallQual",kind="hist",aspect=2)
plt.show()
<Figure size 720x576 with 0 Axes>
In 17:
df_num = train.select_dtypes(include=["float64","int64"])
df_num = df_num[df_num.columns.tolist()[1:5]]
df_num.hist(figsize=(16,20), bins=50,xlabelsize=8,ylabelsize=8)
plt.show()
连续型变量相关性(附)
- 正相关:如果一个特征增加导致另一个特征增加,则它们正相关。值1表示完全正相关
- 负相关:如果一个特征增加导致另一个特征减少,则它们负相关。值-1表示完全正相关
如果两个特征完全正相关,这意味着两个特征包含高度相似的信息,信息中几乎没有或者完全没有差异,这就是多重线性。
所以可以尽可能删除冗余特征,降低训练时间和难度。
In 18:
corrmat = train.corr()
f, ax = plt.subplots(figsize=(20,9))
sns.heatmap(corrmat, vmax=0.8, square=True)
plt.show()
类别型
- 观察类别型变量的基本分布情况:即观察每个属性的频次
- 根据频次统计信息,发现热点属性和极少出现的属性
数据字段:
字段的基本统计量信息:
In 22:
plt.figure(figsize=(8,6))
sns.countplot(df_cat["MSZoning"])
plt.show()
plt.figure(figsize=(8,6))
sns.countplot(df_cat["Street"])
plt.show()
多变量分析
In 24:
plt.style.use("seaborn-white")
type_cluster = train.groupby(["Neighborhood","OverallQual"]).size()
type_cluster.head()
Out24:
Neighborhood OverallQual
Blmngtn 7 14
8 3
Blueste 6 2
BrDale 5 5
6 11
dtype: int64
In 25:
type_cluster.unstack() # 部分截图
# plt.figure(figsize=(20,10))
type_cluster.unstack().plot(kind="bar",
stacked=True,
colormap="coolwarm_r",
figsize=(13,11),
grid=False)
plt.xlabel("OverallQual",fontsize=16)
plt.show()
plt.figure(figsize=(18,12))
sns.boxplot(data=train, x="Neighborhood",y="SalePrice")
plt.show()
小结:上面的图形说明高评价位置(NoRidge、NrigHt和StoneBr)对应高SalePrice,也说明房屋位置评价和高房价有较强的相关性。可以构造新特征:
- 两个类别特征的交叉组合特征
- 组合特征下房屋均价
模型分析
学习曲线
学习曲线是机器学习中用来进行模型效果评估的工具,能够反映训练集和验证集在训练迭代中的分数变化情况。
欠拟合:指模型无法学习到训练集中数据所展现的信息。一般如果训练的损失曲线是一条平坦的线或者相对较高的线,这就表明该模型根本无法学习训练集。 过拟合:模型对训练集学习得很好,但是对新数据的学习效果很差,导致泛化能力差
欠拟合和过拟合曲线的对比:
特征重要性分析
通过模型训练可以得到特征重要性,比如树模型通过计算特征的信息增益或者分裂次数等得到特征的重要性,模型LR或者SVM等使用特征系数作为特征重要组成部分(特征系数越大,则表示对模型的影响越大)。
误差分析
误差分析就是我们通过模型预测的结果来发现问题的关键所在。
- 回归问题:看预测结果的分布
- 分类问题:看混淆矩阵
相关文章
- 机器学习十大经典算法之K-Means聚类算法
- 机器学习十大经典算法之随机森林
- 机器学习算法——线性回归(超级详细且通俗)
- 机器学习之–神经网络算法原理
- 人工智能基础:机器学习常见的算法介绍
- 机器学习算法(一)SVM
- 8个常见的机器学习算法的计算复杂度总结
- 机器学习经典算法:决策树(2)
- AI加速器与机器学习算法:协同设计与进化
- 机器学习经典算法:决策树(2)
- 《机器学习算法竞赛实战笔记1》:如何看待机器学习竞赛问题?
- A.机器学习算法入门教程(一): 基于逻辑回归的分类预测
- A.机器学习入门算法(四): 基于支持向量机的分类预测
- 机器学习算法(九): 基于线性判别模型的LDA手写数字分类识别
- A.机器学习入门算法(五):基于企鹅数据集的决策树分类预测
- 【干货书】时间序列算法导论:使用Python实现机器学习和深度学习技术
- OpenAI再获100亿美元?DoNotPay力砸100万仅为AI律师辩护复述;新冠四种亚型被机器学习算法进行归纳
- 19位算法工程师总结:机器学习项目成功落地的三条秘诀
- 机器学习工程师必知的十大算法详解架构师
- 机器学习的发展历史以及算法演进
- MIT研发脑控机器人,全新机器学习算法识别脑波只需10ms