2018年5月2日星期三

《深入浅出统计学》- 定性数据和定量数据 & 平均数


定性数据和定量数量

数据被划分为各种类别,用以描述某类的性质和特征。因为,类比数据也称为定性数据。关于定性数据,记住一个重点:不能将数据值理解为数字。

数值型数据不同,它所设计的是数字。数值型数据中的数值具有数字的意义,但还涉及计量或计数。由于数值型数据描述的是数量,所以也称为定量数据

  • 频数是一种统计方法,用于描述一个类别中有多少个项。
  • 饼图能很好地体现基本比例。
  • 条形图更灵活、更精确。
  • 数值型数据设计的是数字和数量;类别数据涉及的是表述和质量。
  • 水平条形图用于展现类别数据,尤其是在类别名称太长的时候。
  • 垂直条形用于展现数值型数据;若类别名称不长,也用于体现类别数据。
  • 可以在一张条形图上体现多批数据,具体做法可由你选择。可以使用堆积条形图,让相互关联的长方形并列显示,借此比较频数;可以使用分段条形图,把长方形一个一个衔接起来,借此显示比例和总频数。
  • 条形图标度可以是百分数,也可以是频数。
  • 每张图都变化多端。



  • 频数密度指的是分组数据中的频数的密集度。计算方法如下:频数密度=频数/组距
  • 直方图是一种专门用于体现分组数据的图形。它看起来很像条形图,但每条长方形的高度等于频数密度而不是频数。
  • 绘制直方图时,每个长方形的宽度与其分组宽度(组距)成正比例。长方形按照连续的数字标度绘制。
  • 直方图中的每个组的频数通常长方形面积求出。
  • 直方图的长方形之间没有间隔。


折线图应只用于展现数值型数据,不应用于类别数据。原因是,对类别数据进行比较是有意义的,但为其绘制趋势线却没有意义。只有在基于某些数值型单位(比如时间)对类别进行比较时才使用折线图。这时,每一个类别都用一条独立的线表示。


  • 累积频数即到某个特定数值为止的总频数,即频数等累积总和。
  • 通过累积频数图,可基于累积频数找出每组数据的上限。
  • 需要提现趋势时请使用折线图,例如基于时间的趋势。
  • 可用折线图显示多批数据。每批数据各用一条线表示,请确保能清楚识别每一条线。
  • 由于通过折线图很容易看出趋势形状,因此可用折线图进行基本的预测。只要延长趋势线即可进行预测,但要尽量保持基本形状。
  • 不要使用折线图显示类别数据数据 —— 除非要显示每一个类别的趋势;例如基于时间的趋势。如果要显示每一个类别的趋势i,要为每一个类别画一条线。


均值
𝝻 = ∑x/ n

异常值:与其它数据格格不入的极高或极低的数值。
当异常值将数据向左右或向右「拉」时即产生偏斜数据。

中位数
中位数永远处于中间,它是个中间值。

求中位数三步法
  1. 按顺序排列数字:从最小值到最大值。
  2. 如果有奇数个数值,则中位数为位于中间的数值。如果有 N个数,则中间数的位置为 (n + 1) /2 .
  3. 如果有偶数个数值,则将两个中间数相加,然后除以 2 。中间位置的算法是: ( n + 1) / 2。两个中间数分别位于这中间位置的两侧。


Q:  如果确实想用均值,哪怕存在偏斜数据,还能用吗?
A:  可以用,而且大家经常这么做。不过,这时均值无法最恰当地体现典型值。你需要使用中位数。

Q: 这是你的看法,但均值的主要愿意的确是给出典型值,均值是个平均数。
A 均值带来的危险是:它会给出一个不存在于数据集中区的数值。以功夫为例:如果你要加入这个班,并随机挑出一个人,很可能这个人是在 20 岁左右,因为班上大多数人的年龄都在 20 岁左右——只看均值无法形成这种印象,求出中位数会让你对数据更有准确的预期。

但即时是中位数,有时也会得出不存在于数据集中区的值。有时候,为了正确地指出典型值,需要使用各种各样的方法。

Q:这么说中位数比均值更好?
A:有时候中位数比均值更合适,但这并不是说它更好。大多数时候,你会需要使用均值,因为均值的优势通常远胜中位数,均值对于抽样数据来说更稳定。

Q:对于类别数据该怎样使用均值或中间值呢?



