fish千聊课重新研读03

作者: Bog5d | 来源:发表于2017-09-22 19:22 被阅读14次

    本课主要是统计学常识。 很多概念都值得背诵下来。

    描述统计量

    • 集中趋势
      • 均值
      • 中位数
      • 众数
    • 离散程度
      • 全距
      • 四分位距
      • 方差、标准差
    • 两个变量的关系
      • 协方差
      • 相关系数
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    %matplotlib inline
    %config InlineBackend.figure_format = 'retina'
    
    df = pd.read_csv('HRSalaries.csv')
    df.head()
    
    len(df)
    
    
    30284
    
    • 一共有30284行信息
    我觉得列名称太麻烦了,还是把列名改简单点吧
    df.columns=['id','p_ti','dep','an_s','re_s']
    df.head()
    
    
    
    • 这是我尝试使用上节课的技巧 --修改列名
    df.dep.value_counts()
    
    • 打这行代码时,犯了很多错误。
    • 错误记录1:value_counts是有下面横杠的,我没有写。

    • 个人理解:value_counts方法相当于分类统计。把同一类的汇总起来,数一下有多少个。 只是groupby,是把分类成一堆,后面再接一个函数执行不同的运算。
      value_counts方法就像你家里养了鸡鸭鹅三种动物,它们住在一起的。 老大去把鸡赶到一堆,鸭赶到一堆,鹅赶到一堆,然后分别数了一下,得出结论鸡5只,鸭6只,鹅3只。这就是value_counts,或者groupby()size()方法
      但老二,不会数数,就只是把鸡鸭鹅赶到不同的堆数里了(groupby);然后再叫妈妈来称重,妈妈称好重后,算了一下平均每只鸡重2斤,鸭重3斤,鹅6斤,这就是groupby()mean()方法

    POLICE                   12461
    FIRE                      4798
    SANITATION                2092
    WATER MGMT                1796
    AVIATION                  1252
    TRANSPORTATION            1196
    EMERGENCY MGMT            1182
    GENERAL SERVICES           922
    PUBLIC LIBRARY             874
    FAMILY & SUPPORT           719
    HEALTH                     568
    FINANCE                    533
    LAW                        455
    CITY COUNCIL               265
    BUILDINGS                  261
    COMMUNITY DEVELOPMENT      216
    BUSINESS AFFAIRS           177
    DoIT                        97
    MAYOR'S OFFICE              96
    PROCUREMENT                 77
    CULTURAL AFFAIRS            76
    HUMAN RESOURCES             61
    ANIMAL CONTRL               57
    DISABILITIES                29
    TREASURER                   24
    Name: dep, dtype: int64
    
    df.groupby('dep').size()
    

    此方法与value_counts()等效。

    dep
    ANIMAL CONTRL               57
    AVIATION                  1252
    BUILDINGS                  261
    BUSINESS AFFAIRS           177
    CITY COUNCIL               265
    COMMUNITY DEVELOPMENT      216
    CULTURAL AFFAIRS            76
    DISABILITIES                29
    DoIT                        97
    EMERGENCY MGMT            1182
    FAMILY & SUPPORT           719
    FINANCE                    533
    FIRE                      4798
    GENERAL SERVICES           922
    HEALTH                     568
    HUMAN RESOURCES             61
    LAW                        455
    MAYOR'S OFFICE              96
    POLICE                   12461
    PROCUREMENT                 77
    PUBLIC LIBRARY             874
    SANITATION                2092
    TRANSPORTATION            1196
    TREASURER                   24
    WATER MGMT                1796
    dtype: int64
    
    len(df.dep.unique())
    
    
    • 新知识点: .unique(). 这个方法的意思是找到列表的唯一值。
    • 相当于是把dep的部门名称做成列表,再用len来计算列表长度
    25
    

    集中趋势

    均值

    算数平均值

    $$ \frac{\sum_i x_i}{N}$$

    salary = df.an_s
    salary.head()
    df.head()
    
    salary.head()
    
    0    16140
    1    71506
    2    61085
    3    81928
    4    50379
    Name: an_s, dtype: int64
    
    salary.sum()/len(salary)
    ## 求得工资金额,然后除以领工资人数。当然这是笨办法
    
    60836.98560295866
    
    np.mean(salary)
    ## 这是np的算法
    
    60836.98560295866
    
    salary.mean()
    
    
    60836.98560295866
    
    df.groupby('dep').an_s.mean().sort_values(ascending=False)
    

    尝试默写这段代码时,也是状况百出。

    • 错误记录: 1.sort_values()升降序的那个直接在括号中就是了,而我是sort_values()(ascending=False),用了两个括号。其实排序那个本来就是sort方法的参数
    • 错误记录2.拼写错误ascending ,我拼写为asending,少了个c
    • 个人理解:ascending这个,跟sql的语言类似
    • 个人理解:先把dep分组,再然后计算不同组中的平均值。 这也跟sql里面的语言逻辑很相似,就是sql中两个排序依据的时候 。比如价格和名字,价格相同时,按顺序排列名字
    dep
    DoIT                     73831.979381
    BUILDINGS                72137.885057
    FIRE                     69383.989996
    MAYOR'S OFFICE           68953.677083
    WATER MGMT               64760.186526
    COMMUNITY DEVELOPMENT    64262.597222
    GENERAL SERVICES         63747.808026
    TREASURER                63497.500000
    POLICE                   63127.904984
    TRANSPORTATION           62947.504181
    PROCUREMENT              61452.584416
    HEALTH                   61213.503521
    CULTURAL AFFAIRS         61181.894737
    DISABILITIES             58058.586207
    BUSINESS AFFAIRS         57216.067797
    HUMAN RESOURCES          57108.163934
    LAW                      55917.958242
    AVIATION                 55816.200479
    SANITATION               55555.813576
    FINANCE                  54286.375235
    ANIMAL CONTRL            47604.473684
    PUBLIC LIBRARY           44241.731121
    EMERGENCY MGMT           42845.754653
    CITY COUNCIL             38046.547170
    FAMILY & SUPPORT         31193.307371
    Name: an_s, dtype: float64
    

    中位数

    len(salary)
    #计算一共有多少个人领工资
    
    30284
    
    sa_s = salary.sort_values()
    sa_s.head()
    
    16629    3128
    2247     3132
    20961    3133
    13423    3135
    25422    3135
    Name: an_s, dtype: int64
    
    (sa_s.iloc[15142]+sa_s.iloc[15141])/2
    中值
    
    61836.0
    
    salary.median()
    
    61836.0
    
    np.median(salary)
    
    61836.0
    
    plt.hist(salary,bins=30,rwidth=0.5)
    plt.show()
    
    output_21_0.png
    np.mean(salary)>np.median(salary)
    
    

    均值是否大于中值呢 结论为否,那么就是均值小于中值,那么就是往左偏的

    False
    

    救火人员收入分布

    f_s = df[df.dep=='FIRE'].an_s
    
    plt.hist(f_s,bins=30,rwidth=0.6)
    plt.show()
    

    我的命名都是简写,正式场合还是不能这样么用,不然只有我自己看得懂

    output_24_0.png
    f_s.median()
    
    66260.0
    
    f_s.mean()
    
    69383.9899958316
    
    f_s.median()<f_s.mean()
    
    True
    

    均值大于中值,所以图形偏右

    离散程度

    全距 range

    salary.max()-salary.min()
    笨办法算全距
    
    198320
    
    salary.range()
    
    

    这是一次错误尝试,看看有没有直接算全距的方法,看来没有。

    ---------------------------------------------------------------------------
    
    AttributeError                            Traceback (most recent call last)
    
    <ipython-input-54-1a6fc05747b6> in <module>()
    ----> 1 salary.range()
    
    
    F:\Program Files\conda\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
       2670             if name in self._info_axis:
       2671                 return self[name]
    -> 2672             return object.__getattribute__(self, name)
       2673 
       2674     def __setattr__(self, name, value):
    
    
    AttributeError: 'Series' object has no attribute 'range'
    

    四分位距

    Q1 = salary.quantile(0.25)
    Q1
    
    
    • 错误记录:拼写错误,quantile被我拼写为quartile了
    55671.75
    
    Q3 = salary.quantile(0.75)
    Q3
    
    68558.5
    
    IQR=Q3-Q1
    IQR
    
    12886.75
    
    salary.quantile(0.5) - salary.median()
    
    

    中位数就是0.5分位数

    0.0
    
    salary.plot(kind='box',vert=False,figsize=(6,3))
    
    

    个人理解:这种作图的思路是先把数据摆出来,再说是画图。 相当于是我有这一堆棉花,再说做成棉被;
    但还有中思路,先说我要做棉被,你把棉花拿出来呢,比如plt.plot(salary)

    <matplotlib.axes._subplots.AxesSubplot at 0x23883b030b8>
    
    output_37_1.png
    plt.boxplot(salary)
    
    {'boxes': [<matplotlib.lines.Line2D at 0x23883bd7748>],
     'caps': [<matplotlib.lines.Line2D at 0x23883bddac8>,
      <matplotlib.lines.Line2D at 0x23883be39b0>],
     'fliers': [<matplotlib.lines.Line2D at 0x23883be8a20>],
     'means': [],
     'medians': [<matplotlib.lines.Line2D at 0x23883be3b38>],
     'whiskers': [<matplotlib.lines.Line2D at 0x23883bd7978>,
      <matplotlib.lines.Line2D at 0x23883bdd940>]}
    
    output_38_1.png

    IT从业人员工资

    it_s =df[df.dep=='DoIT'].an_s.tolist()
    
    
    

    什么意思呢,是一个列表吗?

    • 新增知识点,列表化。 把这些数字转化为列表格式
    • 错误记录:拼写错误DoIT,我写成了DOIT。 全大写了
    plt.boxplot(it_s)
    
    
    
    疑问:这段如果不列表化,就读不出数据,这是为什么呢?
    {'boxes': [<matplotlib.lines.Line2D at 0x23884b272b0>],
     'caps': [<matplotlib.lines.Line2D at 0x23884b2cd30>,
      <matplotlib.lines.Line2D at 0x23884b2ceb8>],
     'fliers': [<matplotlib.lines.Line2D at 0x23884a8c940>],
     'means': [],
     'medians': [<matplotlib.lines.Line2D at 0x23884a8c358>],
     'whiskers': [<matplotlib.lines.Line2D at 0x23884b27cc0>,
      <matplotlib.lines.Line2D at 0x23884b27e48>]}
    
    output_41_1.png

    建筑行业和it行业的收入比较
    还以同时画两类图

    bld_s =df[df.dep=='BUILDINGS'].an_s
    bld_s.head()
    
    158    60255
    395    75517
    523    60633
    608    66145
    884    68463
    Name: an_s, dtype: int64
    
    plt.boxplot([it_s,bld_s],labels=["IT","BUILDING"])
    
    
    {'boxes': [<matplotlib.lines.Line2D at 0x23884ba1588>,
      <matplotlib.lines.Line2D at 0x23884e439b0>],
     'caps': [<matplotlib.lines.Line2D at 0x23884ba7ef0>,
      <matplotlib.lines.Line2D at 0x23884baf860>,
      <matplotlib.lines.Line2D at 0x23884e4f978>,
      <matplotlib.lines.Line2D at 0x23884e4fb00>],
     'fliers': [<matplotlib.lines.Line2D at 0x23884e438d0>,
      <matplotlib.lines.Line2D at 0x23884e54b70>],
     'means': [],
     'medians': [<matplotlib.lines.Line2D at 0x23884baf9e8>,
      <matplotlib.lines.Line2D at 0x23884e54358>],
     'whiskers': [<matplotlib.lines.Line2D at 0x23884ba1f98>,
      <matplotlib.lines.Line2D at 0x23884ba77f0>,
      <matplotlib.lines.Line2D at 0x23884e48908>,
      <matplotlib.lines.Line2D at 0x23884e48a90>]}
    
    output_44_1.png

    错误记录:

    • 1.参数data部分应用【】括起来,因为这只是一个参数位置,如果用逗号分隔,会把第二个data放在另外一个参数位置上。
    • 2.labels 参数应该放在括号内
      1. labels=["IT","BUILDING"]我也没有加方括号。,可是区分参数位置很重要的符号,不能乱用

    所有部门雇员收入的box图

    • 哈哈放大招啦,我喜欢这个
    import seaborn as sns
    sns.boxplot(data=df,x='dep',y='an_s')
    plt.show()
    
    ## 意外发现用cmd安装真的好方便啊
    # 不过太拥挤了,能不能设置大一点啊
    
    

    我之前没有安装seaborn包。然后在cmd命令框里,输入conda install seaborn 发现太好用啦

    疑惑:seaborn如何设置图形的大小呢?

    output_47_0.png
    mean = salary.mean()
    var =np.sum((salary-mean)**2)/(len(salary)-1)
    var
    
    
    • 错误记录:sum((salary-mean)**2) 没有加外层括号,使得运算顺序出错。 可能是先相加,再平方去了。
    271490393.4177519
    
    std =np.sqrt(var)
    std
    
    
    • 错误记录:sqrt()不能直接用,是numpy的,所以要加上np。即np.sqrt(data)
    16476.965540346071
    
    #接下来是简单方法s
    np.var(salary)
    
    271481428.6048666
    
    salary.var()
    
    271490393.4177519
    
    salary.std()
    
    
    16476.96554034607
    
    mean = salary.mean()
    np.sum((salary - mean)**2) / (len(salary) - 1)
     
    
    271490393.4177519
    

    我发现两种算法的方差和标准差,是有误差的。

    验证拇指规则

    拇指规则是指68%集中在均值周围正负一个标准差的区间

    • 大约有68% 的数据处在离均值一个标准差的范围内,
    • 大约有95% 的数据处在离均值两个标准差的范围内。
    len(salary[salary.between(mean - std, mean + std)])/len(salary)
    
    
    
    • 错误记录
    1. between前面面要加点
    2. 方括号用错啦,应该是内部那个方括号应该是圆括号
    0.7666094307224938
    
    len(salary[salary.between(mean - 2*std, mean + 2*std)])/len(salary)
    
    0.933364152687888
    

    还真差不多呢。

    两个变量的关系

    协方差

    $$ cov(x,y) = \frac{\sum(x_i - \bar{x})(y_i - \bar{y})}{N-1} $$

    df.head()
    
    score = df.re_s
    score.tail()
    
    
    30279    4.8
    30280    4.9
    30281    6.2
    30282    6.7
    30283    5.5
    Name: re_s, dtype: float64
    
    mean_s=np.mean(score)
    np.sum((salary-mean)*(score-mean_s))/len(score)
     
    
    • *总觉得这个思路和余玄定理很像。 就是用于计算新闻分类的余玄定理
    7.747344090350171
    

    以上求出来的是协方差。 是标准差的晋级版。 标准差是一个变量和均值之间的关系;协方差是两个变量之间的关系,不对呀,是两个变量和均值的关系,还是两个变量之间的关系呢?

    cov = np.cov(salary,score)[0,1]
    cov
    
    7.7475999218100222
    

    相关系数

    $$ \rho = \frac{cov(x,y)}{\sigma_x \sigma_y} $$

    • 其实就是用协方差除以标准差
    corrcoef =cov/(np.std(salary)*np.std(score))
    corrcoef
    
    0.00045634837652977272
    
    np.corrcoef(salary,score)[0,1]
    
    0.00045633330757003586
    

    结果有点小误差。

    plt.scatter(salary,score,alpha=0.5)
    plt.show()
    
    output_69_0.png
    position = df[df.p_ti == 'FIREFIGHTER']
    print(np.corrcoef(position.an_s, position.re_s)[1,0])
    plt.scatter(position.an_s, position.re_s)
    plt.show()
    
    0.0571267765462
    
    output_70_1.png
    df.head()
    

    第三课作业

    1、计算 HRSalaries 数据中评分Review_Score 的均值和中位数,并判断其偏度是左偏还是右偏?

    print(df.re_s.mean())
    print(df.re_s.median())
    df.re_s.median()<df.re_s.mean()
    plt.hist(df.re_s)
    
    6.4558908994849205
    6.5
    
    
    
    
    
    (array([   25.,   101.,   560.,  2480.,  5199.,  8858.,  7821.,  4088.,
             1140.,    12.]),
     array([ 2.  ,  2.78,  3.56,  4.34,  5.12,  5.9 ,  6.68,  7.46,  8.24,
             9.02,  9.8 ]),
     <a list of 10 Patch objects>)
    
    output_73_2.png

    均值小于中值,是往左偏的

    • 2、 Review_Score 的IQR是多少?并绘制该数据的box图。
    print("Review_ScoreIQR:",df.re_s.quantile(0.75)-df.re_s.quantile(0.25))
    
    
    Review_ScoreIQR: 1.4
    
    df.re_s.plot(kind="box",vert=False,figsize=(9,6))
    
    
    <matplotlib.axes._subplots.AxesSubplot at 0x23883c2e780>
    
    output_76_1.png
    plt.boxplot(df.re_s)
    
    {'boxes': [<matplotlib.lines.Line2D at 0x2388914f048>],
     'caps': [<matplotlib.lines.Line2D at 0x2388914aa20>,
      <matplotlib.lines.Line2D at 0x2388914aba8>],
     'fliers': [<matplotlib.lines.Line2D at 0x2388914dc18>],
     'means': [],
     'medians': [<matplotlib.lines.Line2D at 0x2388914d400>],
     'whiskers': [<matplotlib.lines.Line2D at 0x238891639b0>,
      <matplotlib.lines.Line2D at 0x23889163b38>]}
    
    output_77_1.png
    sns.boxplot(data=df.re_s)
    
    <matplotlib.axes._subplots.AxesSubplot at 0x2388fcb31d0>
    
    output_78_1.png

    3、Review_Score的标准差是多少?

    score.var()
    
    1.0617336150160495
    

    4、在Review_Score中,求落在两个标准差内的数据占总数的百分比。

    mean_rs = score.mean()
    var_rs=score.var()
    
    
    #len(np.between[mean_rs-var_rs,mean_rs+var_rs])/len(score)
    #错误记录:本应该是data.between,但我写成了np.between
    len(score[score.between(mean_rs-var_rs,mean_rs+var_rs)])/len(score)
    
    0.7091203275657113
    

    5、对于 DoIT 部门,计算其收入和评分的相关系数。

    it_s=df[df.dep=="DoIT"].an_s
    print(it_s.head())
    it_rs = df[df.dep=="DoIT"].re_s
    print(it_rs.head())
    
    708     64986
    879     80746
    1656    63777
    1904    91184
    2038    90967
    Name: an_s, dtype: int64
    708     5.5
    879     6.3
    1656    8.4
    1904    7.4
    2038    5.1
    Name: re_s, dtype: float64
    
    np.corrcoef(it_s,it_rs)[0,1]
    
    0.0060245710104947512
    
    plt.scatter(it_s,it_rs)
    plt.show()
    
    output_87_0.png

    几乎看不到相关性

    
    

    相关文章

      网友评论

        本文标题:fish千聊课重新研读03

        本文链接:https://www.haomeiwen.com/subject/rqafextx.html