分享

5

 LQuan 2018-02-12

Sklean库

  1. sklearn是机器学习中一个常用的python第三方模块,是进行数据挖掘和分析的便捷高效工具。
  2. sklearn对一些常用的机器学习方法进行了封装,在进行机器学习任务时,只需要简单的调用sklearn里的模块就可以实现大多数机器学习任务。
  3. sklearn建立于Numpy、SciPy和Matplotlib的基础上。

要说明的是,在导入sklearn模块时,一般针对想实现的功能导入相应的子模块即可,不需要导入完整的sklearn模块。
在本章中通过例子的形式来讲解某几个子模块下,需要说明的是这里注重的是模块的应用,具体的算法或者原理只做简单陈述

sklearn简易目录

sklearn模块典型算法应用场景
分类支持向量机、近邻算法、随机森林黑色系商品走势的分化,垃圾邮件检测,图像识别
回归岭回归、Lasso回归技术指标择时,股价预测,药物反应
聚类K-means聚类、谱聚类市场中常见压力指标提取,客户分群
降维主成分分析、矩阵分解、特征选择行业有效因子筛选,数据可视化,效率增强
模型选择网格搜索、交叉验证调参改进模型效果,模型评价
预处理预处理、特征提取文本数据处理,数据标准化,结构化

x
import numpy as np

一、预处理

很多模型对数据输入有一定的要求,常常需要在建模前对数据进行预处理

1.1 标准化与规范化

1.2 二值化

1.3 缺失处理

1.4 多项式变型

1
from sklearn import preprocessing

1.1 标准化和正态化

  • 标准化1:将数据转化为均值0,方差1
  • 标准化2:每个数据 - 数据集最小值 / (数据集最大值 - 数据集最小值)
  • 规范化:处理后范数为1