如果数值是对称的,均值和中位数会相等,否足它们往往不同。一般规律是:如果存在异常值,那么均值往往超着异常值移动,而中位数则停在原来的地方不动。
现在请认认真真考虑如何以最佳方式表示小鸭呱呱游泳班的代表年龄。下面是数据提示:
年龄 1 2 3 31 32 33
频数 3 4 2 2 4 3

  1. 为什么认为均值和中位数都不适用于这些数据?为什么均值和中位数都具有误导性?

     对于以上数据,均值和中位数都具有误导性,因为两者都没有表示出班级中的成员的典型年龄。均值说明有一些十几岁的青少年参加了游泳班。实际上一个也没有,中位数也有同样的问题,但如果有别的人加入班级,中位数会大幅度波动。
  2. 如果必须挑选一个年龄来代表这个班级的年龄,这个年龄是多少?为什么?

    的确不太可能能调出一个完全代表班级的年龄。这个班级实际上是由两批年量组成的:一批是孩子的年龄,一批是家长的年龄。确实无法用一个数字同时代表两批年龄。
  3. 要是能挑选两个年龄呢?你会选哪个年龄?为什么?
    由于这些数据看上去包括两批数据,挑选两个年龄来代表班级年龄是有意义的,一个年龄代表孩子们的年龄,一个是代表家长们的年龄。我们会选择 2 32 因为这两个年龄组的成员最多。


众数
众数是一批数字中最常健的数值,即频数最大的数值。与均值和中位数不同,众数必须是数据集中的一个数值,而且是频繁出现的数值。

如果有一个以上的数值具有最大频数,则每一个这样的数值都是众数。
如果一批数据有两个众数,则我们说这种数据是双峰数据。

众数不仅能用于数值型数据,还能用于类别数据。事实上,众数是唯一能用于类别数据的平均数。在处理类别数据是,众数是最常出现的平均数类型。

具有最高频数的组被称为众数组

求众数三步法:
  1. 把数据中不同或数值全部找出来。
  2. 写出每个数值或类别的频数。
  3. 挑出具有最高频数的一个或几个数值,得出众数。

Q: 你认为总数在什么情况下最有用?A: 当众数的数据较少时,或者,当数据为类别数据,而不是数值型数据时,均值和中位数都不能用于类别数据。

Q: 众数在什么情况下最无用?
A:当众数很多时。

众数必须存在于数据集中,众数时唯一能用于类别数据的平均数。

平均数 计算方法 何时使用
均值(µ) 以下任一算法均可 ∑ x/n 或 ∑f𝓍/∑f 在数据非常对称,且仅显示出一种趋势时使用。
中位数 将所有数据按照升序顺序进行排列。如果有奇数个数值,则中位数位中间的数值;如果有偶数个数值,则中位数由两个中间的数值相加再除以 2 得到的结果。 在数据由于异常值而发生偏斜时使用。
众数 选出具有最大频数的一个或几个数值。如果数据看看分为两组,则为每组找出一个众数。 在遇到类别数据时使用。当数据可以分为两个或更多组时使用。


2016年9月19日星期一

