供自己与新手学习!资源来自网络。
本文用到的数据集:
请点击 提取码:wyez
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import os
get_ipython().magic('matplotlib inline')
snd = pd.read_csv(r'.\data\sndHsPr.csv')
snd.head()
| dist | roomnum | halls | AREA | floor | subway | school | price |
---|
0 | chaoyang | 1 | 0 | 46.06 | middle | 1 | 0 | 48850 |
---|
1 | chaoyang | 1 | 1 | 59.09 | middle | 1 | 0 | 46540 |
---|
2 | haidian | 5 | 2 | 278.95 | high | 1 | 1 | 71662 |
---|
3 | haidian | 3 | 2 | 207.00 | high | 1 | 1 | 57972 |
---|
4 | fengtai | 2 | 1 | 53.32 | low | 1 | 1 | 71268 |
---|
数据预处理
1、根据单价和面积计算房屋价格(价格=单价×面积)
snd["all_pr2"]=snd[["price","AREA"]].apply(lambda x:x[0]*x[1], axis = 1 )
snd.head()
| dist | roomnum | halls | AREA | floor | subway | school | price | all_pr2 |
---|
0 | chaoyang | 1 | 0 | 46.06 | middle | 1 | 0 | 48850 | 2250031.00 |
---|
1 | chaoyang | 1 | 1 | 59.09 | middle | 1 | 0 | 46540 | 2750048.60 |
---|
2 | haidian | 5 | 2 | 278.95 | high | 1 | 1 | 71662 | 19990114.90 |
---|
3 | haidian | 3 | 2 | 207.00 | high | 1 | 1 | 57972 | 12000204.00 |
---|
4 | fengtai | 2 | 1 | 53.32 | low | 1 | 1 | 71268 | 3800009.76 |
---|
2、dist变量重新编码为中文,比如chaoyang改为朝阳区
1、把dist变量重新编码为中文,比如chaoyang改为朝阳区。1)先作频次统计,然后绘制柱形图图展现每个区样本的数量;
district = {'fengtai':'丰台区','haidian':'海淀区','chaoyang':'朝阳区','dongcheng':'东城区','xicheng':'西城区','shijingshan':'石景山区'}
snd['district'] = snd.dist.map(district)
snd.head()
| dist | roomnum | halls | AREA | floor | subway | school | price | all_pr2 | district |
---|
0 | chaoyang | 1 | 0 | 46.06 | middle | 1 | 0 | 48850 | 2250031.00 | 朝阳区 |
---|
1 | chaoyang | 1 | 1 | 59.09 | middle | 1 | 0 | 46540 | 2750048.60 | 朝阳区 |
---|
2 | haidian | 5 | 2 | 278.95 | high | 1 | 1 | 71662 | 19990114.90 | 海淀区 |
---|
3 | haidian | 3 | 2 | 207.00 | high | 1 | 1 | 57972 | 12000204.00 | 海淀区 |
---|
4 | fengtai | 2 | 1 | 53.32 | low | 1 | 1 | 71268 | 3800009.76 | 丰台区 |
---|
3、单因子频数:描述名义变量的分布
3.1统计名义变量的频数
snd.district.value_counts()
丰台区 2947
海淀区 2919
朝阳区 2864
东城区 2783
西城区 2750
石景山区 1947
Name: district, dtype: int64
3.2地区分布条形图与饼状图
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
snd.district.value_counts().plot(kind = 'pie')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2c7630f09240867e8311b9150d45e62a.png#pic_center)
4、单变量描述:描述连续变量的分布
4.1 平均值、中位数、标准差、倾斜
snd.price.mean()
snd.price.median()
snd.price.std()
snd.price.skew()
0.6794935869486859
4.2 聚合函数:agg同时统计多个统计量:平均值、中位数、标准差、倾斜
snd.price.agg(['mean','median','sum','std','skew'])
mean 6.115181e+04
median 5.747300e+04
sum 9.912709e+08
std 2.229336e+04
skew 6.794936e-01
Name: price, dtype: float64
4.3 数据清洗函数quantile统计在1%、50%、99%的数据
snd.price.quantile([0.01,0.5,0.99])
0.01 27104.45
0.50 57473.00
0.99 119996.85
Name: price, dtype: float64
4.4绘制直方图(连续变量)
snd.price.hist(bins=40)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1c172a66aae168fbd65892fcf6e6c033.png#pic_center)
描述统计方法大全
1.1 crosstab函数(行,列)
sub_sch = pd.crosstab(snd.district,snd.school)
sub_sch
school | 0 | 1 |
---|
district | | |
---|
东城区 | 1508 | 1275 |
---|
丰台区 | 2853 | 94 |
---|
朝阳区 | 2267 | 597 |
---|
海淀区 | 1533 | 1386 |
---|
石景山区 | 1929 | 18 |
---|
西城区 | 1207 | 1543 |
---|
1.2分类柱形图
pd.crosstab(snd.dist,snd.subway).plot(kind="bar")
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/75322d78075822288c6580a7aa6d2f9b.png#pic_center)
1.3 普通堆叠柱形图
t1=pd.crosstab(snd.district,snd.school)
t1.plot(kind = 'bar',stacked= True)
type(t1)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/49bec7a7787262c9d3035c7531dfb3db.png#pic_center)
1.4 标准化的堆叠柱形图
列的汇总
sub_sch = pd.crosstab(snd.district,snd.school)
sub_sch["sum1"]=sub_sch.sum(1)
sub_sch.head()
school | 0 | 1 | sum1 |
---|
district | | | |
---|
东城区 | 1508 | 1275 | 2783 |
---|
丰台区 | 2853 | 94 | 2947 |
---|
朝阳区 | 2267 | 597 | 2864 |
---|
海淀区 | 1533 | 1386 | 2919 |
---|
石景山区 | 1929 | 18 | 1947 |
---|
按行求百分比
sub_sch = sub_sch.div(sub_sch.sum1,axis = 0)
sub_sch
school | 0 | 1 | sum1 |
---|
district | | | |
---|
东城区 | 0.541861 | 0.458139 | 1.0 |
---|
丰台区 | 0.968103 | 0.031897 | 1.0 |
---|
朝阳区 | 0.791550 | 0.208450 | 1.0 |
---|
海淀区 | 0.525180 | 0.474820 | 1.0 |
---|
石景山区 | 0.990755 | 0.009245 | 1.0 |
---|
西城区 | 0.438909 | 0.561091 | 1.0 |
---|
sub_sch[[0,1]].plot(kind = 'bar',stacked= True)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ce041bc4a5c3e6deba9f75c63fbfa599.png#pic_center)
1.5 堆叠柱形图函数stack2dim
from stack2dim import *
stack2dim(snd, i="district", j="school")
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/557491bf04c5fe4e476f02a3519aa542.png)
1.6 地图绘制
from pyecharts import options as opts
from pyecharts.charts import Map, Page
from pyecharts.faker import Collector, Faker
C = Collector()
"""
官网给的解释如下:
自从 0.3.2 开始,为了缩减项目本身的体积以及维持 pyecharts 项目的轻量化运行,pyecharts 将不再自带地图 js 文件。如用户需要用到地图图表,可自行安装对应的地图文件包。下面介绍如何安装。
全球国家地图: echarts-countries-pypkg (1.9MB): 世界地图和 213 个国家,包括中国地图
中国省级地图: echarts-china-provinces-pypkg (730KB):23 个省,5 个自治区
中国市级地图: echarts-china-cities-pypkg (3.8MB):370 个中国城市:https://github.com/echarts-maps/echarts-china-cities-js
pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg
别注明,中国地图在 echarts-countries-pypkg 里。
"""
snd_price = list(zip(snd.price.groupby(snd.district).mean().index,
snd.price.groupby(snd.district).mean().values))
min_ = snd.price.groupby(snd.dist).mean().min()
max_ = snd.price.groupby(snd.dist).mean().max()
@C.funcs
def map_visualmap() -> Map:
c = (
Map()
.add("北京各区房价", [list(z) for z in zip(list(snd.price.groupby(snd.district).mean().index), list(snd.price.groupby(snd.district).mean().values))], "北京")
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-VisualMap(连续型)"),
visualmap_opts=opts.VisualMapOpts(max_=max_,min_=min_),
)
)
return c
Page().add(*[fn() for fn, _ in C.charts]).render()
'J:\\myGitHub\\Machine_Learning\\练习\\数据科学\\render.html'
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0ebf02d7b09da25f016fba82b0d813a8.png#pic_center)
1.7 条形图
snd.price.groupby(snd.district).mean().plot(kind="bar")
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/16bbe803636b0093e44d30e6811654a4.png#pic_center)
1.8 条形图排序
snd.price.groupby(snd.district).mean().sort_values(ascending= True).plot(kind = 'barh')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0d8dad3e8d723e2cbee7ecd9bf50ce84.png#pic_center)
1.9 盒须图
sns.boxplot(x = 'district', y = 'price', data = snd)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/39bcb6143533678be4ca9f90358ec6c5.png#pic_center)
1.10 汇总表
snd.pivot_table(values='price', index='district', columns='school', aggfunc=np.mean)
school | 0 | 1 |
---|
district | | |
---|
东城区 | 66276.887931 | 78514.900392 |
---|
丰台区 | 42291.003505 | 48871.617021 |
---|
朝阳区 | 51588.511689 | 57403.405360 |
---|
海淀区 | 61385.803653 | 76911.258297 |
---|
石景山区 | 40353.883878 | 33107.333333 |
---|
西城区 | 76989.369511 | 92468.873623 |
---|
snd.pivot_table(values='price', index='district', columns='school', aggfunc=np.mean).plot(kind = 'bar')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1be75fd7bdfb9b5e6a2a587cd0d9db88.png#pic_center)
1.11 散点图(两个连续变量)
- 使用area和price做散点图,分析area是否影响单位面积房价
snd.plot.scatter(x = 'AREA', y = 'price')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9114a091a71ddf2ecd5afbe481d315d7.png#pic_center)
1.12 双轴图
- 按年度汇总GDP,并计算GDP增长率。绘制双轴图。GDP为柱子,GDP增长率为线。
gdp = pd.read_csv('.\data\gdp_gdpcr.csv',encoding = 'gbk')
gdp.head()
| year | GDP | GDPCR |
---|
0 | 2000 | 100280.1 | 8.5 |
---|
1 | 2001 | 110863.1 | 8.3 |
---|
2 | 2002 | 121717.4 | 9.1 |
---|
3 | 2003 | 137422.0 | 10.0 |
---|
4 | 2004 | 161840.2 | 10.1 |
---|
x = list(gdp.year)
GDP = list(gdp.GDP)
GDPCR = list(gdp.GDPCR)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.bar(x,GDP)
ax1.set_ylabel('GDP')
ax1.set_title("GDP of China(2000-2017)")
ax1.set_xlim(2000,2017)
ax2 = ax1.twinx()
ax2.plot(x,GDPCR,'r')
ax2.set_ylabel('Increase Ratio')
ax2.set_xlabel('Year')
Text(0.5, 0, 'Year')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d7d1237ccf52517da4b6de4f28ce2a29.png#pic_center)
1.13 logit图
- 对age按照5岁间隔分段,命名为age_group,用loss_flag对age_group作logit图。
auto = pd.read_csv(r'.\data\auto_ins.csv',encoding = 'gbk')
auto
| EngSize | Age | Gender | Marital | exp | Owner | vAge | Garage | AntiTFD | import | Loss |
---|
0 | 2.0 | 56 | 男 | 已婚 | 20 | 公司 | 10 | 有 | 有防盗装置 | 进口 | 0.0 |
---|
1 | 1.8 | 41 | 男 | 已婚 | 20 | 公司 | 9 | 有 | 无防盗装置 | 国产 | 0.0 |
---|
2 | 2.0 | 44 | 男 | 未婚 | 20 | 公司 | 8 | 有 | 有防盗装置 | 国产 | 0.0 |
---|
3 | 1.6 | 56 | 男 | 已婚 | 20 | 公司 | 7 | 有 | 有防盗装置 | 国产 | 0.0 |
---|
4 | 1.8 | 45 | 男 | 已婚 | 20 | 公司 | 7 | 无 | 无防盗装置 | 国产 | 0.0 |
---|
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
---|
4228 | 1.8 | 22 | 女 | 未婚 | 0 | 私人 | 1 | 有 | 有防盗装置 | 国产 | 976.0 |
---|
4229 | 2.5 | 22 | 男 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 进口 | 855.6 |
---|
4230 | 1.8 | 21 | 男 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 国产 | 0.0 |
---|
4231 | 1.8 | 21 | 女 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 进口 | 3328.0 |
---|
4232 | 2.4 | 21 | 女 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 进口 | 1564.0 |
---|
4233 rows × 11 columns
auto.Loss = auto.Loss.map(lambda x: 1 if x >0 else 0)
auto
| EngSize | Age | Gender | Marital | exp | Owner | vAge | Garage | AntiTFD | import | Loss |
---|
0 | 2.0 | 56 | 男 | 已婚 | 20 | 公司 | 10 | 有 | 有防盗装置 | 进口 | 0 |
---|
1 | 1.8 | 41 | 男 | 已婚 | 20 | 公司 | 9 | 有 | 无防盗装置 | 国产 | 0 |
---|
2 | 2.0 | 44 | 男 | 未婚 | 20 | 公司 | 8 | 有 | 有防盗装置 | 国产 | 0 |
---|
3 | 1.6 | 56 | 男 | 已婚 | 20 | 公司 | 7 | 有 | 有防盗装置 | 国产 | 0 |
---|
4 | 1.8 | 45 | 男 | 已婚 | 20 | 公司 | 7 | 无 | 无防盗装置 | 国产 | 0 |
---|
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
---|
4228 | 1.8 | 22 | 女 | 未婚 | 0 | 私人 | 1 | 有 | 有防盗装置 | 国产 | 1 |
---|
4229 | 2.5 | 22 | 男 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 进口 | 1 |
---|
4230 | 1.8 | 21 | 男 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 国产 | 0 |
---|
4231 | 1.8 | 21 | 女 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 进口 | 1 |
---|
4232 | 2.4 | 21 | 女 | 未婚 | 0 | 私人 | 1 | 有 | 无防盗装置 | 进口 | 1 |
---|
4233 rows × 11 columns
bins = [21,26,31,36,41,46,51,56,61,67]
labels = [1,2,3,4,5,6,7,8,9]
auto['age_group'] = pd.cut(auto.Age, bins, labels = labels, right =False)
auto.head()
| EngSize | Age | Gender | Marital | exp | Owner | vAge | Garage | AntiTFD | import | Loss | age_group |
---|
0 | 2.0 | 56 | 男 | 已婚 | 20 | 公司 | 10 | 有 | 有防盗装置 | 进口 | 0 | 8 |
---|
1 | 1.8 | 41 | 男 | 已婚 | 20 | 公司 | 9 | 有 | 无防盗装置 | 国产 | 0 | 5 |
---|
2 | 2.0 | 44 | 男 | 未婚 | 20 | 公司 | 8 | 有 | 有防盗装置 | 国产 | 0 | 5 |
---|
3 | 1.6 | 56 | 男 | 已婚 | 20 | 公司 | 7 | 有 | 有防盗装置 | 国产 | 0 | 8 |
---|
4 | 1.8 | 45 | 男 | 已婚 | 20 | 公司 | 7 | 无 | 无防盗装置 | 国产 | 0 | 5 |
---|
log_tab = pd.crosstab(auto.age_group,auto.Loss)
log_tab
Loss | 0 | 1 |
---|
age_group | | |
---|
1 | 87 | 49 |
---|
2 | 308 | 135 |
---|
3 | 743 | 292 |
---|
4 | 826 | 329 |
---|
5 | 578 | 206 |
---|
6 | 324 | 129 |
---|
7 | 112 | 41 |
---|
8 | 42 | 16 |
---|
9 | 8 | 8 |
---|
log_tab[['p0','p1']] = log_tab[[0,1]].apply(lambda x: x/sum(x))
log_tab['log'] = log_tab[['p1','p0']].apply(lambda x: np.log(x[0]/x[-1]),axis = 1)
log_tab
Loss | 0 | 1 | p0 | p1 | log |
---|
age_group | | | | | |
---|
1 | 87 | 49 | 0.028732 | 0.040664 | 0.347335 |
---|
2 | 308 | 135 | 0.101717 | 0.112033 | 0.096598 |
---|
3 | 743 | 292 | 0.245376 | 0.242324 | -0.012519 |
---|
4 | 826 | 329 | 0.272787 | 0.273029 | 0.000886 |
---|
5 | 578 | 206 | 0.190885 | 0.170954 | -0.110275 |
---|
6 | 324 | 129 | 0.107001 | 0.107054 | 0.000492 |
---|
7 | 112 | 41 | 0.036988 | 0.034025 | -0.083504 |
---|
8 | 42 | 16 | 0.013871 | 0.013278 | -0.043658 |
---|
9 | 8 | 8 | 0.002642 | 0.006639 | 0.921423 |
---|
可以看出上面计算的是什么
log_tab.p0.sum(),log_tab.p1.sum(),np.log(log_tab.p1/log_tab.p0)
(0.9999999999999999, 1.0, age_group
1 0.347335
2 0.096598
3 -0.012519
4 0.000886
5 -0.110275
6 0.000492
7 -0.083504
8 -0.043658
9 0.921423
dtype: float64)
log_tab.log.plot()
from woe import WoE
woe = WoE(v_type='d')
woe.fit(auto.age_group,auto.Loss)
fig = woe.plot([8,5])
plt.show(fig)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/da95ff1d2bba2eb6ff816f154aac913c.png#pic_center)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/85acbb2da46e0e4123f9c4ad54309ce8.png#pic_center)