“GitModel统计分析”学习的Task02EDA-学习日志

学习日志


本文章为天池“GitModel统计分析”学习的Task02EDA-学习日志


# !pip install jupyterlab "ipywidgets>=7.5"
# !pip install npm
# !conda install -c conda-forge nodejs
# !pip install plotly

# 加载必要库
import pandas as pd # 数据分析库
import numpy as np # 矩阵计算
import matplotlib.pyplot as plt # 画图

import plotly.express as px # 画图
from statsmodels.graphics.gofplots import qqplot # 统计模型
import seaborn as sns # 统计绘图


# 避免产生报警告
import warnings
warnings.filterwarnings('ignore')

plt.rcParams['font.sans-serif']=['SimHei']#引入中文字体
plt.rcParams['axes.unicode_minus'] = False


plt.rcParams['font.sans-serif']=['KaiTi']
plt.rcParams['axes.unicode_minus'] = False #引入中文字体

#
pd.set_option("display.max_rows", 50) #可显示100
pd.set_option("display.max_columns", 40)#可显示10列

#----------------数据读取----------------
data = pd.read_csv("D:/python/ITEM/HousePrice of Boston/Data/boston.csv")
print(data.head(5))# 读前五行
"""
CRIM:按城镇划分的人均犯罪率
ZN:划分为超过 25,000 平方英尺地块的住宅用地比例。
INDUS:每个城镇的非零售商业用地的比例
CHAS:Charles River 虚拟变量(如果区域以河流为界,则为 1;否则为 0)
NOX:一氧化氮浓度(每 1000 万分之一)[parts/10M]
RM:每户住宅的平均房间数
AGE:1940 年之前建造的自住单元的比例
DIS:到波士顿五个就业中心的加权距离
RAD:通往径向高速公路的指数
TAX:全每 10,000 美元的价值财产税率 [$/10k]
PTRATIO:按城镇划分的师生比例
B:等式 B=1000(Bk-0.63)^2的结果,其中 Bk是城镇中黑人的比例
LSTAT:人口地位较低的百分比

"""
#----------------数据概况----------------
print(data.shape)
#(506, 14)
print(data.columns)
"""
Index(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX',
       'PTRATIO', 'B', 'LSTAT', 'MEDV'],
      dtype='object')
"""
print(data.describe())
"""
            CRIM          ZN       INDUS        CHAS         NOX          RM  \
count  506.000000  506.000000  506.000000  506.000000  506.000000  506.000000   
mean     3.613524   11.363636   11.136779    0.069170    0.554695    6.284634   
std      8.601545   23.322453    6.860353    0.253994    0.115878    0.702617   
min      0.006320    0.000000    0.460000    0.000000    0.385000    3.561000   
25%      0.082045    0.000000    5.190000    0.000000    0.449000    5.885500   
50%      0.256510    0.000000    9.690000    0.000000    0.538000    6.208500   
75%      3.677083   12.500000   18.100000    0.000000    0.624000    6.623500   
max     88.976200  100.000000   27.740000    1.000000    0.871000    8.780000   

              AGE         DIS         RAD         TAX     PTRATIO           B  \
count  506.000000  506.000000  506.000000  506.000000  506.000000  506.000000   
mean    68.574901    3.795043    9.549407  408.237154   18.455534  356.674032   
std     28.148861    2.105710    8.707259  168.537116    2.164946   91.294864   
min      2.900000    1.129600    1.000000  187.000000   12.600000    0.320000   
25%     45.025000    2.100175    4.000000  279.000000   17.400000  375.377500   
50%     77.500000    3.207450    5.000000  330.000000   19.050000  391.440000   
75%     94.075000    5.188425   24.000000  666.000000   20.200000  396.225000   
max    100.000000   12.126500   24.000000  711.000000   22.000000  396.900000   

            LSTAT        MEDV  
count  506.000000  506.000000  
mean    12.653063   22.532806  
std      7.141062    9.197104  
min      1.730000    5.000000  
25%      6.950000   17.025000  
50%     11.360000   21.200000  
75%     16.955000   25.000000  
max     37.970000   50.000000

可以考虑将CRIM,ZN,INDUS化为[0,1]之间的实数
TAX,B,AGE方差较大,可以采用一些降维的手段如:主成分分析(PCA)等
"""
print(data.info())
"""
RangeIndex: 506 entries, 0 to 505
Data columns (total 14 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   CRIM     506 non-null    float64
 1   ZN       506 non-null    float64
 2   INDUS    506 non-null    float64
 3   CHAS     506 non-null    int64  
 4   NOX      506 non-null    float64
 5   RM       506 non-null    float64
 6   AGE      506 non-null    float64
 7   DIS      506 non-null    float64
 8   RAD      506 non-null    int64  
 9   TAX      506 non-null    int64  
 10  PTRATIO  506 non-null    float64
 11  B        506 non-null    float64
 12  LSTAT    506 non-null    float64
 13  MEDV     506 non-null    float64
dtypes: float64(11), int64(3)
显示无缺失值
"""

