数据处理的统计学习(scikit-learn教程)
数据挖掘入门与实战 ?公众号: datadw
一、统计学习:scikit-learn中的设置与评估函数对象(1)数据集scikit-learn 从二维数组描述的数据中学习信息。他们可以被理解成多维观测数据的列表。如(n,m),n表示样例轴,y表示特征轴。
当数据初始时不是(
>>>digits = datasets.load_digits()
python
>>>data = digits.images.reshape((digits.images.shape[0],-1))
(2)估计函数对象
一个估计函数带有一个 >>>estimator.fit(data)
>>>estimator = Estimator(param1=1,param2=2)
>>>estimator.estimated_param_
二、有监督学习:从高维观察数据预测输出变量
(1)近邻和高维灾难
KNN(最近邻)分类示例: # Split iris data in train and test data
高维灾难: 如果特征数是P,你就需要n 1/d^p个点。也就是说,如果我们在一维度情况下需要10个点,在P维度情况下需要10^p个点。当P变大的时候,为获得一个好的预测函数需要的点数将急剧增长。 这被称为高维灾难(指数级增长),也是机器学习领域的一个核心问题。 (2)线性模型:从回归到稀疏性Diabets数据集(糖尿病数据集) 糖尿病数据集包含442个患者的10个生理特征(年龄,性别、体重、血压)和一年以后疾病级数指标。 diabetes = datasets.load_diabetes() 线性模型:y = βX+b ? ?X:数据
? ?y:目标变量
? ?β:回归系数 ? ?b:观测噪声(bias,偏差)
from sklearn import linear_model
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train,diabetes_y_train)print(regr.coef_)
收缩(Shrinkage): X = np.c_[ .5,1].T
y = [.5,1]
test = np.c_[ 0,2].T
regr = linear_model.LinearRegression()import pylab as pl
pl.figure()
np.random.seed(0)for _ in range(6):
? this_X = .1*np.random.normal(size=(2,1)) + X
? regr.fit(this_X,y)
? pl.plot(test,regr.predict(test))
? pl.scatter(this_X,y,s=3) ?
高维统计学习的一个解决方案是将回归系数缩小到0:观测数据中随机选择的两个数据集近似不相关。这被称为岭回归(Ridge Regression): regr = linear_model.Ridge(alpha=.1)
pl.figure()
np.random.seed(0)for _ in range(6):
? this_X = .1*np.random.normal(size=(2,s=3)
这是一个偏差/方差(bias/variance)的权衡:岭α参数越大,偏差(bias)越大,方差(variance)越小 我们可以选择α以最小化排除错误,这里使用糖尿病数据集而不是人为制造的数据: alphas = np.logspace(-4,-1,6)from __future__ import print_functionprint([regr.set_params(alpha=alpha
? ? ? ? ? ?).fit(diabetes_X_train,diabetes_y_train,? ? ? ? ? ?).score(diabetes_X_test,diabetes_y_test) for alpha in alphas])
【注意】扑捉拟合参数的噪声使得模型不能推广到新的数据被称为过拟合。岭回归造成的偏差被称为正则化(归整化,regularization) 稀疏性: 【注意】整个糖尿病数据包含11维数据( 我们可以看到,尽管特征2在整个模型中占据很大的系数,但是和特征1相比,对结果y造成的影响很小。 为了提升问题的状况(考虑到高维灾难),只选择信息含量较大的(对结果y造成的影响较大的)的特征,不选择信息含量较小的特征会很有趣,如把特征2的系数调到0.岭回归将会减少信息含量较小的系数的值,而不是把它们设置为0.另一种抑制措施——Lasso(最小绝对收缩和选择算子)可以使得一些参数为0.这些方法被称作稀疏方法。系数操作可以看作是奥卡姆的剃刀:模型越简单越好。 regr = linear_model.Lasso()
scores = [regr.set_params(alpha=alpha
? ? ? ? ? ?).fit(diabetes_X_train,diabetes_y_train
? ? ? ? ? ?).score(diabetes_X_test,diabetes_y_test) ? ? ?
针对相同问题的不同算法:
logistic = linear_model.LogisticRegression(C=1e5)
logistic.fit(iris_X_train,iris_y_train)
这就是有名的logistic回归。
通过Logistic回归进行收缩和稀疏: 在LogisticRegression对象中C参数控制着正则化的数量:C越大,正则化数目越少。penalty= "12" 提供收缩(非稀疏化系数),penalty="11"提供稀疏化。 练习: from sklearn import datasets,neighbors,linear_model
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
【完整代码】 from sklearn import datasets,linear_model
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
n_samples = len(X_digits)
X_train = X_digits[:.9 * n_samples]
y_train = y_digits[:.9 * n_samples]
X_test = X_digits[.9 * n_samples:]
y_test = y_digits[.9 * n_samples:]
knn = neighbors.KNeighborsClassifier()
logistic = linear_model.LogisticRegression()print('KNN score: %f' % knn.fit(X_train,y_train).score(X_test,y_test))print('LogisticRegression score: %f'
? ? ?% logistic.fit(X_train,y_test))
(3)支持向量机(SVMs)线性SVNs:
样例:Plot different SVM分类器 iris数据集 SVMs能够被用于回归——SVR(支持向量回归)—用于分类——SVC(支持向量分类) 使用核函数:
svc = svm.SVC(kernel='rbf')
交互式样例: 练习: 尝试使用SVMs根据iris数据集前两个特征将其分成两类。留出每一类的10%作为测试样例。 iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y != 0,:2]
y = y[y != 0]
完整代码: """================================SVM Exercise================================A tutorial exercise for using different SVM kernels.This exercise is used in the :ref:`using_kernels_tut` part of the:ref:`supervised_learning_tut` section of the :ref:`stat_learn_tut_index`."""print(__doc__)import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasets,svm
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y != 0,:2]
y = y[y != 0]
n_sample = len(X)
np.random.seed(0)
order = np.random.permutation(n_sample)
X = X[order]
y = y[order].astype(np.float)
X_train = X[:.9 * n_sample]
y_train = y[:.9 * n_sample]
X_test = X[.9 * n_sample:]
y_test = y[.9 * n_sample:]# fit the modelfor fig_num,kernel in enumerate(('linear','rbf','poly')):
? ?clf = svm.SVC(kernel=kernel,gamma=10)
? ?clf.fit(X_train,y_train)
? ?plt.figure(fig_num)
? ?plt.clf()
? ?plt.scatter(X[:,0],X[:,1],c=y,zorder=10,cmap=plt.cm.Paired) ? ?# Circle out the test data
? ?plt.scatter(X_test[:,X_test[:,s=80,facecolors='none',zorder=10)
? ?plt.axis('tight')
? ?x_min = X[:,0].min()
? ?x_max = X[:,0].max()
? ?y_min = X[:,1].min()
? ?y_max = X[:,1].max()
? ?XX,YY = np.mgrid[x_min:x_max:200j,y_min:y_max:200j]
? ?Z = clf.decision_function(np.c_[XX.ravel(),YY.ravel()]) ? ?# Put the result into a color plot
? ?Z = Z.reshape(XX.shape)
? ?plt.pcolormesh(XX,YY,Z > 0,cmap=plt.cm.Paired)
? ?plt.contour(XX,Z,colors=['k','k','k'],linestyles=['--','-','--'],? ? ? ? ? ? ? ?levels=[-.5,0,.5])
? ?plt.title(kernel)
plt.show()
三、模型选择:选择模型和他们的参数(1)分数,和交叉验证分数众所周知,每一个模型会得出一个score方法用于裁决模型在新的数据上拟合的质量。其值越大越好。 from sklearn import datasets,svm
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
svc = svm.SVC(C=1,kernel='linear')
svc.fit(X_digits[:-100],y_digits[:-100]).score(X_digits[-100:],y_digits[-100:])
为了获得一个更好的预测精确度度量,我们可以把我们使用的数据折叠交错地分成训练集和测试集: import numpy as np
X_folds = np.array_split(X_digits,3)
y_folds = np.array_split(y_digits,3)
scores = list()for k in range(3): ? ?# We use 'list' to copy,in order to 'pop' later on
? ?X_train = list(X_folds)
? ?X_test ?= X_train.pop(k)
? ?X_train = np.concatenate(X_train)
? ?y_train = list(y_folds)
? ?y_test ?= y_train.pop(k)
? ?y_train = np.concatenate(y_train)
? ?scores.append(svc.fit(X_train,y_test))print(scores)
这被称为KFold交叉验证 (2)交叉验证生成器上面将数据划分为训练集和测试集的代码写起来很是沉闷乏味。scikit-learn为此自带了交叉验证生成器以生成目录列表: from sklearn import cross_validation
k_fold = cross_validation.KFold(n=6,n_folds=3)for train_indices,test_indices in k_fold: ? ? print('Train: %s | test: %s' % (train_indices,test_indices))
接着交叉验证就可以很容易实现了: kfold = cross_validation.KFold(len(X_digits),n_folds=3)
[svc.fit(X_digits[train],y_digits[train]).score(X_digits[test],y_digits[test]) ? ? ? ? for train,test in kfold]
为了计算一个模型的score,scikit-learn自带了一个帮助函数: cross_validation.cross_val_score(svc,X_digits,y_digits,cv=kfold,n_jobs=-1)
交叉验证生成器: 练习: import numpy as npfrom sklearn import cross_validation,datasets,svm
digits = datasets.load_digits()
X = digits.data
y = digits.target
svc = svm.SVC(kernel='linear')
C_s = np.logspace(-10,10)
完整代码: (3)网格搜索和交叉验证模型网格搜索: from sklearn.grid_search import GridSearchCV
Cs = np.logspace(-6,10)
clf = GridSearchCV(estimator=svc,param_grid=dict(C=Cs),? ? ? ? ? ? ? ? ? n_jobs=-1)
clf.fit(X_digits[:1000],y_digits[:1000]) ? ? ? ?
clf.best_score_ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
clf.best_estimator_.C ? ? ? ? ? ? ? ? ? ? ? ? ? ?# Prediction performance on test set is not as good as on train setclf.score(X_digits[1000:],y_digits[1000:]) ? ? ?
默认情况下, cross_validation.cross_val_score(clf,y_digits) 两个交叉验证循环是并行执行的:一个 【警告】你不能在并行计算时嵌套对象( 交叉验证估测: from sklearn import linear_model,datasets
lasso = linear_model.LassoCV()
diabetes = datasets.load_diabetes()
X_diabetes = diabetes.data
y_diabetes = diabetes.target
lasso.fit(X_diabetes,y_diabetes)# The estimator chose automatically its lambda:lasso.alpha_
这些模型的称呼和他们的对应模型很相似,只是在他们模型名字的后面加上了' 练习:
``` 四、无监督学习:寻找数据的代表(1)聚类:将观测样例聚集到一起聚类解决的问题:
from sklearn import cluster,datasets
iris = datasets.load_iris()
X_iris = iris.data
y_iris = iris.target
k_means = cluster.KMeans(n_clusters=3)
k_means.fit(X_iris)
print(k_means.labels_[::10])print(y_iris[::10])
注意:没有绝对的保证能够恢复真实的分类。首先,尽管scikit-learn使用很多技巧来缓和问题的难度,但选择簇的个数还是是很困难的,初始状态下算法是很敏感的,可能会陷入局部最小。 8个簇: 真实情况: 不要“过解释”聚类结果 应用实例:矢量化 import scipy as sptry:
? lena = sp.lena()except AttributeError: ? from scipy import misc
? lena = misc.lena()
X = lena.reshape((-1,1)) # We need an (n_sample,n_feature) arrayk_means = cluster.KMeans(n_clusters=5,n_init=1)
k_means.fit(X)
values = k_means.cluster_centers_.squeeze()
labels = k_means.labels_
lena_compressed = np.choose(labels,values)
lena_compressed.shape = lena.shape
原始图像: K-means矢量化: 等段:(Equal bins) 图像直方图:
特征凝聚: digits = datasets.load_digits()
images = digits.images
X = np.reshape(images,(len(images),-1))
connectivity = grid_to_graph(*images[0].shape)
agglo = cluster.FeatureAgglomeration(connectivity=connectivity,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? n_clusters=32)
agglo.fit(X)
X_reduced = agglo.transform(X)
X_approx = agglo.inverse_transform(X_reduced)
images_approx = np.reshape(X_approx,images.shape)
(2)分解:从一个信号到成分和加载成分及其加载:
上面观测样例的点分布在一个方向上是非常平坦的:三个特征单变量的一个甚至可以有其他两个准确的计算出来。PCA用来发现数据在哪个方向上是不平坦的。 当被用来转换数据的时候,PCA可以通过投射到一个主子空间来降低数据的维度。: # Create a signal with only 2 useful dimensionsx1 = np.random.normal(size=100)
x2 = np.random.normal(size=100)
x3 = x1 + x2
X = np.c_[x1,x2,x3]from sklearn import decomposition
pca = decomposition.PCA()
pca.fit(X)print(pca.explained_variance_) ?# As we can see,only the 2 first components are usefulpca.n_components = 2X_reduced = pca.fit_transform(X)
X_reduced.shape
五、联合起来(1)管道(流水线)我们已经知道了一些估测器(模型)能够转换数据,一些可以预测变量。我们也能够将其结合到一起: from sklearn import linear_model,decomposition,datasetsfrom sklearn.pipeline import Pipelinefrom sklearn.grid_search import GridSearchCV
logistic = linear_model.LogisticRegression()
pca = decomposition.PCA()
pipe = Pipeline(steps=[('pca',pca),('logistic',logistic)])
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target################################################################################ Plot the PCA spectrumpca.fit(X_digits)
plt.figure(1,figsize=(4,3))
plt.clf()
plt.axes([.2,.2,.7,.7])
plt.plot(pca.explained_variance_,linewidth=2)
plt.axis('tight')
plt.xlabel('n_components')
plt.ylabel('explained_variance_')################################################################################ Predictionn_components = [20,40,64]
Cs = np.logspace(-4,4,3)
(2)使用特征联进行人脸识别? ?该实例使用的数据集是从“Labeled Faces in the Wild”节选预处理得到的。更为熟知的名字是LFW。
http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz(233 MB) 六、寻求帮助###(1)项目邮件列表 (2)问答(Q&A)机器学习从业者参与的社区
数据挖掘入门与实战 搜索添加微信公众号:datadw 教你机器学习,教你数据挖掘 长按图片,识别二维码,点关注 ? 公众号: weic2c? ? 长按图片,识别二维码,点关注 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |