1.回歸中的異常值
考慮異常值系草,假設(shè)線性回歸將最小化誤差的平方和杆故,那么哪個是最佳的線性回歸
2. 產(chǎn)生異常值的原因
傳感器故障 ignore
數(shù)據(jù)輸入錯誤 ignore
反常事件 pay attention
3. 選擇異常值
4. 異常值檢測/刪除算法
步驟:
- 訓(xùn)練所有數(shù)據(jù)
- 找出訓(xùn)練集中訪問錯誤最多的點(diǎn),去除這些點(diǎn)诈豌,這些點(diǎn)一般占據(jù)全部數(shù)據(jù)的10%
*對當(dāng)前減小后的數(shù)據(jù)集再次進(jìn)行訓(xùn)練
重復(fù)以上
5.使用殘差的異常值檢測
殘差 residual error
在對數(shù)據(jù)進(jìn)行擬合后,數(shù)據(jù)點(diǎn)所產(chǎn)生的誤差
6. 刪除異常值對回歸的影響
7. 異常值刪除策略的小結(jié)
如果要清理擬合結(jié)果,就要去除異常值
如果進(jìn)行的是異常檢測或者欺詐檢測爸业,那么就要去除好的數(shù)據(jù)點(diǎn),保留異常數(shù)值
無論哪種情況亏镰,適用于所有機(jī)器算法的好算法是:
- 訓(xùn)練數(shù)據(jù)
- 去掉誤差最大的點(diǎn)扯旷,一般稱為殘差
- 重復(fù)以上
8. 異常值迷你項(xiàng)目簡介
明顯的異常值可能對回歸結(jié)果有很大的影響
本項(xiàng)目就是去除與回歸線間殘差最大的10%左右的數(shù)據(jù)點(diǎn),去除后再重新擬合回歸
迷你項(xiàng)目也會講到索抓,在安然數(shù)據(jù)集中钧忽,我們要去除異常值還是重點(diǎn)關(guān)注異常值
9. 異常值迷你項(xiàng)目
此項(xiàng)目有兩部分。在第一部分中將運(yùn)行回歸逼肯,然后識別并刪除具有最大殘差的 10% 的點(diǎn)耸黑。然后,根據(jù) Sebastian 在課程視頻中所建議的篮幢,從數(shù)據(jù)集中刪除那些異常值并重新擬合回歸大刊。
在第二部分中,你將熟悉安然財(cái)務(wù)數(shù)據(jù)中的一些異常值洲拇,并且了解是否/如何刪除它們奈揍。
10. 帶有異常值的回歸斜率
Sebastian 向我們描述了改善回歸的一個算法,你將在此項(xiàng)目中實(shí)現(xiàn)該算法赋续。你將在接下來的幾個測試題中運(yùn)用這一算法男翰。總的來說纽乱,你將在所有訓(xùn)練點(diǎn)上擬合回歸蛾绎。舍棄在實(shí)際 y 值和回歸預(yù)測 y 值之間有最大誤差的 10% 的點(diǎn)。
先開始運(yùn)行初始代碼 (outliers/outlier_removal_regression.py) 和可視化點(diǎn)鸦列。一些異常值應(yīng)該會跳出來租冠。部署一個線性回歸,其中的凈值是目標(biāo)薯嗤,而用來進(jìn)行預(yù)測的特征是人的年齡(記得在訓(xùn)練數(shù)據(jù)上進(jìn)行訓(xùn)練M绲)。
數(shù)據(jù)點(diǎn)主體的正確斜率是 6.25(我們之所以知道骆姐,是因?yàn)槲覀兪褂迷撝祦砩蓴?shù)據(jù))镜粤;你的回歸的斜率是多少捏题?
from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit(ages_train,net_worths_train)
print reg.coef_ #5.08
11. 帶有異常值的回歸分?jǐn)?shù)
當(dāng)使用回歸在測試數(shù)據(jù)上進(jìn)行預(yù)測時,你獲得的分?jǐn)?shù)是多少肉渴?
你的回歸應(yīng)用到測試數(shù)據(jù)后的得分是多少公荧?
from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit(ages_train,net_worths_train)
print reg.coef_
print reg.score(ages_test,net_worths_test) #0.88
12.清理后的斜率
你將在 outliers/outlier_cleaner.py 中找到 outlierCleaner() 函數(shù)的骨架并向其填充清理算法。用到的三個參數(shù)是:predictions 是一個列表同规,包含回歸的預(yù)測目標(biāo)循狰;ages 也是一個列表,包含訓(xùn)練集內(nèi)的年齡券勺;net_worths 是訓(xùn)練集內(nèi)凈值的實(shí)際值绪钥。每個列表中應(yīng)有 90 個元素(因?yàn)橛?xùn)練集內(nèi)有 90 個點(diǎn))。你的工作是返回一個名叫cleaned_data 的列表朱灿,該列表中只有 81 個元素昧识,也即預(yù)測值和實(shí)際值 (net_worths) 具有最小誤差的 81 個訓(xùn)練點(diǎn) (90 * 0.9 = 81)。cleaned_data 的格式應(yīng)為一個元組列表盗扒,其中每個元組的形式均為 (age, net_worth, error)跪楞。
一旦此清理函數(shù)運(yùn)行起來,你應(yīng)該能看到回歸結(jié)果發(fā)生了變化侣灶。新斜率是多少甸祭?是否更為接近 6.25 這個“正確”結(jié)果?
現(xiàn)在當(dāng)異常值被清除后褥影,你的回歸的新斜率是多少池户?
注意:在 outliers/outlier_removal_regression.py 執(zhí)行異常值清理的部分中(以注釋 ### identify and remove the most outlier-y points 開頭),請確保 reg.predict
的輸入?yún)?shù)是 ages_train
而非 ages
凡怎,這樣你就只是基于訓(xùn)練數(shù)據(jù)進(jìn)行清理校焦。清理器的參數(shù)還應(yīng)基于 *_train
變量。
def outlierCleaner(predictions, ages, net_worths):
"""
Clean away the 10% of points that have the largest
residual errors (difference between the prediction
and the actual net worth).
Return a list of tuples named cleaned_data where
each tuple is of the form (age, net_worth, error).
"""
cleaned_data = []
error = (net_worths-predictions)**2 #數(shù)組
data = zip(ages,net_worths,error) #zip() 函數(shù)用于將可迭代的對象作為參數(shù)统倒,
#將對象中對應(yīng)的元素打包成一個個元組寨典,
#然后返回由這些元組組成的列表。
sorted_data = sorted(data,key=lambda tup:tup[2])
cleaned_data=sorted_data[:81]
return cleaned_data
#!/usr/bin/python
import random
import numpy
import matplotlib.pyplot as plt
import pickle
from outlier_cleaner import outlierCleaner
### load up some practice data with outliers in it
ages = pickle.load( open("practice_outliers_ages.pkl", "r") )
net_worths = pickle.load( open("practice_outliers_net_worths.pkl", "r") )
### ages and net_worths need to be reshaped into 2D numpy arrays
### second argument of reshape command is a tuple of integers: (n_rows, n_columns)
### by convention, n_rows is the number of data points
### and n_columns is the number of features
ages = numpy.reshape( numpy.array(ages), (len(ages), 1))
net_worths = numpy.reshape( numpy.array(net_worths), (len(net_worths), 1))
from sklearn.cross_validation import train_test_split
ages_train, ages_test, net_worths_train, net_worths_test = train_test_split(ages, net_worths, test_size=0.1, random_state=42)
### fill in a regression here! Name the regression object reg so that
### the plotting code below works, and you can see what your regression looks like
from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit(ages_train,net_worths_train)
print reg.coef_
print reg.score(ages_test,net_worths_test)
try:
plt.plot(ages, reg.predict(ages), color="blue")
except NameError:
pass
plt.scatter(ages, net_worths)
plt.show()
### identify and remove the most outlier-y points
cleaned_data = []
try:
predictions = reg.predict(ages_train)
cleaned_data = outlierCleaner( predictions, ages_train, net_worths_train )
except NameError:
print "your regression object doesn't exist, or isn't name reg"
print "can't make predictions to use in identifying outliers"
### only run this code if cleaned_data is returning data
if len(cleaned_data) > 0:
ages, net_worths, errors = zip(*cleaned_data)
ages = numpy.reshape( numpy.array(ages), (len(ages), 1))
net_worths = numpy.reshape( numpy.array(net_worths), (len(net_worths), 1))
### refit your cleaned data!
try:
reg.fit(ages, net_worths)
plt.plot(ages, reg.predict(ages), color="blue")
print reg.coef_ #6.37
print reg.score(ages_test,net_worths_test) #0.98
except NameError:
print "you don't seem to have regression imported/created,"
print " or else your regression object isn't named reg"
print " either way, only draw the scatter plot of the cleaned data"
plt.scatter(ages, net_worths)
plt.xlabel("ages")
plt.ylabel("net worths")
plt.show()
else:
print "outlierCleaner() is returning an empty list, no refitting to be done"
13. 清理后的分?jǐn)?shù)
當(dāng)使用回歸在測試集上進(jìn)行預(yù)測時房匆,新的分?jǐn)?shù)是多少耸成?
14. 安然異常值
在本節(jié)回歸課程的迷你項(xiàng)目中,你使用回歸來預(yù)測安然雇員的獎金浴鸿。如你所見井氢,單一的異常值都可以對回歸結(jié)果造成很大的差異。但是岳链,我們之前沒有跟你說過的是花竞,你在項(xiàng)目中使用的數(shù)據(jù)集已經(jīng)被清理過明顯的異常值了。第一次看到數(shù)據(jù)集時掸哑,識別并清除異常值是你一直應(yīng)該思考的問題约急,而你現(xiàn)在已經(jīng)通過安然數(shù)據(jù)有了一定的實(shí)踐經(jīng)驗(yàn)寇仓。
你可以在 outliers/enron_outliers.py 中找到初始代碼,該代碼讀入數(shù)據(jù)(以字典形式)并將之轉(zhuǎn)換為適合 sklearn 的 numpy 數(shù)組烤宙。由于從字典中提取出了兩個特征(“工資”和“獎金”),得出的 numpy 數(shù)組維度將是 N x 2俭嘁,其中 N 是數(shù)據(jù)點(diǎn)數(shù)躺枕,2 是特征數(shù)。對散點(diǎn)圖而言供填,這是非常完美的輸入拐云;我們將使用 matplotlib.pyplot 模塊來繪制圖形。(在本課程中近她,我們對所有可視化均使用 pyplot叉瘩。)將這些行添加至腳本底部,用以繪制散點(diǎn)圖:
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()
如你所見粘捎,可視化是查找異常值最強(qiáng)大的工具之一薇缅!
15. 識別最大的安然異常值
有一個異常值應(yīng)該會立即跳出來。現(xiàn)在的問題是識別來源攒磨。我們發(fā)現(xiàn)原始數(shù)據(jù)源對于識別工作非常有幫助泳桦;你可以在 final_project/enron61702insiderpay.pdf 中找到該 PDF。
該數(shù)據(jù)點(diǎn)的字典鍵名稱是什么娩缰?(例如:如果是 Ken Lay灸撰,那么答案就是“LAY KENNETH L”)。
data_dict = pickle.load( open("../final_project/final_project_dataset.pkl", "r") )
def find_outlier(data_dict):
max_bonus = 0
max_name = None
for i in data_dict:
if data_dict[i]['bonus']> max_bonus and data_dict[i]['bonus']!= 'NaN':
max_bonus = data_dict[i]['bonus']
max_name = i
return max_name
print find_outlier(data_dict) #TOTAL
16. 移除安然異常值拼坎?
你認(rèn)為這個異常值應(yīng)該并清除浮毯,還是留下來作為一個數(shù)據(jù)點(diǎn)?
- 清除掉泰鸡,它是一個電子表格 bug
17. 還有更多異常值嗎债蓝?
從字典中快速刪除鍵值對的一種方法如以下行所示:
dictionary.pop( key, 0 )
寫下這樣的一行代碼(你必須修改字典和鍵名)并在調(diào)用 featureFormat() 之前刪除異常值。然后重新運(yùn)行代碼鸟顺,你的散點(diǎn)圖就不會再有這個異常值了惦蚊。
所有異常值都沒了嗎?
Enron 數(shù)據(jù)中還有異常值嗎讯嫂?
- 可能還有四個
18 再識別兩個異常值
我們認(rèn)為還有 4 個異常值需要調(diào)查脯倚;讓我們舉例來看。兩人獲得了至少 5 百萬美元的獎金硝岗,以及超過 1 百萬美元的工資朴摊;換句話說,他們就像是強(qiáng)盜千扔。
和這些點(diǎn)相關(guān)的名字是什么憎妙?
def find_more_outliers(data_dict):
for i in data_dict:
if data_dict[i]['bonus']!='NaN' and data_dict[i]['salary']!='NaN':
if data_dict[i]['bonus']>5e6 and data_dict[i]['salary']>1e6:
print i,data_dict[i]['bonus'],data_dict[i]['salary']
find_more_outliers(data_dict) #LAY KENNETH L 7000000 1072321
#SKILLING JEFFREY K 5600000 1111258
19 移除這些異常值库正?
你是否會猜到這些就是我們應(yīng)該刪除的錯誤或者奇怪的電子表格行,你是否知道這些點(diǎn)之所以不同的重要原因厘唾?(換句話說褥符,在我們試圖構(gòu)建 POI 識別符之前,是否應(yīng)該刪除它們抚垃?)
你認(rèn)為這個異常值應(yīng)該并清除喷楣,還是留下來作為一個數(shù)據(jù)點(diǎn)?
- 留下來鹤树,它是有效的數(shù)據(jù)點(diǎn)
Yes! They're two of Enron's biggest bosses, and definitely people of interest.