#----------------数据处理----------------

#----------------缺失值处理----------------
null = pd.read_csv("D:/python/ITEM/HousePrice of Boston/Data/boston_null.csv")
print(null.head(5))# 读前五行
print(null.info())
"""
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   CRIM     506 non-null    float64
 1   ZN       506 non-null    float64
 2   INDUS    506 non-null    float64
 3   CHAS     506 non-null    int64  
 4   NOX      504 non-null    float64
 5   RM       504 non-null    float64
 6   AGE      505 non-null    float64
 7   DIS      491 non-null    float64
 8   RAD      506 non-null    int64  
 9   TAX      506 non-null    int64  
 10  PTRATIO  506 non-null    float64
 11  B        453 non-null    float64
 12  LSTAT    506 non-null    float64
 13  MEDV     506 non-null    float64
dtypes: float64(11), int64(3)
由上可知NOX,RM,AGE,DIS,B 存在空值
"""
#----------------缺失值处理-1.null进行计数---------------
print(null.isnull().sum())
"""
None
CRIM        0
ZN          0
INDUS       0
CHAS        0
NOX         2
RM          2
AGE         1
DIS        15
RAD         0
TAX         0
PTRATIO     0
B          53
LSTAT       0
MEDV        0
dtype: int64
"""
#----------------缺失值处理-2.缺失值可视化---------------
# 缺失值可视化
missing = null.isnull().sum()
missing = missing[missing > 0] # 筛选出有缺失值(大于0)的特征
missing.sort_values(inplace = True) # 排序
missing.plot.bar() # 调用pandas内置的条形图绘制
plt.show()

sns.heatmap(null.isnull())
plt.show()
"""
如果缺失值少,或者大量特征缺失但是在样本足够大的情况下也可以考虑删除.否则不建议删除
"""
#----------------缺失值处理-3.统计缺失比例---------------
A = []
for col in null.columns:
    A.append((col,
             null[col].isnull().sum() * 100 / null.shape[0]))#每列NULL个数/样本含量
pd.DataFrame(A, columns=['Features', 'missing rate'])
print(A)
"""
[('CRIM', 0.0),
 ('ZN', 0.0), 
 ('INDUS', 0.0),
  ('CHAS', 0.0), 
  ('NOX', 0.3952569169960474), 
  ('RM', 0.3952569169960474),
  ('AGE', 0.1976284584980237),
   ('DIS', 2.964426877470356), 
   ('RAD', 0.0), 
   ('TAX', 0.0), 
   ('PTRATIO', 0.0), 
   ('B', 10.474308300395258), 
   ('LSTAT', 0.0), 
   ('MEDV', 0.0)]
如果缺失值超过95%的特征,我们会考虑删除它,因为意义不大.
"""
print(null.nunique()) #另一类特征也可以考虑删除,那就是方差特别小,或者说取值唯一的特征是没有意义的.,即只有一种取值
"""
CRIM       504
ZN          26
INDUS       76
CHAS         2
NOX         81
RM         445
AGE        356
DIS        401
RAD          9
TAX         66
PTRATIO     46
B          326
LSTAT      455
MEDV       229
dtype: int64

Process finished with exit code 0

"""
#将missing和unique合在一起
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

