对比赛数据做EDA
- 数据分析
- 缺失值分析
- 特征值分析
- 是否有单调特征列(单调的特征列很大可能是时间)
- 特征nunique分布
- 出现在测试集中的community,但是在训练集中数量较少
- 统计特征值出现频次大于100的特征
- Label分布
- 不同的特征值的样本的label的分布
#导入相关的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
#导入数据
train_data=pd.read_csv('train_data.csv')
train_data['Type']='train' #新插入一列作为数据集辨识符,供后面训练集和测试集融合用
test_data = pd.read_csv('./test_a.csv')
test_data['Type'] = 'Test'
data_all = pd.concat([test_data, test_data])
train_data.head()
ID | area | rentType | houseType | houseFloor | totalFloor | houseToward | houseDecoration | communityName | city | ... | landMeanPrice | totalWorkers | newWorkers | residentPopulation | pv | uv | lookNum | tradeTime | tradeMoney | Type | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100309852 | 68.06 | 未知方式 | 2室1厅1卫 | 低 | 16 | 暂无数据 | 其他 | XQ00051 | SH | ... | 0.0000 | 28248 | 614 | 111546 | 1124.0 | 284.0 | 0 | 2018/11/28 | 2000.0 | train |
1 | 100307942 | 125.55 | 未知方式 | 3室2厅2卫 | 中 | 14 | 暂无数据 | 简装 | XQ00130 | SH | ... | 0.0000 | 14823 | 148 | 157552 | 701.0 | 22.0 | 1 | 2018/12/16 | 2000.0 | train |
2 | 100307764 | 132.00 | 未知方式 | 3室2厅2卫 | 低 | 32 | 暂无数据 | 其他 | XQ00179 | SH | ... | 0.0000 | 77645 | 520 | 131744 | 57.0 | 20.0 | 1 | 2018/12/22 | 16000.0 | train |
3 | 100306518 | 57.00 | 未知方式 | 1室1厅1卫 | 中 | 17 | 暂无数据 | 精装 | XQ00313 | SH | ... | 3080.0331 | 8750 | 1665 | 253337 | 888.0 | 279.0 | 9 | 2018/12/21 | 1600.0 | train |
4 | 100305262 | 129.00 | 未知方式 | 3室2厅3卫 | 低 | 2 | 暂无数据 | 毛坯 | XQ01257 | SH | ... | 0.0000 | 800 | 117 | 125309 | 2038.0 | 480.0 | 0 | 2018/11/18 | 2900.0 | train |
5 rows × 52 columns
print(train_data.info()) #查看索引、数据类型和内存信息
print(train_data.describe()) #查看数据值列的汇总统计. 通过使用这个函数,我们可以知道数据集中数据的数量,平均值,最值等
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 41440 entries, 0 to 41439
Data columns (total 52 columns):
ID 41440 non-null int64
area 41440 non-null float64
rentType 41440 non-null object
houseType 41440 non-null object
houseFloor 41440 non-null object
totalFloor 41440 non-null int64
houseToward 41440 non-null object
houseDecoration 41440 non-null object
communityName 41440 non-null object
city 41440 non-null object
region 41440 non-null object
plate 41440 non-null object
buildYear 41440 non-null object
saleSecHouseNum 41440 non-null int64
subwayStationNum 41440 non-null int64
busStationNum 41440 non-null int64
interSchoolNum 41440 non-null int64
schoolNum 41440 non-null int64
privateSchoolNum 41440 non-null int64
hospitalNum 41440 non-null int64
drugStoreNum 41440 non-null int64
gymNum 41440 non-null int64
bankNum 41440 non-null int64
shopNum 41440 non-null int64
parkNum 41440 non-null int64
mallNum 41440 non-null int64
superMarketNum 41440 non-null int64
totalTradeMoney 41440 non-null int64
totalTradeArea 41440 non-null float64
tradeMeanPrice 41440 non-null float64
tradeSecNum 41440 non-null int64
totalNewTradeMoney 41440 non-null int64
totalNewTradeArea 41440 non-null int64
tradeNewMeanPrice 41440 non-null float64
tradeNewNum 41440 non-null int64
remainNewNum 41440 non-null int64
supplyNewNum 41440 non-null int64
supplyLandNum 41440 non-null int64
supplyLandArea 41440 non-null float64
tradeLandNum 41440 non-null int64
tradeLandArea 41440 non-null float64
landTotalPrice 41440 non-null int64
landMeanPrice 41440 non-null float64
totalWorkers 41440 non-null int64
newWorkers 41440 non-null int64
residentPopulation 41440 non-null int64
pv 41422 non-null float64
uv 41422 non-null float64
lookNum 41440 non-null int64
tradeTime 41440 non-null object
tradeMoney 41440 non-null float64
Type 41440 non-null object
dtypes: float64(10), int64(30), object(12)
memory usage: 16.4+ MB
None
ID area totalFloor saleSecHouseNum \
count 4.144000e+04 41440.000000 41440.000000 41440.000000
mean 1.001221e+08 70.959409 11.413152 1.338538
std 9.376566e+04 88.119569 7.375203 3.180349
min 1.000000e+08 1.000000 0.000000 0.000000
25% 1.000470e+08 42.607500 6.000000 0.000000
50% 1.000960e+08 65.000000 7.000000 0.000000
75% 1.001902e+08 90.000000 16.000000 1.000000
max 1.003218e+08 15055.000000 88.000000 52.000000
subwayStationNum busStationNum interSchoolNum schoolNum \
count 41440.000000 41440.000000 41440.000000 41440.000000
mean 5.741192 187.197153 1.506395 48.228813
std 4.604929 179.674625 1.687631 29.568448
min 0.000000 24.000000 0.000000 9.000000
25% 2.000000 74.000000 0.000000 24.000000
50% 5.000000 128.000000 1.000000 47.000000
75% 7.000000 258.000000 3.000000 61.000000
max 22.000000 824.000000 8.000000 142.000000
privateSchoolNum hospitalNum ... tradeLandArea landTotalPrice \
count 41440.000000 41440.000000 ... 41440.000000 4.144000e+04
mean 6.271911 4.308736 ... 12621.406425 1.045363e+08
std 4.946457 3.359714 ... 49853.120341 5.215216e+08
min 0.000000 0.000000 ... 0.000000 0.000000e+00
25% 2.000000 1.000000 ... 0.000000 0.000000e+00
50% 5.000000 4.000000 ... 0.000000 0.000000e+00
75% 9.000000 6.000000 ... 0.000000 0.000000e+00
max 24.000000 14.000000 ... 555508.010000 6.197570e+09
landMeanPrice totalWorkers newWorkers residentPopulation \
count 41440.000000 41440.000000 41440.000000 41440.000000
mean 724.763918 77250.235497 1137.132095 294514.059459
std 3224.303831 132052.508523 7667.381627 196745.147181
min 0.000000 600.000000 0.000000 49330.000000
25% 0.000000 13983.000000 0.000000 165293.000000
50% 0.000000 38947.000000 0.000000 245872.000000
75% 0.000000 76668.000000 0.000000 330610.000000
max 37513.062490 855400.000000 143700.000000 928198.000000
pv uv lookNum tradeMoney
count 41422.000000 41422.000000 41440.000000 4.144000e+04
mean 26945.663512 3089.077085 0.396260 8.837074e+03
std 32174.637924 2954.706517 1.653932 5.514287e+05
min 17.000000 6.000000 0.000000 0.000000e+00
25% 7928.000000 1053.000000 0.000000 2.800000e+03
50% 20196.000000 2375.000000 0.000000 4.000000e+03
75% 34485.000000 4233.000000 0.000000 5.500000e+03
max 621864.000000 39876.000000 37.000000 1.000000e+08
[8 rows x 40 columns]
数据结构分析
- 该数据集是41440行* 52列的数据,即有41440个用户数据和50个特征,1个目标变量,1个数据标志符
- 除了pv,uv为41422行之外,其他特征均为41440行,证明pv和uv有18个缺失值
- 数据类型包括float(10个),int(30个),object(12个)
- Object 数据类型可以指向任意数据类型的数据,由本数据可以看出,非纯数字的数据都是Object类型(如含中英文文本,字符等),我们之后要对这些数据进行处理。
- 本赛题是房价预测,因此我们的目标变量应为:tradeMoney
因为我们要对Object类型数据进行处理,所以我们要先把Object类型的和数字型的特征分别提取筛选出来
#根据数据结构表,可以划分出如下的数值型特征和类别型特征
categorical_feas = ['rentType', 'houseType', 'houseFloor', 'region', 'plate', 'houseToward', 'houseDecoration',
'communityName','city','region','plate','buigeldYear']
numerical_feas=['ID','area','totalFloor','saleSecHouseNum','subwayStationNum',
'busStationNum','interSchoolNum','schoolNum','privateSchoolNum','hospitalNum',
'drugStoreNum','gymNum','bankNum','shopNum','parkNum','mallNum','superMarketNum',
'totalTradeMoney','totalTradeArea','tradeMeanPrice','tradeSecNum','totalNewTradeMoney',
'totalNewTradeArea','tradeNewMeanPrice','tradeNewNum','remainNewNum','supplyNewNum',
'supplyLandNum','supplyLandArea','tradeLandNum','tradeLandArea','landTotalPrice',
'landMeanPrice','totalWorkers','newWorkers','residentPopulation','pv','uv','lookNum']
缺失值分析
#EDA那些操作,应该在测试集上也来一套的~这里偷懒了,所以这里是对data_all进行缺失值分析
def missing_vaule(df):
data_all_null=pd.DataFrame(df.isnull().sum(),columns={'missing_sum'})
data_all_null['exist_sum']=len(df)-data_all_null['missing_sum']
data_all_null['sum'] = len(df)
data_all_null['missingRatio'] = data_all_null['missing_sum']/len(df)*100
data_all_null['dtype'] = df.dtypes
#ascending:默认True升序排列;False降序排列
data_all_null = data_all_null[data_all_null['missing_sum']>0].reset_index().sort_values(by=['missing_sum','index'],ascending=[False,True])
#将有缺失的特征截取出来,根据缺失数大小重新排序,缺失值越大越排在前面(索引按0-9升序排列)
data_all_null.set_index('index',inplace=True) #设置复合索引
return data_all_null
missing_vaule(train_data)
missing_sum | exist_sum | sum | missingRatio | dtype | |
---|---|---|---|---|---|
index | |||||
pv | 18 | 41422 | 41440 | 0.043436 | float64 |
uv | 18 | 41422 | 41440 | 0.043436 | float64 |
分析
- 采用编写函数的方式来直接获取结果,以后常用,一定要学会自己写函数
- 结果是,仅有pv、uv存在缺失值,
- 其实在总体情况一览中,info()函数也能看出来。
6. 单调特征列分析
#是否有单调特征列(单调的特征列很大可能是时间)
#单增序列
def increasing(value):
cnt = 0
len_ = len(value)
for i in range(len_-1):
if value[i+1] > value[i]:
cnt += 1
return cnt
fea_cols=[col for col in train_data.columns] #第一个col是变量,第二个col相当于键
for col in fea_cols:
cnt = increasing(train_data[col].values) #计算单增特征个数
if cnt / train_data.shape[0] >= 0.55: #设置大于0.5小于1的阈值即可保证全局单调而不是局部单调
print('单调特征:',col)
print('单调特征值个数:', cnt)
print('单调特征值比例:', cnt / train_data.shape[0])
单调特征: tradeTime
单调特征值个数: 24085
单调特征值比例: 0.5812017374517374
分析
- 先写一个简单的循坏语句来做单调的函数,参考C++的写法。然后再应用到每列上。
- 单调特征列一般为时间,而且对于时序问题,时间越近的数据则参考价值越大,所赋的权重也应该越大。
- 多说句额外的,时间列在特征工程的时候,不同的情况下能有很多的变种形式,比如按年月日分,或者按不同的维度在时间上聚合分组,等等
7.特征分布
# 特征nunique分布
for feature in categorical_feas:
print(feature + "的特征分布如下:")
print(train_data[feature].value_counts())
if feature != 'communityName': # communityName不同值太多,暂且不看图表
plt.hist(data_all[feature], bins=3)
plt.show()
print(train_data['communityName'].value_counts())
print(train_data['communityName'].value_counts())
简要分析
用自带函数value_counts() 来得到每个分类变量的 种类 分布;
并且简单画出柱状图。
rentType:4种,且绝大多数是无用的未知方式;
houseType:104种,绝大多数在3室及以下;
houseFloor:3种,分布较为均匀;
region: 15种;
plate: 66种;
houseToward: 10种;
houseDecoration: 4种,一大半是其他;
buildYear: 80种;
communityName: 4236种,且分布较为稀疏;
此步骤是为之后数据处理和特征工程做准备,先理解每个字段的含义以及分布,之后需要根据实际含义对分类变量做不同的处理。
未完待续##