1
X_train = np.array([[ 1., -1., 2.],
原数据: [[ 1. -1. 2.] [ 2. 0. 0.] [ 0. 1. -1.]]
1
print('标准化1:')
标准化1:[[ 0. -1.22474487 1.33630621] [ 1.22474487 0. -0.26726124] [-1.22474487 1.22474487 -1.06904497]]标准化2:[[ 0.5 0. 1. ] [ 1. 0.5 0.33333333] [ 0. 1. 0. ]]规范化:[[ 0.40824829 -0.40824829 0.81649658] [ 1. 0. 0. ] [ 0. 0.70710678 -0.70710678]]

1.2 二值化

1
print('原数据:')
原数据:[[ 1. -1. 2.] [ 2. 0. 0.] [ 0. 1. -1.]]二值化:[[ 1. 0. 1.] [ 1. 0. 0.] [ 0. 1. 0.]]

1.3 缺失处理

1
from sklearn.preprocessing import Imputer
原数据:[[nan, 2], [6, nan], [7, 6]]----------按列均值填充缺失:

1.4 多项式变型

1
X = np.arange(6).reshape(3,2)
原数据:[[0 1] [2 3] [4 5]]多项式转化:(X1, X2)→(1, X1, X2, X1^2, X1X2, X2^2)[[ 1. 0. 1. 0. 0. 1.] [ 1. 2. 3. 4. 6. 9.] [ 1. 4. 5. 16. 20. 25.]]

二、分类

2.1 决策树

2.2 识别手写数字——SVM

2.3 logistic回归

2.1 决策树

决策树是分类中最为基础的算法之一。其核心是依据特征的重要程度,依次使用单个特征进行分类。
下面使用sklearn中自带的一个数据集,演示一个决策树的小例子。
决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。

1
from sklearn.datasets import load_iris #sklearn.datasets中很多可用的数据集
1
iris = load_iris() #导入iris数据集
特征:[[ 5.1 3.5 1.4 0.2] [ 4.9 3. 1.4 0.2] [ 4.7 3.2 1.3 0.2] [ 4.6 3.1 1.5 0.2] [ 5. 3.6 1.4 0.2] [ 5.4 3.9 1.7 0.4] [ 4.6 3.4 1.4 0.3] [ 5. 3.4 1.5 0.2] [ 4.4 2.9 1.4 0.2] [ 4.9 3.1 1.5 0.1]]目标:[0 0 0 0 0 0 0 0 0 0]
1
clf = tree.DecisionTreeClassifier() #可以自己设定很多参数,如果不写则默认参数
对第一条记录的预测类别: [0]第一条记录的实际类别: 0对第一条记录的类别概率预测: [[ 1. 0. 0.]]

决策树的一大好处是可以直观地看到决策树的样子,从而看到分类的整个逻辑。可以利用graphviz和pydotplus库来实现决策树的可视化,这里不做演示。可参考下列代码:
tree.export_graphviz(clf,out_file = dot_data,feature_names=feature_name,class_names=target_name,filled=True,rounded=True,special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf('WineTree.pdf')

2.2 识别手写数字——SVM

图像识别的功能可以从分类的角度来实现。例如,我们希望从一些手写数字的图片,来识别图中的数字到底是哪个数字。可以用SVM分类器来实现

1
from sklearn import datasets, svm

导入和查看数据集digits
可以看到数据集digits中有1797个图片,每个图片的数据维度为8$*$8
利用作图matplotlib库中的imshow函数,可以看到前四个图片,如下所示

1
digits = datasets.load_digits()
1
images_and_labels = list(zip(digits.images, digits.target)) #查看 前四个图形

将特征数据集转化为一个矩阵
原数据集中每个图片(记录)是以一个$8*8$矩阵形式存储的,而在建模过程中不能直接以这样格式的矩阵作为输入,所以对数据集要进行一定的转换
将一个$8*8$的矩阵转化为一个向量来处理

1
n_samples = len(digits.images)
1
digits.images[0] #原数据集第一个记录
1
data[0] #转换后的数据集的第一个记录

利用样本的前一半数据集训练模型(支持向量机),使用训练好的模型对样本的后一半数据集进行预测
查看部分的预测结果。从结果可以看到,模型对这四个记录都预测对了

1
classifier = svm.SVC(gamma=0.001)

2.3 Logistic回归

logistic回归又称logistic回归分析,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域。
Logistic模型用来预测一个分类变量。例如用身高,体重等因子判断一个人为男性(1)还是女性(0)。例如在已知一个人的身高为180cm,65kg时,预测他为男性概率为90%。
不妨设预测目标为$y$,解释变量为$x_1,x_2,...,x_m$,logistic模型可以用如下公式来表达(注意logistic模型是事先规定模型结构的)
$$ln(\frac{Prob(y=1)}{1-Prob(y=1)}) = β_0+β_1*x_1+β_2*x_2+...+β_m*x_m$$或者$$Prob(y=1) = \frac{1}{1+exp(-(β_0+β_1*x_1+β_2*x_2+...+β_m*x_m))}$$
其中$β_0,β_1,...,β_m$为待估计的参数,一般采用极大似然估计MLE来处理。

1
from sklearn import linear_model, datasets
1
iris = datasets.load_iris()

训练模型

1
logreg = linear_model.LogisticRegression(C=1e5)
1
logreg.coef_ #查看模型参数beta的估计

模型预测,构建分类边界

1
h = 0.02 #作图的间隔
1
Z = Z.reshape(xx.shape)

三、回归

3.1 普通线性回归

3.2 正则化路径——Lasso和Elastic Net回归

3.1 普通线性回归

1
from sklearn import datasets, linear_model
1
# Load the diabetes dataset
系数估计: 938.237861251均方误差: 2548.07拟合优度: 0.47
1
plt.style.use('ggplot')

3.2 正则化路径——Lasso和Elastic Net回归

这两种回归方式实际上都是在普通线性回归的损失函数中增加了一个惩罚项penelty
$ Lasso:J(\theta) = \frac{1}{2m}[\sum_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})^2 + \alpha\sum_{j=1}^{n}\theta_{j}^{2} ] $
$ Elastic Net:J(\theta) = \frac{1}{2m}[\sum_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})^2 + \alpha_1\sum_{j=1}^{n}\theta_{j}^{2} + \alpha_2\sum_{j=1}^{n}|\theta_{j}| ] $

导入库和数据集

1
from itertools import cycle
1
X.shape, y.shape

路径计算——路径图指的是系数估计和学习率$\alpha$(惩罚项前的系数)之间的关系

1
eps = 5e-3 #指定学习率变化的速率
1
print('利用Lasso计算正则化路径...')
利用Lasso计算正则化路径...利用弹性网计算正则化路径...
1
colors = cycle(['b', 'r', 'g', 'c', 'k'])

注意为了画图的方便,这里的横坐标是-log10(学习率),也就是说横坐标越大则学习率越小。
可以看到在学习率很大的情况下,即惩罚项前的系数很大,几乎所有的系数都被压缩到了0
随着学习率的减小,可以发现弹性网回归,比Lasso回归的参数变化更加平稳一些

Lasso可以强制参数估计都大于0,即将小于的参数都压缩为0

1
print('利用正Lasso计算正则化路径....')
利用正Lasso计算正则化路径....
1
plt.figure(figsize=(8,5))

弹性网也可以只产生正的参数估计,即将负的参数估计压缩到0

1
print('使用正弹性网计算正则化路径...')
使用正弹性网计算正则化路径...
1
plt.figure(figsize=(8,5))

四、聚类

4.1 1D核密度估计——1D Kernel Density Estimation

4.2 像素矢量量化——k-means聚类

4.1 1D核密度估计——1D Kernel Density Estimation