print(df_stats(null))
"""
    Feature  missing num  missing rate  unique num
0      CRIM            0      0.000000         504
1        ZN            0      0.000000          26
2     INDUS            0      0.000000          76
3      CHAS            0      0.000000           2
4       NOX            2      0.395257          81
5        RM            2      0.395257         445
6       AGE            1      0.197628         356
7       DIS           15      2.964427         401
8       RAD            0      0.000000           9
9       TAX            0      0.000000          66
10  PTRATIO            0      0.000000          46
11        B           53     10.474308         326
12    LSTAT            0      0.000000         455
13     MEDV            0      0.000000         229

Process finished with exit code 0
#

"""
#----------------缺失值处理-4.缺失值填充---------------
null = null.fillna(null.mean()) # 用均值填充
"""
空值填充方法
一、直接填充
0/-1值填充
单变量填补:用单一变量的均值/中位数/众数/二分之一最小值/零值进行补值
二、插值填充
所谓的插值法就是通过两点(x0,y0),(x1,y1)估计中间点的值
三、KNN预测缺失值进行填充
步骤是选择出其他不存在缺失值的列,同时去除掉需要预测缺失值的列存在缺失值的行,然后计算距离。
如果缺失值是离散的,使用K近邻分类器,投票选出K个邻居中最多的类别进行填补;如果为连续变量,则用K近邻回归器,拿K个邻居中该变量的平均值填补。
四、Kmeans预测缺失值进行填充
参考:https://blog.csdn.net/vivian_ll/article/details/91900323
"""
sns.heatmap(null.isnull())
plt.show()

#----------------变量分析----------------
"""
1.研究单变量随机变量的性质与特征刻画
分析一个变量的情况,包括但不限于:数据类型、分布情况、是否有离群值
2.研究随机变量之间的关系. 
相关性分析、分组统计···
"""
#----------------单变量分析----------------
#1.分析标签
"""
明白任务的需求:数据挖掘任务主要分为两类:回归与分类.
回归:是指标签值是连续值的任务,例如预测房价信息,房价是一个连续的变量,任务属于回归问题(Regression).
分类:标签是离散的数据分析任务,鸢尾花(Iris)数据集,它收集了三种鸢尾花的萼片长度,宽度等信息,要求预测鸢尾花属于哪种类别,因此它的标签就是123,代表三类鸢尾花. 


本次任务属于回归型任务
"""
print(data["MEDV"].nunique())
#229

print(data["MEDV"].describe())#统计信息
"""
count    506.000000
mean      22.532806
std        9.197104
min        5.000000
25%       17.025000
50%       21.200000
75%       25.000000
max       50.000000
Name: MEDV, dtype: float64
Process finished with exit code 0
方差不大但是不够集中,非正态,极值较正常
"""
#密度分布图
plt.figure()
sns.distplot(data["MEDV"],
            bins=100,#柱子的个数
            hist=True,#是否绘制直方图
            kde=True,#是否绘制密度图
            rug=True,#数据分布标尺
            color='b',#颜色
#             vertical=False,#是否水平绘制
#             norm_hist=False,#标准化,kde为True时自动标准化
            axlabel=None,#x轴标注
            label=None,#图例标签,通过plt.legend()显示
            ax=None,
            )
plt.show()
#分布呈现轻微右偏,可以考虑用对数化处理让其符合正态分布

