优达笔记-安然数据分析 异常值处理

安然事件,作为美国最大的欺诈案,也是破产案,不仅在经济法律领域有很重要的意义,它所保留下来的关于高管及员工的工资、邮件、股权等等的真实数据对于想要学习机器学习的人来说也是非常好的材料

上一篇文章我们讲了如何查看数据,包括查看这些数据有那些特征,每个人的数据是什么,如何查看NaN值等,需要回归的可以再看两眼哦[机器学习] 美国最大欺诈案—对安然事件数据集的分析(一)

本篇文章主要是对安然事件数据的异常值进行分析

我们采用的方法是运行回归,然后识别并删除具有最大残差的 10% 的点。然后,从数据集中删除那些异常值并重新拟合回归(对这个方法不明白的童鞋请看[机器学习] 遇到异常值怎么办?

对异常值不做处理的回归

打开\ud120-projects\outliers\outlier_removal_regression.py
这个python文件已经包含了数据载入和可视化的代码,需要填写的就是一个线性回归的代码(线性回归不了解的童鞋请看[机器学习] 最实用的算法:回归

from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit(ages_train,net_worths_train)

注意由于sklearn的升级,弃用了.cross_validation模块,所以还需要改一行代码:

###23行的from sklearn.cross_validation import train_test_split改为:
from sklearn.model_selection import train_test_split

你可以通过下面的代码来查看未经异常值处理的斜率和R²值:

print "Slope is:",reg.coef_

print "R^2 for testing data is:",reg.score(ages_test,net_worths_test)

优达笔记-安然数据分析 异常值处理

此时的斜率是5.078,R²为0.878

对异常值处理之后的回归

打开\ud120-projects\outliers\outlier_cleaner.py 中找到 outlierCleaner() 函数的骨架并向其填充清理算法。

到的三个参数是:predictions 是一个列表,包含回归的预测目标;ages 也是一个列表,包含训练集内的年龄;net_worths 是训练集内净值的实际值。每个列表中应有 90 个元素(因为训练集内有 90 个点)。你的工作是返回一个名叫cleaned_data 的列表,该列表中只有 81 个元素,也即预测值和实际值 (net_worths) 具有最小误差的 81 个训练点 (90 * 0.9 = 81)。cleaned_data 的格式应为一个元组列表,其中每个元组的形式均为 (age, net_worth, error)。一旦此清理函数运行起来,你应该能看到回归结果发生了变化。新斜率是多少?是否更为接近 6.25 这个“正确”结果?

这是我的答案

    cleaned_data=[]
    e=abs(predictions-net_worths)
    cleaned_data=zip(ages,net_worths,e)
    cleaned_data=sorted(cleaned_data,key=lambda clean:clean[2])
    clean_num=int(math.ceil(len(cleaned_data)*0.9))
    cleaned_data=cleaned_data[:clean_num]

优达笔记-安然数据分析 异常值处理
会发现,经过异常处理之后,斜率变成了6.37,R²为0.983

安然异常值的可视化

这次我们分析的不是"年龄”和“收入”了,而是“工资”和“奖金",

你可以在 outliers/enron_outliers.py 中找到初始代码,该代码读入数据(以字典形式)并将之转换为适合 sklearn 的 numpy 数组。由于从字典中提取出了两个特征(“工资”和“奖金”),得出的 numpy 数组维度将是 N x 2,其中 N 是数据点数,2 是特征数。对散点图而言,这是非常完美的输入;我们将使用 matplotlib.pyplot 模块来绘制图形。(在本课程中,我们对所有可视化均使用 pyplot。)将这些行添加至脚本底部,用以绘制散点图

for point in data:
    salary = point[0]
    bonus = point[1]
    matplotlib.pyplot.scatter( salary, bonus )

matplotlib.pyplot.xlabel("salary")
matplotlib.pyplot.ylabel("bonus")
matplotlib.pyplot.show()

就会出现可视化的图:
优达笔记-安然数据分析 异常值处理

我们可以看到右上角有一个异常值,那么这个异常值是谁呢?怎么搜索它?可以排个序然后找到那个最大值:

max_value=sorted(data,reverse=True,key=lambda sal:sal[0])[0]
print max_value

for item in data_dict:
    if data_dict[item]['salary']==max_value[0]:
	    print item

然后会发现,这个异常值的key是 TOTAL,说明它是一个电子表格 bug,清除掉就可以了

清除的方法就是在调用 featureFormat() 之前写下这样的代码:

data_dict.pop('TOTAL', 0 )

优达笔记-安然数据分析 异常值处理

即使是清除了异常值之后,仍然有一些数据看起来不是很合乎逻辑,我们认为还有 4 个异常值需要调查;举例来看。两人获得了至少 5 百万美元的奖金,以及超过 1 百万美元的工资;换句话说,他们就像是强盗。怎么可以拿这么多钱呢?

用下面的代码找到这两个人:

for item in data_dict:
    if data_dict[item]['bonus']!='NaN' and data_dict[item]['salary']!='NaN':
	    if data_dict[item]['bonus']>5e6 and data_dict[item]['salary']>1e6:
		    print item

发现这两个人就是:LAY KENNETH L和SKILLING JEFFREY K,但是这两个数据就不需要删除了,因为他们并不是因为Excel的bug或者什么输入错误,而是这两个人可能非法拿到了很多钱,是非常重要的研究对象

OK,到此异常处理就结束了,是不是很有意思?

你的是对作者莫大的支持哦~????

如果你想看其他的关于机器学习的一些知识,可以关注我的知乎专栏,我是一个机器学习小白,初学者总会遇到各种各样的困难,我会从初学者的角度把每一个坑都给你仔仔细细的讲明白咯~

优达笔记-安然数据分析 异常值处理