对于一个数据集,查看该数据集的频率或者频数分布图是常用的手段,希望通过频率分布图了解该数据集的大致分布是如何的。而细致地考虑频率分布图的画法,其实际上假设数据点在划分的一个小区间上服从均匀分布。所以我们常见的频率分布图都是多个柱形组成的。那么如果,考虑以每个数据点为中心,作一个小区间,且数据点在这个小区间上的分布不是均匀分布,而是一些其他如正态、指数等的分布。通过这种操作方法可以得到一个数据集的核密度的估计。

1
from scipy.stats import norm
1
N = 100
1
true_dens = (0.3 * norm(0, 1).pdf(X_plot[:, 0]) + 0.7 * norm(5, 1).pdf(X_plot[:, 0])) #数据真实的概率密度

4.2 像素矢量量化——k-means聚类

在保持图片显示质量的情况下,将图片使用颜色的种类从96615中压缩到64种
考虑用k-means聚类方法来实现上述功能,其核心原理是:将类似的颜色都划分到一个类中

1
from sklearn.cluster import KMeans
1
n_colors = 64
使用数据集的一部分子集训练模型对整张图片进行颜色预测(K-means方法)
1
def recreate_image(codebook, labels, w, h):
1
plt.figure(1)

五、降维——decomposition

5.1 主成分分析——PCA

5.2 局部线性嵌入

5.1 主成分分析——PCA

原始数据集为四维,不好作图,经过PCA处理后,可以降维到三维,可以作图。PCA的核心是协方差矩阵的特征值分解。

1
from mpl_toolkits.mplot3d import Axes3D
1
centers = [[1, 1], [-1, -1], [1, -1]]
原始维度: (150, 4)进行PCA处理PCA降维后: (150, 3)
1
fig = plt.figure()

5.2 局部线性嵌入——Locally Linear Embedding

局部线性嵌入,和传统的关注样本方差的降维方法相比,更关注在降维中保持样本数据的局部线性特征
LLE是流形学习(Manifold Learning)的一种。什么是流形降维过程?从左图可以得到启发:
我们希望将三维空间中的这块布展开,但是展开到二维空间上仍然能够局部保留布结构的特征。
局部线性嵌入,所实现的是局部最优解,且假设数据样本在局部满足线性关系,计算较快。其具体步骤可分为下面三步:

1. 对每个样本点,求K近邻,一般使用和KNN类似的算法2. 对每个样本点在其邻域中,求解其与K个近邻的线性关系,得到线性关系权重系数3. 基于权重系数,在低维空间重构样本数据
1
from mpl_toolkits.mplot3d import Axes3D
1
print('带入数据集')
带入数据集
1
fig = plt.figure(figsize=(7,5))
1
print('运行 局部线性嵌入')
运行 局部线性嵌入完成重构. 重构误差: 6.88621e-08
1
fig = plt.figure(figsize=(7,5))

六、模型选择和评价

6.1 欠拟合underfitting和过度拟合overfitting

6.2 学习曲线——learning curve

6.3 分类器评价

6.1 欠拟合Underfitting与过度拟合Overfitting

面对样本,我们希望有一个拟合效果恰好的模型,既不是underfitting也不是overfitting

1
from sklearn.pipeline import Pipeline

虚拟构建一个样本。假设已知x和y之间的关系是cos函数的关系,我们随机抽取一个样本。要注意的是,样本数据可能受到随机干扰,所以样本中的数据可能不是精确服从y=cos(x)的关系
如下图中,真实关系为红色线,而抽取的样本只是围绕在线周围,而不是全都在线上。

1
n_samples = 30

下面,我们利用线性模型,或者多项式线性模型来对x和y之间的关系进行拟合预测。
分别使用多项式阶数为1,4,15的线性模型来进行拟合,结果如下面三张图所示,可以看到第一张图中,使用线性模型来拟合,拟合效果不佳,存在underfitting的情况;第二张图中,使用4阶多项式线性模型来拟合,可以发现和真实关系之间非常接近,拟合效果较为理想;第三张图中,使用了15阶多项式线性模型来拟合,发现模型在三个模型中最好地拟合了样本点数据,然而却偏离了真实的模型,存在overfitting的情况。

1
degrees = [1, 4, 15]

实际上,可以从交叉验证(Cross Validation)的角度来帮助选择模型
交叉验证的思想是:对于一个数据集,抽取其中一部分数据集进行模型训练,利用训练好的模型对剩下的数据集进行预测,且求预测误差,不断更换模型训练的数据集,直到所有的数据都被预测过为止,汇总每次预测的误差,作为模型评价的标准。

1
from sklearn.model_selection import cross_val_score
1
#利用交叉验证进行模型评估
Degree 1   MSE = 3.76e-01(+/- 5.77e-01)Degree 4   MSE = 1.19e-01(+/- 1.56e-01)Degree 15   MSE = 1.78e+07(+/- 5.33e+07)