保留字在 PostgreSQL  里做常规字符使用时用双引号(""), 而 MySQL 里用 backtick(反引号 `)。

PostgreSQL 监控指标

原文地址: PostgreSQL监控指标

PostgreSQL 版本: 8.2.15

数据库状态信息

  1. 目前客户端的连接数
    SELECT COUNT(*) FROM pg_stat_activity WHERE NOT procpid = pg_backend_pid()
    
  2. 连接状态
    SELECT procpid, waiting, current_timestamp - LEAST(query_start, xact_start) AS runtime, SUBSTR(current_query, 1, 25) AS current_query FROM pg_stat_activity WHERE NOT procpid = pg_backend_pid()
    
    可以查看每个连接的 procpid,是否发生等待,根据事物或查询统计已执行时间,查询语句等。有多少个连接查询就会有多少条记录。
  3. 数据库占用空间
    SELECT pg_size_pretty(pg_database_size('postgres'))
    
    一个数据库数据文件对应存储在以这个数据库 oid (pid) 命令的文件中,通过统计所有以 oid(pid) 命名文件的总大小,也可以得出这个数据库占用大空间。oid(pid) 可通过 SQL SELECT oid, datname FROM pg_database;获得。
    表占用的空间使用 pg_relation_size() 查询,对应的系统中的文件名和 pg_class 中的 filename 相同,一个热点的表最好一天一个统计大小,获得表的一个增长状况。根据需求提前准备空间应付数据库的增长。
  4. 等待事件
    SELECT bl.pid AS blocked_pid, a.usename AS blocked_user, kl.pid AS blocking_pid, ka.usename AS blocking_user, a.current_query AS blocked_statement 
    FROM pg_locks bl 
    JOIN pg_stat_activity a ON a.procpid = bl.pid 
    JOIN pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid 
    JOIN pg_stat_activity ka ON ka.procpid = kl.pid WHERE NOT bl.granted;
    
    根据阻塞的语句的会话 PID 做相应处理。

数据库统计信息

  1. 统计 SQL, 需安装扩展 pg_stat_statements-1.1.sql,调整 postgres.conf: shared_preload_libraries=‘pg_stat_statements’
    SELECT calls, total_time, rows, 100.0 * shared_blks_hit /nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent,substr(query,1,25)
    FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
    
    上述查询是按照查询到执行时间排序,可以定位到执行比较慢的 sql, 也可以用来查常用 SQL,以及 SQL 共享内存的命中率等信息。
  2. 表的共享内存使用情况,需安装扩展 pg_buffercache-1.0.sql
    SELECT c.relname, count(*) AS buffers 
    FROM pg_buffercache b INNER JOIN pg_class c ON b.relfilenode = pg_relation_filenode(c.oid) 
    AND b.reldatabase IN (0, (SELECT oid FROM pg_database WHERE datname = current_database())) GROUP BY c.relname ORDER BY 2 DESC LIMIT 5;
    
    表在共享内存中占用的块数,用来查看表是不是在内存中,buffers 的单位是数据块,默认 8K, 如果计算大小等于表的大小,说明全表的数据都在缓存在,这时的查询速度很快。
  3. 表执行操作的统计
    统计对一个表操作的偏重, INSERT, UPDATE, DELETE 的比率
    SELECT relname,cast(n_tup_ins AS numeric) / (n_tup_ins + n_tup_upd + n_tup_del) AS ins_pct,
    cast(n_tup_upd AS numeric) / (n_tup_ins + n_tup_upd + n_tup_del) AS upd_pct, 
    cast(n_tup_del AS numeric) / (n_tup_ins + n_tup_upd + n_tup_del) AS del_pct 
    FROM pg_stat_user_tables where relname='products';
    
  4. 表 IO 和索引 IO
    表 IO 主要涉及查询的逻辑块和物理块,归到底也是命中率的问题。一个表存在在内存中的内容越多,相应的查询速度越快。相关视图:pg_stat_user_tables
    相对于表的大小来说,索引占用的空间要小很多,所以常用的表,可以让其索引一直存在内存中,很多时候保持索引的一个高命中率是非常必要的。相关视图pg_stat_user_indexes
    SELECT indexrelname,cast(idx_blks_hit as numeric) / (idx_blks_hit + idx_blks_read) AS hit_pct,
    idx_blks_hit,idx_blks_read 
    FROM pg_statio_user_indexes WHERE (idx_blks_hit + idx_blks_read)>0 ORDER BY hit_pct;
    

系统监控信息

  1. 数据库基本状态信息
    $ ps -ef | grep postgres
    $ netstat -altunp | grep 5432
    $ pg_controdata 
    

  2. $ top -u gpadmin
    $ free
    $ iotop -u gpadmin
    
    用 top 可以分析出系统当前整体的负载状况。当总体负载率很低,在 IO 等待率高的时候可以用 iotop 来定位 IO 具体的进程, top 中的 VIRT RES 表示进程希望获取的内存和占用系统内存的数量。可以据此来判断系统内存的分配情况。内存的值也关联到一些参数的设定,如 postgres 在发生 checkpoint 之前, checkpointer process 进程会消耗比较大的物理内存,直到检查点发生后,占用的内存会被释放掉,所以在设置 checkpoint 时间的时候也要将内存的占用考虑进去。


2016年9月18日星期日

获取 *nix 文件的绝对路径

cd `dirname $0`
path=`pwd`
因为 $0 是指当前路径到执行脚本的相对路径。所以先需切换到执行文件的目录,才能用 pwd得到其绝对路径。

2016年9月13日星期二

PostgreSQL 管理进程

  1. 查看当前服务器的连接情况
    SELECT * FROM pg_stat_activity;
    
    返回信息包括如下:
    • datid
    • datname 数据库名
    • procpid 进程 ID
    • sess_id 会话 ID
    • usesysid
    • usename 提交 SQL 的用户名
    • current_query 当前 SQL 执行
    • waiting 当前是否等待
    • query_start SQL 提交时间
    • backend_start 后台执行时间
    • client_add SQL 提交的服务器
    • application_name SQL 提交的终端
    • xact_start SQL 执行开始时间
    • waiting_reason 等待原因,与 waiting 字段结合使用
    该查询结果也可在 PgAdmin 的 ”服务器状态“ 里查看到。
  2. 杀死 IDLE 进程
    SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE current_query=''
  3. 当 pg 版本 >= 8.4 时,可用以上 SQL Kill 所有 IDLE 进程, pg_terminate_backend 是 pg 的内部方法。另外还有 pg_cancel_backend(procpid) 取消指定进程的查询操作,但它不能释放数据库连接。

2016年9月8日星期四

PostgreSQL psql 客户端命令

连接数据库
psql -h host_name -U user_name -d database_name -W

  • \l 列出所有数据库
  • \d 显示当前数据库下的所有表
  • \d table_name 列出指定表名的表结构
  • \c database_name 切换到指定的数据库,这时会要重新输入用户名和密码
  • \q 退出终端

2016年8月7日星期日

PDO 参数设置

// 只返回字段名的结果
$this->pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);

// 防止整形在返回结果中变为字符串
$this->pdo->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, false);
$this->pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);