plt.figure()
sns.distplot(np.log(data["MEDV"]+1),
            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.show()

"""
分类任务:
采用此法画出频率分布直方图,或者直接更直接的画图条形统计图.
如果分类的标签分布是相似的,可以直接建模. 但如果标签出现很明显的一高一低的情况,说明标签的分布不均衡,那再建模前需要做一些操作(例如:欠采样、调整损失函数),再进行建模. 
否则会出现一个问题,模型会对出现频率低的样本非常不敏感. 模型训练的过程就类似考前复习的过程,所以我们在建模前要尽量保证标签的均衡性.
"""
#----------------离散型变量----------------

data[['CHAS', 'RAD']].hist()
plt.show()
#类别型变量更大的作用是用于后续在特征工程中,用于进行特征交叉,继续特征的增强,挖掘更深层次的潜在信息.
#----------------连续型变量----------------
data[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'TAX', 'PTRATIO', 'B', 'LSTAT']].hist(bins=100)
plt.show()

"""
变量实际上是有相似(A高B高)的分布情况的,或者相反的分布情况的(A高B低),这样的性质称为变量之间的相关性. 相关性一般有两种情况:
正相关:如果特征A的增加(减少)会导致特征B增加(减少),即特征A与特征B变化趋势相同.
负相关:如果特征A的增加(减少)会导致特征B减少(增加),即特征A与特征B变化趋势相反.
当两个变量呈正相关或者负相关时,我们称两个变量是相关的. 如果两个变量有较强的相关性时,如果将这些变量一起用的话,会有很多是冗余的. 因为这样变量之间有较强的相关性,
那么变量与变量之间是可以相互表示的,所以在建模时,需要尽可能消除特征之间的共线性,也就是尽量使用相关性比较小的特征,这样可以减少训练时间,使得模型的学习效果更好.那么下面我们讲讲如何去刻画特征间的相关性.
"""

#----------------多变量分析----------------
#1. 相关性
"""
可视化而言,最简单的方式就是将两个特征对应的坐标点在坐标系下描出来,研究他们的变化趋势,也就是说每一个点的坐标试一个二元组(Xai,ybi),
其中Xai表示第i个样本,特征a的取值;
ybi表示第i个样本,特征b的取值. 我们用seaborn库可以很直观的任意两个特征之间的散点图.
"""
# 任意两个变量间的相关性散点图来判断
sns.set()
cols = data.columns # 罗列出数据集的所有列
sns.pairplot(data[cols], size = 2.5) # 成对画出任意两列的散点图
plt.show()

"""
分析:
1.先看图像呈“对角线分布的”,即/或者\这两种类型分布的图像,这样的图像说明这两个变量间有较强的相关性,是可以被消除共线性的“嫌疑对象”. 
如图中的DIS和AGE,尽管他不是严格的直线分布,但至少其分布呈现带状
2.看那些趋势比较明显单调,但是不太像直线,而是类似于“对数函数”的图像,
例如图中的DIS和NOX,因为这类图像,只要做一下对数化,马上就可以得到类似直线的效果,那么也是可以被处理的.
3.关注需要得出的预测结果,一般最后一行(列)与其他行(列)的关系,也就是特征与标签的关系,
如果这两者出现了较强相关性,那么这些特征我们需要留意,因为这些特征对标签有着比较直接的关系,例如RM和LSTAT.
"""
sns.pairplot(data[["AGE", "DIS"]], size = 3) # 成对画出任意两列的散点图, size是点的大小
plt.show()
sns.pairplot(np.log(data[["NOX", "DIS"]]), size = 3)
plt.show()
sns.pairplot(np.log(data[["RM", "LSTAT", "MEDV"]]), size = 3)
plt.show()

#2.刻画两个随机变量的相关性的方法:协方差与相关系数.
print(data.cov())
# 直接计算相关性系数
Corr_Matrix = data.corr()
print(Corr_Matrix)
#相关性系数,采用热力图进行可视化
#correlation matrix
f, ax = plt.subplots(figsize=(12, 9)) # 设置画布
sns.heatmap(Corr_Matrix, vmax=.8, square=True # 画热力图
#             , annot=True # s是否显示数值
           )
plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值