以波士顿房价数据进行数据分析
文章目录
1 总体分析步骤
- 加载数据
- 概览数据
- 缺失值处理
- 变量分析
- 单一变量
- 多变量关系
2 数据加载
- 载入数据
house = pd.read.csv("./data/boston.csv").head()
- 数据的规模
house.shape
- 数据集的每一列的列名
house.columns
- 基本统计描述
house.describe()
/house.info()
- 查看是否有缺失值
- 查看数据是否正常,例如A是一个处于[0,1]之间的比值,但在展示中A>1,说明数据不正常,需要修正
- 查看统计数据是否正常,例如方差特别大,在后续的处理中,可以采用一些降维的手段如:主成分分析(PCA)等
3 数据处理
3.1 缺失值处理
- 总体查看:
null.info()
- 查看样本总数为506,非空值不等于506的即为含有缺失值的特征
- 缺失值计算:
null.isnull().sum()
- 缺失值可视化
- 柱状图
missing = null.isnull().sum()
missing = missing[missing > 0] # 筛选出有缺失值(大于0)的特征
missing.sort_values(inplace = True) # 排序
missing.plot.bar() # 调用pandas内置的条形图绘制
-
热力图
sns.heatmap(null.isnull())
-
热力图可以帮助看出缺失值的位置,如果有些样本出现大量特征缺失的情况,在样本足够大的情况下也可以考虑删除
- 统计缺失比例
A = []
for col in null.columns:
A.append((col,
null[col].isnull().sum() * 100 / null.shape[0]))
pd.DataFrame(A, columns=['Features', 'missing rate'])
- 缺失值超过95%的特征,会考虑删除,因为意义不大
- 方差特别小的特征也考虑删除,或者说取值唯一的特征是没有意义的;举例,如果在一次考试中,大家的数学成绩都是100分,那么是没有办法通过数学成绩来区分每位同学的能力的,也就是说数学这门课没有区分性,不具有分析的意义,可以删掉
- 统计每个特征会有多少不同取值
df.nunique()
- 为了更好的呈现,将特征的唯一值个数加入到上面的统计表中,并封装成函数,便于之后使用
def df_stats(df):
'''
统计该df的缺失值,比例以及唯一值个数.
'''
L = []
for col in df.columns:
L.append((col,
df[col].isnull().sum(),
df[col].isnull().sum() * 100 / df.shape[0],
df[col].nunique()))
res = pd.DataFrame(L, columns = ['Feature',
'missing num',
'missing rate',
'unique num'])
return res
- 缺失值填充
null = null.fillna(null.mean()) # 用均值填充
-
这是比较简单粗暴的方式,之后会细讲缺失值处理方式
-
可视化查看
sns.heatmap(null.isnull())
此时已没有缺失值
3.2 变量分析
- 研究思路:首先研究单变量的数据类型、分布情况、是否有离群值等情况,再研究变量之间的关系:相关性分析、分组统计等
3.2.1 单变量分析
3.2.1.1 分析标签
- 标签类型
- 首先是分析数据标签,要明白任务的需求。数据挖掘任务主要分为两类:回归与分类。
- 回归指标签值是连续值的任务,例如用到的数据集,要求预测房价信息,房价是一个连续的变量,因此这样的任务属于回归问题(Regression)
- 分类指标签值离散的任务,例如鸢尾花(Iris)数据集,收集三种鸢尾花的萼片长度,宽度等信息,要求根据这些信息预测鸢尾花属于哪种类别,因此标签就是1,2,3,代表三类鸢尾花。这种任务属于分类任务
-
house["MEDV"].nunique()
查看标签的取值:因为取值个数比较多,可以大致判断本次任务属于回归型任务。 但这并非判断标准,只是一个判断的参考,主要还是分析题目的任务需求 -
house["MEDV"].describe()
打印标签的统计信息:
- 从统计信息可以大致看出,分布还算正常,没有太大的方差(方差太大说明数据不太可能是正态的,因为不够集中)。对于是否有离群值后面我们需要通过箱线图或者散点图等可视化分析后才能得知
- 画密度分布图,看标签取值的总体分布情况
plt.figure()
sns.distplot(house["MEDV"],
bins=100,#柱子的个数
hist=True,#是否绘制直方图
kde=True,#是否绘制密度图
rug=True,#数据分布标尺
color='r',#颜色
# vertical=False,#是否水平绘制
# norm_hist=False,#标准化,kde为True时自动标准化
axlabel=None,#x轴标注
label=None,#图例标签,通过plt.legend()显示
ax=None,
)
- 如图
- 看到整个分布稍微有一点左偏,因此在实战中,我们可以采用对数化的方法,让标签分布接近正态
plt.figure()
sns.distplot(np.log(house["MEDV"]),
bins=100,#柱子的个数
hist=True,#是否绘制直方图
kde=True,#是否绘制密度图
rug=True,#数据分布标尺
color='r',#颜色
# vertical=False,#是否水平绘制
# norm_hist=False,#标准化,kde为True时自动标准化
axlabel=None,#x轴标注
label=None,#图例标签,通过plt.legend()显示
ax=None,
)
- 变换之后,可以将取值小于1.5的取值视为异常值,将其舍弃
- 对于分类任务而言,可以采用此法画出它的频率分布直方图,或者更直接的画条形统计图,如果分类的标签分布是相似的,那么我们可以直接建模;如果标签出现很明显的一高一低的情况,说明标签的分布不均衡,在建模前需要做一些操作(例如&