1. 既有趣、又有益的交叉验证
validate your machine learning in a better way
通过测试、验证,进而评估你的算法是否能够做你想做的
2. 测试的好处
why use training&testing data?
it helps us understand our results better
□ gives estimate of performance on an independent data set
□ serves as check on overfitting
3.在 Sklearn 中训练/测试分离
如何使用sklearn 中的一些工具拆分训练集和测试集
import numpy as np
from sklearn import corss_validation
from sklearn import datasets
from sklearn import svm
X_train,X_test,y_train,y_test = cross_validation.train_test_split(
iris.data,iris.target,test_size = 0.4,random_state=0) #将数据拆分成训练集和测试集
print X_train.shape,y_train.shape
print X_test.shape,y_test.shape
X_train
训练集的特征
X_test
测试集的特征
y_train
训练集的标签
y_test
测试集的标签
.shape
how many events fall each of these two data sets,the training and the testing
特征 标签
4. 何处使用训练与测试数据 1
the overall analysis flow:
- train/test split
train_features/test_features/train_labels/test_labels - PCA a feature transform
pca.fit(train_features)
#找到数据主成分
pca.transform(train_features)
#转换为主成分表示 - SVM a classification algorithm
svc.fit
svc.predict
pca.fit(train_features)
looking for patterns in the training data
testing data is only something we are going to be using as a tool for validating the steps we are talking about
if we fit our PCA using our testing data,we are sort of giving ourselves a little bit of an unfair advantage.
6. 何处使用训练与测试数据 3
pca.fit(train_features)
#找到数据主成分
pca.transform(train_features)
#转换为主成分表示
svc.train(train_features)
pca.transform(test_features)
#使用在训练数据中发现的主成分来表示我的测试特征
7. 何处使用训练与测试数据 4
after the pca.transform(test_features) ,your test data is now in the same form as your training data set.
pca.fit(train_features)
pca.transform(train_features)
svm.train(train_features)
pca.transform(test_features)
svc.predict(test_features)
8.k-fold cross validation
在你将数据集拆分成训练集和测试集时,你希望最大化训练集,以便获得最好的学习结果,同时,你也希望最大化测试集,以获得最佳验证,那么这里就存在折衷,那么就是交叉验证/cross validation
the basic idea is that 将数据平分到K个相同大小的容器内,而在之前的操作中,我们只是挑选其中的一个容器作为测试容器,另外一个作为训练容器,这是静态训练-测试方法
在k-fold 交叉验证中,你将运行K次单独的学习试验learning experiment
,在每次试验中,你将从这K个子集中挑选一个作为测试集,剩下K-1个子集放在一起作为训练集,然后训练你的机器学习算法,与以前一样,在测试集上验证性能,在k-fold 交叉验证,这一操作会运行K次,然后对于K个测试集的表现进行平均,将K次试验的测试结果取平均值
因为你要运行K次单独的learning experiment,所以这会花更多的计算时间,但是机器学习算法的评估将更准确,因为从某种程度上讲,你几乎使用了全部的数据用于训练集,也几乎使用了全部的数据用于测试集
static train test methodology --min training time
k- fold cross validation -- min run time / max accuracy
9. Sklearn 中的 K-fold cross validation
from sklearn.cross_validation import KFold
t0= time()
cv = KFold( len(authors), 2, shuffle=True ) #将 shuffle 标志设置为 true来随机化 Sklearn K-fold cross validation 中的事件
for train_indices,test_indices in kf:
# make training and testing datasets
features_train = [word_data[ii] for ii in train_indices] #利用索引进入特征和标签
features_test = [word_data[ii] for ii in test_indices]
authors_train = [authors[ii] for ii in train_indices]
authors_test = [authors[ii] for ii in train_indices]
# TFIDF and feature selection
vectorizer = TfidfVectorizer(sublinear_tf = True,max_df=0.5,
stop_words = 'english')
feature_train_transformed = vectorizer.fit_transform(features_train)
feature_test_transformed = vectorizer.transform(features_test)
selector = SelectPercentile(f_classif,percentile = 10)
selector.fit(features_train_transformed,authors_train)
features_train_transformed = selector.transform(features_train_transformed).toarray()
features_test_transformed = selector.transform(features_test_transformed).toarray()
clf = GaussianNB()
clf.fit(features_train_transformed,authors_train)
print "training time:" ,round(time() - t0,3),'s'
t0=time()
pred = clf.predict(features_test_transfomed)
print "predicting time",round(time() - t0,3),'s'
acc = accuracy_score(pred,authors_test)
print "accuracy:", round(acc,3)
len(authors)
the number of items in the total data set
train_indices
a set of indices of all the data points that i'm going to use in the training set
10. 针对 Sklearn 中的 k-fold cross validation的实用建议
cv = KFold( len(authors), 2, shuffle=True )
shuffle=True 可避免所有某一特定类型的事件都属于训练集,而另一特定类型的事件则属于测试集,在这种情况下,针对一种类型事件的训练不会帮助我们成功地对另一类型的事件进行分类
11. 为调整参数而进行的交叉验证
交叉验证选择可实现最佳性能的参数调整方式
12. klearn 中的 GridSearchCV
GridSearchCV 用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。它的好处是,只需增加几行代码,就能遍历多种组合。
下面是来自 sklearn 文档 的一个示例:
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
svr = svm.SVC()
clf = grid_search.GridSearchCV(svr, parameters)
clf.fit(iris.data, iris.target)
print clf.best_params_
让我们逐行进行说明。
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
参数字典以及他们可取的值。在这种情况下,他们在尝试找到 kernel(可能的选择为 'linear' 和 'rbf' )和 C(可能的选择为1和10)的最佳组合。
这时,会自动生成一个不同(kernel、C)参数值组成的“网格”:
('rbf', 1) | ('rbf', 10) |
---|---|
('linear', 1) | ('linear', 10) |
各组合均用于训练 SVM,并使用交叉验证对表现进行评估。
svr = svm.SVC()
这与创建分类器有点类似,就如我们从第一节课一直在做的一样。但是请注意,“clf” 到下一行才会生成—这儿仅仅是在说采用哪种算法。另一种思考方法是,“分类器”在这种情况下不仅仅是一个算法,而是算法加参数值。请注意,这里不需对 kernel 或 C 做各种尝试;下一行才处理这个问题。
clf = grid_search.GridSearchCV(svr, parameters)
这是第一个不可思议之处,分类器创建好了。 我们传达算法 (svr) 和参数 (parameters) 字典来尝试,它生成一个网格的参数组合进行尝试。
clf.fit(iris.data, iris.target)
第二个不可思议之处。 拟合函数现在尝试了所有的参数组合,并返回一个合适的分类器,自动调整至最佳参数组合。现在您便可通过 clf.best_params_
来获得参数值。
15. 验证迷你项目简介
建立一个监督学习算法,该算法可根据安然数据集判断公司破产时发生的欺诈案件中,谁是利益相关人
创建第一版本的嫌疑人识别器
16. 验证迷你项目
在此迷你项目中,你将从分割训练数据和测试数据开始。这是你通往“构建 POI 识别符”这个最终项目的第一步。
17.第一个(过拟合)POI 识别符
你将先开始构建想象得到的最简单(未经过验证的)POI 识别符。 本节课的初始代码 (validation/validate_poi.py) 相当直白——它的作用就是读入数据,并将数据格式化为标签和特征的列表。 创建决策树分类器(仅使用默认参数),在所有数据(你将在下一部分中修复这个问题!)上训练它,并打印出准确率。 这是一颗过拟合树,不要相信这个数字!尽管如此,准确率是多少?
import pickle
import sys
sys.path.append("../tools/")
from feature_format import featureFormat, targetFeatureSplit
data_dict = pickle.load(open("../final_project/final_project_dataset.pkl", "r") )
### first element is our labels, any added elements are predictor
### features. Keep this the same for the mini-project, but you'll
### have a different feature list when you do the final project.
features_list = ["poi", "salary"]
data = featureFormat(data_dict, features_list)
labels, features = targetFeatureSplit(data)
### it's all yours from here forward!
from sklearn import svm
from sklearn.metrics import accuracy_score
clf = svm.SVC()
clf.fit(features,labels)
pred = clf.predict(features)
acc = accuracy_score(pred,labels)
print acc #0.9894
你的首个(过拟合)POI 标识符的准确度是多少? 0.9894
从 Python 3.3 开始,字典键被处理的顺序发生了变化,顺序在每次代码运行时都会得到随机化处理。 这会造成与评分工具和项目代码(均在 Python 2.7 下运行)的一些兼容性问题。 要更正这个问题,向 validate_poi.py
第 25 行调用的 featureFormat
添加以下参数:
sort_keys = '../tools/python2_lesson13_keys.pkl'
这将以 Python 2 的键顺序打开 tools
文件夹中的文件。
注意:如果你没有获得评分工具期望的结果,你可能会想查看 tools/feature_format.py
文件。 由于最终项目发生的变化,一些文件更改影响了此处所写任务的数量输出。 检查你是否从资源库获得了最新版本的文件,以便 featureFormat
具有 sort_keys = False
的默认参数,并且 keys = dictionary.keys()
能够产生结果。
18. 部署训练/测试机制
现在,你将添加训练和测试,以便获得一个可靠的准确率数字。 使用 sklearn.cross_validation 中的 train_test_split 验证; 将 30% 的数据用于测试,并设置 random_state 参数为 42(random_state 控制哪些点进入训练集,哪些点用于测试;将其设置为 42 意味着我们确切地知道哪些事件在哪个集中; 并且可以检查你得到的结果)。更新后的准确率是多少?
适当部署的测试范围的准确度是多少?
#!/usr/bin/python
"""
Starter code for the validation mini-project.
The first step toward building your POI identifier!
Start by loading/formatting the data
After that, it's not our code anymore--it's yours!
"""
import pickle
import sys
sys.path.append("../tools/")
from feature_format import featureFormat, targetFeatureSplit
data_dict = pickle.load(open("../final_project/final_project_dataset.pkl", "r") )
### first element is our labels, any added elements are predictor
### features. Keep this the same for the mini-project, but you'll
### have a different feature list when you do the final project.
features_list = ["poi", "salary"]
data = featureFormat(data_dict, features_list)
labels, features = targetFeatureSplit(data)
### it's all yours from here forward!
from sklearn import tree
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
features_train, features_test, labels_train, labels_test = \
train_test_split(features,labels,test_size=0.3,
random_state = 42)
clf = tree.DecisionTreeClassifier()
clf.fit(features_train,labels_train)
pred = clf.predict(features_test)
acc = accuracy_score(pred,labels_test)
print acc