统计学中的相关性分析
掌握一点儿统计学介绍了统计学中常用到的函数,特别重点介绍了Standard Deviation(标准差)。接下来结合一个案例来谈谈相关性(Correlation)分析的问题。按照维基百科的讲解,所谓“相关性”指的是两个变量之间关系(或依赖)的度量。相关性的度量值其取值范围从-1(perfect negative relationship,完美负相关)到1(perfect positive relationship,完美正相关)之间,若值为0,则表明两个变量之间不存在straight-line relationship(直线关系)。而所谓“Linear Correlation(线性相关)”指的就是两个变量之间存在一种直线关系。
在Data Science from Scratch一书中给出一个案例分析:某社交网站某人的朋友数与他(她)在该网站上花费的时间之间的关系。通过对网站日志数据的挖掘,可以获得用户每天的分钟数(记为daily_minutes)和朋友数(记为num_friends)。根据前面获得的知识,这个问题就转换为求daily_minutes与num_friends两个变量之间的Correlation。
Covariance
要计算相关性,可以先看看covariance(协方差)的概念,它与variance(方差)是一个成对的概念。variance度量的是单个变量与变量平均值的偏差,而covariance度量的是两个变量的总体误差。在Python中,可以实现为:
def covariance(x, y):
n = len(x)
return dot(de_mean(x), de_mean(y)) / (n - 1)def de_mean(x):
"""获得各个数与mean的差值"""
x_mean = mean(x)
return [x_i - x_mean for x_i in x]
dot函数的功能是将两组数的元素两两相乘后对它们的乘积进行求和。至于为什么是除以n - 1,在掌握一点儿统计学中已有详细介绍。
注意de_mean并没有对差值取绝对值或求平方,因而当x和y变量同时都大于各自平均数或同时都小于各自平均数时,covariance的值就为正数,如果一个变量大于平均数,而另一个小于平均数,结果就为负数。根据协方差的意义,如果两个变量分别为x和y,当covariance值为较大的正数时,则y值大,x值也会大,y值小,x值也会小;若covariance值为较大的负数时,变化则是逆向的;若接近于0,意味着二者几乎不存在关系。
不过,计算covariance存在两个致命的问题。其一是它忽略了两个变量的单位问题,例如daily_minutes的单位是分钟,而num_friends是个数,二者风马牛不相及,就好似将苹果与西瓜进行对比一样,没有直接的对比性。其二则是covariance值的大小不足以说明变量间的相关性。例如当num_friends的数量翻倍而daily_minutes的数值保持不变时,虽然covariance的值同样翻倍了,但并不认为这两个变量的相关性加强了。
注意,从数值看,covariance的取值并非-1到1之间,因而也不符合计算相关性的要求。
Correlation
为了消除前面提及的两个因素对相关性的影响,我们可以对两个变量求标准差,通过压缩离散度来保障度量的精确性。计算correlation的函数为:
def correlation(x, y):
stdev_x = standard_deviation(x)
stdev_y = standard_deviation(y)
if stdev_x > 0 and stdev_y > 0:
return covariance(x, y) / (stdev_x * stdev_y)
esle:
return 0
此时,correlation的取值范围在-1到1之间。若值为-1,可以称之为perfect anti-correlation,为1,则称之为perfect correlation。
但是,我们在采集数据样本时,需要特别关注一些异常数据,这些数据就像声音分析时出现的噪音一般,会对分析结果产生较大的影响,导致分析失误。例如,对某一个用户而言,可能他拥有非常高的朋友数,但每天用在该网站的时间为0,这就会影响correlation的取值。
这种异常数据在现实生活中是极为常见的情况,借助前面的例子,可能出现的情况是某个拥有高朋友数的用户因为外出度假,无法方便的上网,导致在度假期间几乎没有上网分钟数。因此在进行数据分析时,我们要提前甄别这些异常数据,然后在分析时过滤这些异常数据。
辛普森悖论(Simpson's Paradox)
辛普森悖论是由英国统计学家E.H.Simpson在1951年提出的悖论,即在某个条件下的两组数据,分别讨论时都会满足某种性质,可是一旦合并考虑,却可能导致相反的结论。
书中给出一个范例,视图通过计算数据科学家的平均朋友数来判断他们的社交参与程度。进行分析时,将数据样本分为西海岸(West Coast)和东海岸(East Coast)数据科学家。结果得到的结果如下所示:
coast |
# of members |
avg. # of friends |
---|---|---|
West Coast |
101 |
8.2 |
East Coast |
103 |
6.5 |
根据朋友数的平均值来看,西海岸的数据科学家似乎更有朋友缘。然而,当我们为该数据加入一个学位(degree)变量时,发现数据出现了迥然不同的变化:
coast |
degree |
# of members |
avg. # of friends |
---|---|---|---|
West Coast |
PhD |
35 |
3.1 |
East Coast |
PHD |
70 |
3.2 |
West Coast |
no PhD |
66 |
10.9 |
East Coast |
no PHD |
33 |
13.4 |
在增加了degree变量时,发现无论是拥有博士学位的数据科学家还是没有博士学位的数据科学家,在朋友数的平均值方面都是东海岸数据科学家的值要高。这与没有引入degree变量之前的数据截然相反。
为什么会造成这样的结果呢?原因在于数据的量与质是不等价的,就好似我们只以100场篮球比赛的胜率来评价一只球队的水平高低一样。如果一只球队专找高手挑战20场而胜1场,另外80场找平手挑战而胜40场,结果胜率41%;另一只球队则专挑高手挑战80场而胜8场,而剩下20场平手打个全胜,结果胜率为28%,比 41%小很多,但仔细观察挑战对象,后者明显较有实力。因此,若要避免辛普森悖论,就需要斟酌各个分组的权重,以一定的系数去消除以分组资料基数差异所造成的影响。
Correlation和Causation(因果关系)
两个变量的相关性并不意味着二者存在因果关系(correlation is not causation)。即使x和y的关系是强相关性,也不能意味着是x是y的因,y是x的果,因为影响到y的除了x之外,可能还有其他的变量。
即以sum_friends与daily_minutes为例,一个用户的朋友数越多,确实可能导致他在该网站上花费的时间数增加,但也有可能是该网站上发表的文章内容吸引了用户。即使是朋友数,其实也存在质量之分。例如某个用户的朋友数也许不多,但如果他的朋友都是他的同好或知己,会极大地影响上网时间的激增。假设这个网站是数据科学相关的网站,那么用户对数据科学的热爱程度同样会影响到他的上网时间。
- Java 10 已发布!时隔 6 月带来 109 项新特性
- STL中的nth_element()方法的使用
- C++queue容器学习(详解)
- 牛客面经 |这可能不只是一篇面经
- 图的基本算法(BFS和DFS)
- C++STL中set的使用策略(详解)
- Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)(A.思维题,B.思维题)
- 设计模式六大原则(1):单一职责原则
- 设计模式六大原则(2):里氏替换原则
- Selenium2+python自动化72-logging日志使用
- Codeforces Round #395 (Div. 2)(A.思维,B,水)
- php实现图形计算器
- Selenium2+python自动化73-定位的坑:class属性有空格
- 华中农业大学第五届程序设计大赛网络同步赛题解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java进阶训练营 第一周JVM 预习笔记
- LeetCode905. 按奇偶排序数组 题解
- codeforces 1133D (map+精度控制)
- 只要十步,你就可以应用表达式树来优化动态调用
- 宏任务和微任务的一个小事
- 如何使用ES6的新特性async await进行异步处理
- java9-可以在interface中定义私有方法了
- 继承
- ES5新增方法
- django 重写user表 继承 AbstractUser 出现创建用户密码是明文
- Element表单嵌套数据验证
- 表格中的输入框验证
- 如何设置Element表格显示或者隐藏列
- Python 二进制,十进制,十六进制转换
- 原生node处理get和post请求