从交叉验证的结果来看,确实是阶数为4的模型的MSE表现最好。

6.2 学习曲线——learning curve

学习曲线可用来比较不同模型,其刻画的是随着训练样本容量的变化,模型学习进行预测的均方误差的变化

1
from sklearn.svm import SVR
1
# 生成数据
1
svr = SVR(kernel='rbf', C=1e1, gamma=0.1)
1
plt.figure()

6.3 分类器评价

在使用分类进行建模之后,往往需要对分类结果进行评价
可以从混淆矩阵,ROC曲线和交叉验证来考虑模型的分类效果

1
from sklearn.model_selection import train_test_split

人为构造数据集

1
X = np.random.randn(500,4)

模型训练和预测

1
clf = tree.DecisionTreeClassifier() #可以自己设定很多参数,如果不写则默认参数

混淆矩阵及其衍生指标

1
from sklearn import metrics
混淆矩阵:[[56 43] [59 42]]分类结果评价 DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None, max_features=None, max_leaf_nodes=None, min_impurity_split=1e-07, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=None, splitter='best'): precision recall f1-score support 0 0.49 0.57 0.52 99 1 0.49 0.42 0.45 101avg / total 0.49 0.49 0.49 200

ROC曲线和AUC

1
fpr, tpr, thresholds = metrics.roc_curve(expected, probas_[:, 1])
1
plt.figure()

交叉验证

1
from sklearn.model_selection import StratifiedKFold
1
cv = StratifiedKFold(n_splits=6) #考虑6折交叉验证

七、集成学习

集成学习是使用一系列学习器进行学习,并使用某种规则把各个学习结果进行整合从而获得比单个学习器更好的学习效果的一种机器学习方法。

7.1 特征重要程度——随机森林(Random Forest)

7.2 异常点检索——IsolationForest

7.3 梯度Boosting回归——Gradient Boosting Regression

7.1 特征重要程度——随机森林(Random Forest)

随机森林是如决策树的基础分类器的bagging

1
from sklearn.datasets import make_classification

人为构造一个分类数据集——样本容量为1000,特征个数为10,有信息含量的特征个数为3,目标类别个数为2

1
X, y = make_classification(n_samples=1000,n_features=10,n_informative=3,n_redundant=0,
[[ 0.24983722 2.07999753 -2.41574285 1.55250219 -0.02025345 1.52308665 1.50875967 -0.44983528 -0.04794935 -0.36425081] [-0.48628731 2.43254818 -2.81984222 -0.16765617 1.1524328 -0.20515407 1.67435428 0.92336623 -0.5970967 -0.78257457] [ 0.13037419 1.37164964 -1.48661612 0.28419927 -0.27937185 0.48323822 -1.70331195 -1.31814927 -1.18427125 0.9759933 ] [ 0.03665774 0.96342311 -1.6891696 -1.65494387 1.08040923 -0.73978191 -0.2680128 -0.62612224 1.00035313 1.6443156 ]][0 0 0 0]

构建随机森林模型

1
forest = ExtraTreesClassifier(n_estimators=250,random_state=0)
1
importances = forest.feature_importances_
1
print('Feature ranking:')
Feature ranking:1. feature 1 (0.295902)2. feature 2 (0.208351)3. feature 0 (0.177632)4. feature 3 (0.047121)5. feature 6 (0.046303)6. feature 8 (0.046013)7. feature 7 (0.045575)8. feature 4 (0.044614)9. feature 9 (0.044577)10. feature 5 (0.043912)

可视化特征重要程度

1
plt.figure()

7.2 异常点检索——IsolationForest

对于异常点的检索,实际上也从分类问题的角度来考虑。模型实际上就是对异常点类别和非异常点类别进行分类,如果能够分类准确的话,相当于能够检索出异常点

1
from sklearn.ensemble import IsolationForest
1
rng = np.random.RandomState(42)

模型拟合

1
clf = IsolationForest(max_samples=100, random_state=rng) #构建模型
1
xx, yy = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50))

利用模型来检索异常点,结果可以从上图看到,蓝色越深的区域是模型认为的异常区域。大多数红色点在蓝色较深的异常区域。

7.3 梯度Boosting回归——Gradient Boosting Regression

Gradient Boosting Regression结合梯度下降和Boosting的想法,对普通的回归方法进行了改进

1
from sklearn import ensemble
1
boston = datasets.load_boston() #Boston住房数据集

拟合模型

1
params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 2,'learning_rate': 0.01, 'loss': 'ls'}
MSE: 6.6523

可视化模型deviance——模型的deviance越小说明模型拟合越好

1
test_score = np.zeros((params['n_estimators'],), dtype=np.float64)

可视化特征重要程度

1
feature_importance = clf.feature_importances_ #模型结果中有特征重要程度这一选项

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多