文章中大部分例子的代码
参考文档:
安装
pip install -U scikit-learn
从一个例子开始
使用 SVM 分类手写数字。
数据特征
sklearn
本身提供了一些数据集,比如手写数字、鸢尾花、糖尿病人特征,还为一些较大数据集提供了下载接口。你还可以在skimage
中发现更多图像数据。
sklearn
的数据集最基本的属性是 data 和 target,也就是特征集和目标集。
特征集是一个(n_samples, n_features)的ndarray,目标集是一个(n_samples,)的ndarray(可以是多维,一般视作多标签)。
比如我们要用的digits的data(X)就是一个64位的int数组,表示每一个像素的灰度。target自然就是对应的数字。
from sklearn import datasets
digits = datasets.load_digits()
digits_X_y=(digits.data,digits.target)
estimator
sklearn
的分类器、回归器等等,以及各种数据处理处理器都属于这个类。比如SVM classifier。其fit(X,y)
方法用来在数据集上训练
from sklearn import svm
clf = svm.SVC(gamma=0.001,C=100.)
clf.fit(*digits_X_y)
predicate(X)
用来预测数据
clf.predict(digits.data[-3:])
超参数可以在新建对象时设置,也可以通过set_params
方法重设,不过重设完需要再训练一遍。
clf.set_params(C=10.).fit(*digits_X_y)
训练好的 estimator 可以用 python 自带的pickle或joblib进行持久化。处理大量数据时,joblib表现更优秀一些。
What are the different use cases of joblib versus pickle? - Stack Overflow
import pickle
s = pickle.dumps(clf)
多标签
你可以将目标集进行二值化,这样分类器就会默认进行多标签分类。
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import MultiLabelBinarizer
X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]
y = [0, 0, 1, 1, 2]
clf = OneVsRestClassifier(estimator=SVC(random_state=0))
clf.fit(X, y).predict(X)
# out:
# [0,0,1,1,2]
y = LabelBinarizer().fit_transform(y)
clf.fit(X, y).predict(X)
"""
array([[1, 0, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 0]])
"""
监督学习
分类
- 以下展示了使用 KNN 算法进行分类的例子。
from sklearn.neighbors import KNeighborsClassifier
iris = datasets.load_iris()
iris_X = iris.data
iris_y = iris.target
# divide data set into test_set and train_set
np.random.seed(1926)
indices = np.random.permutation(len(iris_X))
iris_X_train = iris_X[indices[:-10]]
iris_y_train = iris_y[indices[:-10]]
iris_X_test = iris_X[indices[-10:]]
iris_y_test = iris_y[indices[-10:]]
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(iris_X_train,iris_y_train)
print(knn.predict(iris_X_test),iris_y_test)
"""
(array([0, 1, 2, 0, 1, 0, 2, 1, 2, 2]),
array([0, 2, 2, 0, 1, 0, 2, 1, 2, 2]))
"""
在实际使用中,我们不能用训练的数据对模型进行测试,所以一般将数据分为测试集和训练集。
除了上面演示的手动伪随机分类,sklearn
其实提供了分类接口train_test_split
。
# 分割 25% 的数据作为测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
很多
sklearn
实现的算法都有随机成分,要使这些算法结果能复现,务必手设random_state
。
- 使用 SVM, 通过前两种特征区分两种鸢尾花
iris = datasets.load_iris()
iris_X = iris.data[iris.target != 0][:,(0,1)]
iris_y = iris.target[iris.target != 0]
# try different kernels
clf = SVC(C=100.,kernel="linear")
clf.fit(iris_X,iris_y)
# visualization
可以尝试不同的kernel参数。
回归
线性回归
线性回归模型:
\[$$\hat{y}(w, x) = w_0 + w_1 x_1 + ... + w_p x_p $$ \]其中$$$$w = (w_1, ..., w_p) $$$$是系数 coef_
,$$$$w_0 $$$$是截距 intercept_
- 使用线性回归预测糖尿病情况的例子:
# load data set
diabetes = datasets.load_diabetes()
diabetes_X_train,diabetes_X_test,diabetes_y_train,diabetes_y_test = train_test_split(
diabetes.data,diabetes.target,test_size=20
)
from sklearn import linear_model
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train,diabetes_y_train)
print(regr.coef_)
普通的线性回归受数据方差影响较大,而且容易过拟合。sklearn
还提供了岭回归和lasso回归。
岭回归
在普通最小二乘法的基础上设置了惩罚参数$$$$\alpha $$$$,损失函数为
\[$$\min_{w} || X w - y||^2 + \alpha ||w||^2 $$ \]>>> from sklearn import linear_model
>>> reg = linear_model.Ridge (alpha = .5) # 设置alpha
>>> reg.fit ([[0, 0], [0, 0], [1, 1]], [0, .1, 1])
Ridge(alpha=0.5, copy_X=True, fit_intercept=True, max_iter=None,
normalize=False, random_state=None, solver='auto', tol=0.001)
>>> reg.coef_
array([ 0.34545455, 0.34545455])
>>> reg.intercept_
0.13636...
设置较大的$$$$\alpha $$$$,可以使权重绝对值减小
贝叶斯岭回归通过概率模型估算 alpha 等先验参数,因此不需要手动指定,但其推断非常耗时。
使用 BayesianRidge
类即可。
Lasso 回归
与岭回归非常类似,最小化的是
\[$$\min_{w} { \frac{1}{2n_{\text{samples}}} ||X w - y|| ^ 2 + \alpha |w|} $$ \]from sklearn import linear_model
reg = linear_model.Lasso(alpha = 0.1)
reg.fit([[0, 0], [1, 1]], [0, 1])
print(reg.coef_)
print(reg.intercept_)
print(reg.predict([[1, 1]]))
'''
[0.6 0. ]
0.2
[0.8]
'''
可以使用交叉验证来确定 alpha 较好的取值。
Lasso
类使用坐标下降算法,而 LassoLars
使用最小角回归,可以得到精确解,但对噪声非常敏感。
弹性网络
是对岭回归和 Lasso 的结合,函数为
\[$$\min_{w} { \frac{1}{2n_{\text{samples}}} ||X w - y|| ^ 2 + \alpha \rho |w| + \frac{\alpha(1-\rho)}{2} ||w|| ^ 2} $$ \]其中新参数$$$$\rho $$$$表示 L1 范数(即绝对值)的比例,在代码中称为 l1_ratio。
from sklearn import linear_model
reg = linear_model.ElasticNet(alpha = 0.1, l1_ratio = 0.7)
reg.fit([[0, 0], [1, 1]], [0, 1])
print(reg.coef_)
print(reg.intercept_)
print(reg.predict([[1, 1]]))
'''
[0.33973141 0.33952552]
0.1603715314203198
[0.83962847]
'''
对于惩罚项的探讨可以看Fyx
- 用例:diabetes数据集的前两个参数,其中一个明显对回归影响较小。我们可以通过lasso回归进行系数收缩(稀疏化)。
- 使用 diabetes 前两个参数进行回归
from sklearn.linear_model import Lasso
regr = Lasso()
# select best hyper-param
alphas = np.linspace(1,0,num=20,endpoint=False)
scores = [regr.set_params(alpha = alpha
).fit(diabetes_X_train,diabetes_y_train
).score(diabetes_X_test,diabetes_y_test)
for alpha in alphas ]
best_alpha = alphas[scores.index(max(scores))]
regr.set_params(alpha = best_alpha).fit(diabetes_X_train,diabetes_y_train)
print(regr.coef_)
logistic regression
也就是套了个sigmoid函数的线性回归,我们可以用它来做分类:
log = LogisticRegression(C=1e5)
log.fit(iris_X,iris_y)
print(log.predict(iris_X[::50]),iris_y[::50])
"""
[0,1,2] [0,1,2]
"""
模型评估
sklearn
的estimator基本都有score
接口,返回决定系数,可以用来评估模型准确度。
sklearn
还提供了一堆交叉验证方法,比如最简单的K折验证:
from sklearn.model_selection import KFold,cross_val_score
k_fold = KFold(n_splits=3)
[svc.fit(X_digits[train],y_digits[train]
).score(X_digits[test],y_digits[test])
for train,test in k_fold.split(X_digits)]
或者你可以直接生成交叉验证分数数组:
cross_val_score(svc,X_digits,y_digits,cv=k_fold,n_jobs=1)
基本上在类后加上CV就是该类的交叉验证器(比如LassoCV
),可以通过其寻找最佳参数(就相对于上面lasso回归手找alpha的过程)。
sklearn
还提供了一个通用的参数选择器GridSearchCV
:
from sklearn import datasets
from sklearn.linear_model import Lasso
from sklearn.model_selection import GridSearchCV
X,y = datasets.load_diabetes(return_X_y=True)
X = X[:150]
y = y[:150]
lasso = Lasso(random_state=0,max_iter=1e4)
alphas = np.logspace(-4,-0.5,30)
grid_params = [{'alpha':alphas}]
n_folds = 5
regr = GridSearchCV(lasso,grid_params,cv=n_folds)
regr.fit(X,y) # 对于CV,fit方法就是搜索参数过程
scores = regr.cv_results_["mean_test_score"]
scores_std = regr.cv_results_["std_test_score"]
print(regr.best_params_)
通过scores和scores_std画出的alpha-score图像:
测试极大依赖于数据集,所以并不一定可靠。
无监督学习
聚类
- 通过 k-means 对鸢尾花进行聚类的例子:
k_means = cluster.KMeans(n_clusters=3)
k_means.fit(X_iris)
print(k_means.labels_[::10])
print(y_iris[::10])
"""
[1 1 1 1 1 0 0 0 0 0 2 2 2 2 2]
[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2]
"""
- Vector Quantization
- 通过聚类对图片信息进行压缩
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from sklearn import cluster
try:
from scipy.misc import face
face = face(gray=True)
except ImportError:
face = sp.face(gray=True)
n_clusters = 5
np.random.seed(0)
X = face.reshape((-1, 1)) # We need an (n_sample, n_feature) array
k_means = cluster.KMeans(n_clusters=n_clusters, n_init=4)
k_means.fit(X)
values = k_means.cluster_centers_.squeeze()
labels = k_means.labels_
# create an array from labels and values
face_compressed = np.choose(labels, values)
face_compressed.shape=face.shape
- 灰度图:算法将数据都聚到了五个灰度上。
- 分层聚集聚类
from skimage.data import coins
import numpy as np
import matplotlib.pyplot as plt
coins_mat = coins()
X = np.reshape(coins_mat,(-1,1))
from sklearn.feature_extraction import grid_to_graph
from sklearn.cluster import AgglomerativeClustering
connectivity = grid_to_graph(*coins_mat.shape) # 这是一个描述像素点邻接情况的spare matrix
n_clusters = 27 #簇的数量
ward = AgglomerativeClustering(n_clusters=n_clusters, linkage='ward',
connectivity=connectivity)
ward.fit(X)
- 处理前后:
特征聚集
试想,如果我们将数据集进行转置,就相当于把features当作了样本。
在转置的数据集上进行聚类可以减少特征数,是一种简单的降维方法。
from sklearn import datasets
from sklearn.cluster import FeatureAgglomeration
from sklearn.feature_extraction.image import grid_to_graph
digits = datasets.load_digits()
images = digits.images
X = np.reshape(images,(len(images),-1))
connectivity = grid_to_graph(*images[0].shape)
agglo = FeatureAgglomeration(connectivity=connectivity,n_clusters=32)
agglo.fit(X)
# X_reduced 是变换后,也就是降维后的数据集
# X_approx 是将变换后的数据以原来测度表示
X_reduced = agglo.transform(X)
X_approx = agglo.inverse_transform(X_reduced)
images_approx = np.reshape(X_approx,images.shape)
特征聚集模式:一些像素部分被合并考虑。
不要过度解读聚类的结果。
分解
PCA
使用 PCA 可以将数据投影到低维:
import numpy as np
from sklearn import decomposition
x1 = np.random.normal(size=100)
x2 = np.random.normal(size=100)
x3 = x1 + x2
X = np.c_[x1,x2,x3]
pca = decomposition.PCA(n_components='mle')
pca.fit(X)
X_pca = pca.transform(X)
X_pca.shape
其中,n_components
参数为-1或none时,只进行变换,保留所有特征,为int则保留相应数量特征,‘mle’则自动保留合适的特征。
你可以查看各个特征的方差,自行舍弃。
ICA
你可以使用 ICA 从混合数据中提取独立的特征。
假设原特征矩阵 $$$$S$$$$,混合数据矩阵 $$$$X$$$$。有变换使得 $$$$X=AS$$$$。ICA 可以通过 $$$$X$$$$ 求得 $$$$S'$$$$ 和 $$$$A'$$$$(当然不一定是原来的,只是一组独立的特征)。
# 计算ICA
ica = decomposition.FastICA()
S_ = ica.fit_transform(X) # 得到预测结果
A_ = ica.mixing_.T
管道
对于复杂的模型,sklearn
支持组合各类estimator。
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.decomposition import PCA
pca = PCA()
log = LogisticRegression(max_iter=1e4)
pipe = Pipeline(steps=[('decomposition',pca),('regression',log)])
比如这就是一个数据处理和回归器的组合,按理只要是 estimator 就可以往管道里塞,pipeline 会和最后一个estimator类型相同。上面这个管道就可以作为一个回归器。
对pipeline使用GridSearchCV
的例子:
from sklearn import datasets
from sklearn.model_selection import GridSearchCV
X_digits, y_digits = datasets.load_digits(return_X_y=True)
# 使用 __ 分隔的参数名称来设置管道的参数:
param_grid = {
'decomposition__n_components': [5, 15, 30, 45, 64],
'regression__C': np.logspace(-4, 4, 4),
}
search = GridSearchCV(estimator=pipe,param_grid=param_grid,n_jobs=-1)
search.fit(X_digits,y_digits)
print(search.best_params_)
更多例子?
官方提供了许多实际例子,可以尝试尝试。文章中大部分例子的代码
参考文档:
安装
pip install -U scikit-learn
从一个例子开始
使用 SVM 分类手写数字。
数据特征
sklearn
本身提供了一些数据集,比如手写数字、鸢尾花、糖尿病人特征,还为一些较大数据集提供了下载接口。你还可以在skimage
中发现更多图像数据。
sklearn
的数据集最基本的属性是 data 和 target,也就是特征集和目标集。
特征集是一个(n_samples, n_features)的ndarray,目标集是一个(n_samples,)的ndarray(可以是多维,一般视作多标签)。
比如我们要用的digits的data(X)就是一个64位的int数组,表示每一个像素的灰度。target自然就是对应的数字。
from sklearn import datasets
digits = datasets.load_digits()
digits_X_y=(digits.data,digits.target)
estimator
sklearn
的分类器、回归器等等,以及各种数据处理处理器都属于这个类。比如SVM classifier。其fit(X,y)
方法用来在数据集上训练
from sklearn import svm
clf = svm.SVC(gamma=0.001,C=100.)
clf.fit(*digits_X_y)
predicate(X)
用来预测数据
clf.predict(digits.data[-3:])
超参数可以在新建对象时设置,也可以通过set_params
方法重设,不过重设完需要再训练一遍。
clf.set_params(C=10.).fit(*digits_X_y)
训练好的 estimator 可以用 python 自带的pickle或joblib进行持久化。处理大量数据时,joblib表现更优秀一些。
What are the different use cases of joblib versus pickle? - Stack Overflow
import pickle
s = pickle.dumps(clf)
多标签
你可以将目标集进行二值化,这样分类器就会默认进行多标签分类。
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import MultiLabelBinarizer
X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]
y = [0, 0, 1, 1, 2]
clf = OneVsRestClassifier(estimator=SVC(random_state=0))
clf.fit(X, y).predict(X)
# out:
# [0,0,1,1,2]
y = LabelBinarizer().fit_transform(y)
clf.fit(X, y).predict(X)
"""
array([[1, 0, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 0]])
"""
监督学习
分类
- 以下展示了使用 KNN 算法进行分类的例子。
from sklearn.neighbors import KNeighborsClassifier
iris = datasets.load_iris()
iris_X = iris.data
iris_y = iris.target
# divide data set into test_set and train_set
np.random.seed(1926)
indices = np.random.permutation(len(iris_X))
iris_X_train = iris_X[indices[:-10]]
iris_y_train = iris_y[indices[:-10]]
iris_X_test = iris_X[indices[-10:]]
iris_y_test = iris_y[indices[-10:]]
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(iris_X_train,iris_y_train)
print(knn.predict(iris_X_test),iris_y_test)
"""
(array([0, 1, 2, 0, 1, 0, 2, 1, 2, 2]),
array([0, 2, 2, 0, 1, 0, 2, 1, 2, 2]))
"""
在实际使用中,我们不能用训练的数据对模型进行测试,所以一般将数据分为测试集和训练集。
除了上面演示的手动伪随机分类,sklearn
其实提供了分类接口train_test_split
。
# 分割 25% 的数据作为测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
很多
sklearn
实现的算法都有随机成分,要使这些算法结果能复现,务必手设random_state
。
- 使用 SVM, 通过前两种特征区分两种鸢尾花
iris = datasets.load_iris()
iris_X = iris.data[iris.target != 0][:,(0,1)]
iris_y = iris.target[iris.target != 0]
# try different kernels
clf = SVC(C=100.,kernel="linear")
clf.fit(iris_X,iris_y)
# visualization
可以尝试不同的kernel参数。
回归
线性回归
线性回归模型:
\[$$\hat{y}(w, x) = w_0 + w_1 x_1 + ... + w_p x_p $$ \]其中$$$$w = (w_1, ..., w_p) $$$$是系数 coef_
,$$$$w_0 $$$$是截距 intercept_
- 使用线性回归预测糖尿病情况的例子:
# load data set
diabetes = datasets.load_diabetes()
diabetes_X_train,diabetes_X_test,diabetes_y_train,diabetes_y_test = train_test_split(
diabetes.data,diabetes.target,test_size=20
)
from sklearn import linear_model
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train,diabetes_y_train)
print(regr.coef_)
普通的线性回归受数据方差影响较大,而且容易过拟合。sklearn
还提供了岭回归和lasso回归。
岭回归
在普通最小二乘法的基础上设置了惩罚参数$$$$\alpha $$$$,损失函数为
\[$$\min_{w} || X w - y||^2 + \alpha ||w||^2 $$ \]>>> from sklearn import linear_model
>>> reg = linear_model.Ridge (alpha = .5) # 设置alpha
>>> reg.fit ([[0, 0], [0, 0], [1, 1]], [0, .1, 1])
Ridge(alpha=0.5, copy_X=True, fit_intercept=True, max_iter=None,
normalize=False, random_state=None, solver='auto', tol=0.001)
>>> reg.coef_
array([ 0.34545455, 0.34545455])
>>> reg.intercept_
0.13636...
设置较大的$$$$\alpha $$$$,可以使权重绝对值减小
贝叶斯岭回归通过概率模型估算 alpha 等先验参数,因此不需要手动指定,但其推断非常耗时。
使用 BayesianRidge
类即可。
Lasso 回归
与岭回归非常类似,最小化的是
\[$$\min_{w} { \frac{1}{2n_{\text{samples}}} ||X w - y|| ^ 2 + \alpha |w|} $$ \]from sklearn import linear_model
reg = linear_model.Lasso(alpha = 0.1)
reg.fit([[0, 0], [1, 1]], [0, 1])
print(reg.coef_)
print(reg.intercept_)
print(reg.predict([[1, 1]]))
'''
[0.6 0. ]
0.2
[0.8]
'''
可以使用交叉验证来确定 alpha 较好的取值。
Lasso
类使用坐标下降算法,而 LassoLars
使用最小角回归,可以得到精确解,但对噪声非常敏感。
弹性网络
是对岭回归和 Lasso 的结合,函数为
\[$$\min_{w} { \frac{1}{2n_{\text{samples}}} ||X w - y|| ^ 2 + \alpha \rho |w| + \frac{\alpha(1-\rho)}{2} ||w|| ^ 2} $$ \]其中新参数$$$$\rho $$$$表示 L1 范数(即绝对值)的比例,在代码中称为 l1_ratio。
from sklearn import linear_model
reg = linear_model.ElasticNet(alpha = 0.1, l1_ratio = 0.7)
reg.fit([[0, 0], [1, 1]], [0, 1])
print(reg.coef_)
print(reg.intercept_)
print(reg.predict([[1, 1]]))
'''
[0.33973141 0.33952552]
0.1603715314203198
[0.83962847]
'''
对于惩罚项的探讨可以看Fyx
- 用例:diabetes数据集的前两个参数,其中一个明显对回归影响较小。我们可以通过lasso回归进行系数收缩(稀疏化)。
- 使用 diabetes 前两个参数进行回归
from sklearn.linear_model import Lasso
regr = Lasso()
# select best hyper-param
alphas = np.linspace(1,0,num=20,endpoint=False)
scores = [regr.set_params(alpha = alpha
).fit(diabetes_X_train,diabetes_y_train
).score(diabetes_X_test,diabetes_y_test)
for alpha in alphas ]
best_alpha = alphas[scores.index(max(scores))]
regr.set_params(alpha = best_alpha).fit(diabetes_X_train,diabetes_y_train)
print(regr.coef_)
logistic regression
也就是套了个sigmoid函数的线性回归,我们可以用它来做分类:
log = LogisticRegression(C=1e5)
log.fit(iris_X,iris_y)
print(log.predict(iris_X[::50]),iris_y[::50])
"""
[0,1,2] [0,1,2]
"""
模型评估
sklearn
的estimator基本都有score
接口,返回决定系数,可以用来评估模型准确度。
sklearn
还提供了一堆交叉验证方法,比如最简单的K折验证:
from sklearn.model_selection import KFold,cross_val_score
k_fold = KFold(n_splits=3)
[svc.fit(X_digits[train],y_digits[train]
).score(X_digits[test],y_digits[test])
for train,test in k_fold.split(X_digits)]
或者你可以直接生成交叉验证分数数组:
cross_val_score(svc,X_digits,y_digits,cv=k_fold,n_jobs=1)
基本上在类后加上CV就是该类的交叉验证器(比如LassoCV
),可以通过其寻找最佳参数(就相对于上面lasso回归手找alpha的过程)。
sklearn
还提供了一个通用的参数选择器GridSearchCV
:
from sklearn import datasets
from sklearn.linear_model import Lasso
from sklearn.model_selection import GridSearchCV
X,y = datasets.load_diabetes(return_X_y=True)
X = X[:150]
y = y[:150]
lasso = Lasso(random_state=0,max_iter=1e4)
alphas = np.logspace(-4,-0.5,30)
grid_params = [{'alpha':alphas}]
n_folds = 5
regr = GridSearchCV(lasso,grid_params,cv=n_folds)
regr.fit(X,y) # 对于CV,fit方法就是搜索参数过程
scores = regr.cv_results_["mean_test_score"]
scores_std = regr.cv_results_["std_test_score"]
print(regr.best_params_)
通过scores和scores_std画出的alpha-score图像:
测试极大依赖于数据集,所以并不一定可靠。
无监督学习
聚类
- 通过 k-means 对鸢尾花进行聚类的例子:
k_means = cluster.KMeans(n_clusters=3)
k_means.fit(X_iris)
print(k_means.labels_[::10])
print(y_iris[::10])
"""
[1 1 1 1 1 0 0 0 0 0 2 2 2 2 2]
[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2]
"""
- Vector Quantization
- 通过聚类对图片信息进行压缩
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from sklearn import cluster
try:
from scipy.misc import face
face = face(gray=True)
except ImportError:
face = sp.face(gray=True)
n_clusters = 5
np.random.seed(0)
X = face.reshape((-1, 1)) # We need an (n_sample, n_feature) array
k_means = cluster.KMeans(n_clusters=n_clusters, n_init=4)
k_means.fit(X)
values = k_means.cluster_centers_.squeeze()
labels = k_means.labels_
# create an array from labels and values
face_compressed = np.choose(labels, values)
face_compressed.shape=face.shape
- 灰度图:算法将数据都聚到了五个灰度上。
- 分层聚集聚类
from skimage.data import coins
import numpy as np
import matplotlib.pyplot as plt
coins_mat = coins()
X = np.reshape(coins_mat,(-1,1))
from sklearn.feature_extraction import grid_to_graph
from sklearn.cluster import AgglomerativeClustering
connectivity = grid_to_graph(*coins_mat.shape) # 这是一个描述像素点邻接情况的spare matrix
n_clusters = 27 #簇的数量
ward = AgglomerativeClustering(n_clusters=n_clusters, linkage='ward',
connectivity=connectivity)
ward.fit(X)
- 处理前后:
特征聚集
试想,如果我们将数据集进行转置,就相当于把features当作了样本。
在转置的数据集上进行聚类可以减少特征数,是一种简单的降维方法。
from sklearn import datasets
from sklearn.cluster import FeatureAgglomeration
from sklearn.feature_extraction.image import grid_to_graph
digits = datasets.load_digits()
images = digits.images
X = np.reshape(images,(len(images),-1))
connectivity = grid_to_graph(*images[0].shape)
agglo = FeatureAgglomeration(connectivity=connectivity,n_clusters=32)
agglo.fit(X)
# X_reduced 是变换后,也就是降维后的数据集
# X_approx 是将变换后的数据以原来测度表示
X_reduced = agglo.transform(X)
X_approx = agglo.inverse_transform(X_reduced)
images_approx = np.reshape(X_approx,images.shape)
特征聚集模式:一些像素部分被合并考虑。
不要过度解读聚类的结果。
分解
PCA
使用 PCA 可以将数据投影到低维:
import numpy as np
from sklearn import decomposition
x1 = np.random.normal(size=100)
x2 = np.random.normal(size=100)
x3 = x1 + x2
X = np.c_[x1,x2,x3]
pca = decomposition.PCA(n_components='mle')
pca.fit(X)
X_pca = pca.transform(X)
X_pca.shape
其中,n_components
参数为-1或none时,只进行变换,保留所有特征,为int则保留相应数量特征,‘mle’则自动保留合适的特征。
你可以查看各个特征的方差,自行舍弃。
ICA
你可以使用 ICA 从混合数据中提取独立的特征。
假设原特征矩阵 $$$$S$$$$,混合数据矩阵 $$$$X$$$$。有变换使得 $$$$X=AS$$$$。ICA 可以通过 $$$$X$$$$ 求得 $$$$S'$$$$ 和 $$$$A'$$$$(当然不一定是原来的,只是一组独立的特征)。
# 计算ICA
ica = decomposition.FastICA()
S_ = ica.fit_transform(X) # 得到预测结果
A_ = ica.mixing_.T
管道
对于复杂的模型,sklearn
支持组合各类estimator。
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.decomposition import PCA
pca = PCA()
log = LogisticRegression(max_iter=1e4)
pipe = Pipeline(steps=[('decomposition',pca),('regression',log)])
比如这就是一个数据处理和回归器的组合,按理只要是 estimator 就可以往管道里塞,pipeline 会和最后一个estimator类型相同。上面这个管道就可以作为一个回归器。
对pipeline使用GridSearchCV
的例子:
from sklearn import datasets
from sklearn.model_selection import GridSearchCV
X_digits, y_digits = datasets.load_digits(return_X_y=True)
# 使用 __ 分隔的参数名称来设置管道的参数:
param_grid = {
'decomposition__n_components': [5, 15, 30, 45, 64],
'regression__C': np.logspace(-4, 4, 4),
}
search = GridSearchCV(estimator=pipe,param_grid=param_grid,n_jobs=-1)
search.fit(X_digits,y_digits)
print(search.best_params_)
更多例子?
官方提供了许多实际例子,可以尝试尝试。
标签:digits,iris,fit,笔记,学习,alpha,import,sklearn From: https://www.cnblogs.com/thornblog/p/16926826.html