第四章 机器学习

4.1 机器学习简介

机器学习是用数据科学的计算能力和算法能力去弥补统计学的不足。

基本统计学概念:偏差(bias)、方差(variance)、过拟合(overfitting)和欠拟合(underfitting)

4.1.1 机器学习分类

机器学习一般分为:有监督学习和无监督学习。

有监督学习分为:分类和回归任务,分类任务中,标签都是离散值;回归任务中标签都是连续值。

无监督学习分为:聚类和降维任何。聚类算法将数据分成不同的组别;降维算法追求更简洁的方式表现数据。

半监督学习,通常在标签数据不完整时使用。

4.2 Scikit-Learn简介

4.2.1 Scikit-Learn的数据表示

机器学习是从数据创建模型的学问,因此你首先需要了解怎样表示数据才能让计算机理解。sklearn认为数据表示最好的方法就是用数据表的形式。

1.数据表

# 基本的数据表示二维网格数据,其中每一行表示数据集的样本,而列表示构成每个样本的相关特征。
import seaborn as sns
iris = sns.load_dataset('iris')
iris.head()
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa

2.特征矩阵

# 这个表格通过二维数组或矩阵的形式将信息清晰底表达出来,我们记此类矩阵为特征矩阵。特征矩阵通常被简记为X。
# 它是维度为[n_samples, n_features]的二维矩阵。samples--样本(行数),features--特征数(列数)
# 一、样本(即每一行)通常是指数据集中的每一个对象。
# 二、特征(即每一列)通常是指每个样本都具有的某种量化观测值。一般,特征都是实数值,但有时也可能是布尔值或离散值。

3.目标数组

# 除了特征矩阵x之外,还需要一个标签或标签数组,记为y。目标数组一般是一维数组,
# 长度就是样本总数n_samples,通常用一维的NumPy数组或者Pandas的Series表示。
# 目标数组可以是连续的数值类型,也可以是离散的类型/标签。
%matplotlib inline
sns.set()
sns.pairplot(iris,hue='species',size=1.5)
# 从iris数据集中抽取特征矩阵和目标数组
X_iris = iris.drop('species',axis=1)
print("X_iris:",X_iris.shape)
y_iris = iris['species']
print("y_iris:",y_iris.shape)
X_iris: (150, 4)
y_iris: (150,)

4.2.2 Scikit-Learn的评估器API

sklearn api主要遵循以下设计原则:

统一性:所有对象使用共同接口连接一组方法和统一的文档。

内省:所有参数都是公共属性。

限制对象层级:只有算法才能用Python类表示。数据集都用标准的数据类型(NumPy数组、Pandas DataFrame、SciPy稀疏矩阵)表示,参数名称用标准的Python字符串。

函数组合:许多机器学习任务都可以用一串基本算法实现,sklearn尽量支持这种可能。

明智的默认值:当模型需要用户设置参数时,sklearn预先设置合适的默认值。

sklearn中的所有机器学习算法都是用过评估器API实现的,它为机器学习应用提供统一的接口

1.API基础知识

sklearn评估器API的常用步骤如下:

(1)通过从sklearn中导入适当的评估器类,选择模型类。

(2)用合适的数值对模型类进行实例化,配置模型超参数。

(3)整理数据,获取特征矩阵和目标数组。

(4)调用模型实例的fit()方法对数据进行拟合。

(5)对新数据应用模型:

在有监督学习模型中,通常使用predict()方法预测新数据的标签;

在无监督学习模型中,通常使用transform()或predict()方法转换或推断数据的性质。

2.有监督学习示例:简单线性回归

import matplotlib.pyplot as plt
import numpy as np rng = np.random.RandomState(42)
x = 10 * rng.rand(50)
y = 2 * x - 1 + rng.randn(50)
# a.选择模型类
from sklearn.linear_model import LinearRegression
# b.选择模型超参数
# 问题:
# 我们想要拟合偏移量(即直线的截距)吗?
# 我们需要对模型进行归一化处理吗?
# 我们需要对特征进行预处理以提高模型灵活性吗?
# 我们打算在模型中使用哪种正则化类型?
# 我们打算使用多少模型组件?
# 有一些重要的参数必须在选择模型类时确定好。这些参数通常被称为超参数,即在模型拟合之前必须确定下来的参数。
model = LinearRegression(fit_intercept=True) # 拟合直线截距
print("模型超参数:\n",model)
# c.抽取特征矩阵和目标数据
X = x[:,np.newaxis]
print("特征矩阵X:\n",X)
print("目标数组y:\n",y)
# d.拟合数据
model.fit(X,y)
# fit()方法会在模型内部进行大量运算,运算结果将存储在模型属性中,供用户使用。
# 在sklearn中,所有通过fit()方法获得的模型参数都带一条下划线。如:线性模型中的模型参数如下:
print("模型的斜率:",model.coef_)
print("模型的截距:",model.intercept_)
# 模型训练效果评价:
# 原数据由y = 2 * x - 1 + rng.randn(50)获得,从中看出直线斜率为 2,截距为 1
# 拟合模型的直线斜率为 1.9776566,截距为 -0.903310725531 误差很小。
# e.预测新数据的标签
xfit = np.linspace(-1,11)
Xfit = xfit[:,np.newaxis]
yfit = model.predict(Xfit)
plt.scatter(x,y) # 散点图
plt.plot(xfit,yfit)
模型超参数:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
特征矩阵X:
[[ 3.74540119]
[ 9.50714306]
[ 7.31993942]
[ 5.98658484]
[ 1.5601864 ]
[ 1.5599452 ]
[ 0.58083612]
[ 8.66176146]
[ 6.01115012]
[ 7.08072578]
[ 0.20584494]
[ 9.69909852]
[ 8.32442641]
[ 2.12339111]
[ 1.81824967]
[ 1.8340451 ]
[ 3.04242243]
[ 5.24756432]
[ 4.31945019]
[ 2.9122914 ]
[ 6.11852895]
[ 1.39493861]
[ 2.92144649]
[ 3.66361843]
[ 4.56069984]
[ 7.85175961]
[ 1.99673782]
[ 5.14234438]
[ 5.92414569]
[ 0.46450413]
[ 6.07544852]
[ 1.70524124]
[ 0.65051593]
[ 9.48885537]
[ 9.65632033]
[ 8.08397348]
[ 3.04613769]
[ 0.97672114]
[ 6.84233027]
[ 4.40152494]
[ 1.22038235]
[ 4.9517691 ]
[ 0.34388521]
[ 9.09320402]
[ 2.58779982]
[ 6.62522284]
[ 3.11711076]
[ 5.20068021]
[ 5.46710279]
[ 1.84854456]]
目标数组y:
[ 7.22926896 18.18565441 13.52423055 10.67206599 0.64185082
1.4000462 -0.29896653 17.38064514 11.36591852 11.3984114
-0.26422614 18.01311476 14.97193082 3.8584585 3.66749887
3.59937032 4.24562734 9.18591626 7.9701638 5.80012793
10.75788366 1.60421824 3.736558 5.13103024 8.93392551
16.05975926 2.92146552 10.28822167 11.2099274 -0.7161115
11.51229264 3.94851904 0.26520582 19.5423544 15.69289556
15.98984947 5.17932245 0.65443493 12.77642131 5.81548096
1.22109281 9.26065077 1.16566447 16.66813782 3.36710603
11.74868864 6.14962364 9.73011153 9.40444538 3.21035654]
模型的斜率: [ 1.9776566]
模型的截距: -0.903310725531
[<matplotlib.lines.Line2D at 0x1e13980d1d0>]

3.有监督学习示例:鸢尾花数据分类

# 我们将使用高斯朴素贝叶斯方法来训练鸢尾花数据集,这个方法假设每个特征中属于每一类的观测值都符合高斯分布。
# 因为高斯朴素贝叶斯方法速度很快,而且不需要选择超参数,所以通常适合作为初步分类手段,在借助复杂模型进行优化之前使用。
from sklearn.naive_bayes import GaussianNB # 1.选择模型类
model = GaussianNB() # 2.初始化模型
from sklearn.cross_validation import train_test_split
Xtrain,Xtest,ytrain,ytest = train_test_split(X_iris,y_iris) # 3.分割数据集
model.fit(Xtrain,ytrain) # 4.拟合数据集
ypredict = model.predict(Xtest) # 5.预测数据集
from sklearn.metrics import accuracy_score
print(accuracy_score(ypredict,ytest)) # 6.模型准确率评估
print(accuracy_score(ytest,ypredict))
# 准确率高达97%
0.947368421053
0.947368421053

4.无监督学习示例:鸢尾花数据降维

# 对鸢尾花数据集进行降维,以便能更方便地对数据进行可视化
# 降维的任务是要找到一个可以保留数据本质特征的低维矩阵来表示高维数据。
# 降维通常用于辅助数据可视化的工作,毕竟二维数据画图比多维甚至更高维的数据画图更方便。
# 主成分分析(principal component analysis,PCA)方法,这一种快速线性降维技术。
from sklearn.decomposition import PCA # 1.选择模型类
model = PCA(n_components=2) # 2.设置超参数,初始化模型
model.fit(X_iris) # 3.拟合模型
x_2D = model.transform(X_iris) # 4.将数据转换为二维
iris['PCA1'] = x_2D[:,0]
iris['PCA2'] = x_2D[:,1]
sns.lmplot("PCA1","PCA2",hue='species',data=iris,fit_reg=False)
# 从二维数据标示图可以看出,虽然PCA算法根本不知道花的种类标签,但不同种类的花还是
# 被清晰地区分开来! 这表明用一种比较简单的分类方法就能够有效地学习这份数据集。
<seaborn.axisgrid.FacetGrid at 0x1e139168198>

5.无监督学习示例:鸢尾花数据聚类

# 聚类方法是要对没有标签的数据集进行分组。
# 使用一个强大的聚类方法----高斯混合模型(Guassian mixture model,GMM)。
# GMM模型试图将数据构造成若干服从高斯分布的概率密度函数镞。
from sklearn.mixture import GaussianMixture # 1.选择模型类
model = GaussianMixture(n_components=3,covariance_type='full') # 2.设置超参数,初始化模型 组件数量,协方差类型
model.fit(X_iris) # 3.拟合数据
y_predict = model.predict(X_iris) # 4.预测簇标签
iris['cluster'] = y_predict
sns.lmplot("PCA1","PCA2",data=iris,hue='species',col='cluster',fit_reg=False)
# 根据簇数量对数据进行分割,就会清晰地看出GaussianMixture算法的训练效果:setosa类的花在簇0中
# 被完美底区分出来,唯一的遗憾是第二幅图中的versicolor和virginical还有一点混淆。
# 这就说明,即使没有专家告诉完美每朵花的具体类型,但由于每种花的特征差异很大,
# 因此完美也可以通过简单的聚类算法自动识别出不同种类的花!
# 这种算法还可以帮助专家们探索观察样本之间的关联性。
<seaborn.axisgrid.FacetGrid at 0x1e13c455630>

4.2.3 应用:手写数字探索

1.加载并可视化手写数字

from sklearn.datasets import load_digits
digits = load_digits()
digits.images.shape
# 这份图像数据是一个三维矩阵:共有1797个样本,每张图像都是8 × 8 像素。对前100张图进行可视化:
import matplotlib.pyplot as plt
fig,axes = plt.subplots(10,10,figsize=(8,8),
subplot_kw={'xticks':[],'yticks':[]},
gridspec_kw=dict(hspace=0.1,wspace=0.1))
for i,ax in enumerate(axes.flat):
ax.imshow(digits.images[i],cmap='binary',interpolation='nearest')
ax.text(0.05,0.05,str(digits.target[i]),
transform=ax.transAxes,color='green') # 为了在sklearn中使用数据,需要一个维度为[n_samples, n_features]的二维特征矩阵
# 可以将每个样本图像的所有像素都作为特征,也就是将每个数字的8 × 8像素平铺成长度为64的一维数组。
# 另外,还需要一个目标数组,用来表示每个数字的真实值(标签)。这两份数据已经放在手写数字数据集
# 的data与target属性中,直接使用即可:
X = digits.data
y = digits.target
print("X的形状:",X.shape,"\n",X)
print("y的形状:",y.shape,"\n",y)
# 从上面可以看出,一共有1797个样本和64个特征。
X的形状: (1797, 64)
[[ 0. 0. 5. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 10. 0. 0.]
[ 0. 0. 0. ..., 16. 9. 0.]
...,
[ 0. 0. 1. ..., 6. 0. 0.]
[ 0. 0. 2. ..., 12. 0. 0.]
[ 0. 0. 10. ..., 12. 1. 0.]]
y的形状: (1797,)
[0 1 2 ..., 8 9 8]

2.无监督学习:降维

# 虽然我们想对具有64维参数控件的样本进行可视化,但是咋如此高纬度的控件中进行可视化十分困难。
# 因此,我们需要借助无监督学习方法将维度降到二维。
# 这次试试流行学学习算法中的isomap算法对数据域进行降维:
from sklearn.manifold import Isomap # 1.选择模型类
model = Isomap(n_components=2) # 2.设置超参数,模型初始化
model.fit(X) # 3.拟合模型
data_projected = model.transform(X) # 4.将数据转为二维
print(data_projected.shape)
# 现在数据已经投影到二维。把数据画出来,看看从结构中能发现什么:
plt.scatter(data_projected[:,0],data_projected[:,1],c=y,
edgecolor='none',alpha=0.5,
cmap=plt.cm.get_cmap('nipy_spectral',10))
plt.colorbar(label='digit label',ticks=range(10))
plt.clim(-0.5,9.5) # 这幅图呈现除了非常直观的效果,让我们知道数字在64维空间中的分离(可识别)程度。
# 例如,在参数空间中,数字0和数字1基本不会重叠。
# 另外,从图中会发现,数字1和数字4好像有点儿混淆---也许有人写数字1时喜欢在上面加个“帽子”,因此看起来像数字4.
# 虽然有些瑕癖,但从总体上看,各个数字在参数空间中的分离程度还是令人满意的。
# 这其实告诉完美;用一个非常简单的有监督分类算法就可以完成任务。
(1797, 2)

4.有监督学习:数字分类

Xtrain,Xtest,ytrain,ytest = train_test_split(X,y,random_state=0)
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(Xtrain,ytrain)
y_predict = model.predict(Xtest)
from sklearn.metrics import accuracy_score
print(accuracy_score(y_predict,ytest))
# 可以看出,通过一个非常简单的模型,数字识别率就可以达到80%以上!但仅依靠这个指标,
# 我们无法知道模型哪里做的不好,解决这个问题的办法就是用混淆矩阵。
# 可以用sklearn计算混淆矩阵,然后用seaborn画出来:
from sklearn.metrics import confusion_matrix
mat = confusion_matrix(ytest,y_predict)
sns.heatmap(mat,square=True,annot=True,cbar=False)
plt.xlabel('predicted value')
plt.ylabel('true value')
# 从图中可以看出,误判的主要原因是许多数字2被误判成了数字1和数字8.
0.833333333333
<matplotlib.text.Text at 0x1e13b0dccc0>

# 另一种显示模型特征的直观方式是将样本画出来,然后把预测标签放在左下角,用绿色表示预测正确,用红色表示预测错误:
fig,axes = plt.subplots(10,10,figsize=(8,8),
subplot_kw={'xticks':[],'yticks':[]},
gridspec_kw=dict(hspace=0.1,wspace=0.1))
test_images = Xtest.reshape(-1,8,8)
for i,ax in enumerate(axes.flat):
ax.imshow(test_images[i],cmap='binary',interpolation='nearest')
ax.text(0.05,0.05,str(y_predict[i]),
transform=ax.transAxes,
color='green' if (ytest[i] == y_predict[i]) else 'red')
# 通过观察这部分样本数据,我们能自动模型哪里的学习不够好。如果希望分类准确率达到90%以上
# 可能需要借助更加复杂的算法,例如支持向量机、随机森林,或者其他分类算法。

4.2 Scikit-Learn简介(机器学习篇)的更多相关文章

  1. Scikit Learn: 在python中机器学习

    转自:http://my.oschina.net/u/175377/blog/84420#OSC_h2_23 Scikit Learn: 在python中机器学习 Warning 警告:有些没能理解的 ...

  2. (原创)(三)机器学习笔记之Scikit Learn的线性回归模型初探

    一.Scikit Learn中使用estimator三部曲 1. 构造estimator 2. 训练模型:fit 3. 利用模型进行预测:predict 二.模型评价 模型训练好后,度量模型拟合效果的 ...

  3. (原创)(四)机器学习笔记之Scikit Learn的Logistic回归初探

    目录 5.3 使用LogisticRegressionCV进行正则化的 Logistic Regression 参数调优 一.Scikit Learn中有关logistics回归函数的介绍 1. 交叉 ...

  4. ORM查询语言(OQL)简介--高级篇(续):庐山真貌

    相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎换骨 ORM查询语言(OQL)简介--高级篇(续):庐山 ...

  5. ORM查询语言(OQL)简介--高级篇:脱胎换骨

    相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎换骨 ORM查询语言(OQL)简介--高级篇(续):庐山 ...

  6. scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类 (python代码)

    scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类数据集 fetch_20newsgroups #-*- coding: UTF-8 -*- import ...

  7. ORM查询语言(OQL)简介高级篇

    ORM查询语言(OQL)简介--高级篇:脱胎换骨 在写本文之前,一直在想文章的标题应怎么取.在写了<ORM查询语言(OQL)简介--概念篇>.<ORM查询语言(OQL)简介--实例篇 ...

  8. Scikit Learn

    Scikit Learn Scikit-Learn简称sklearn,基于 Python 语言的,简单高效的数据挖掘和数据分析工具,建立在 NumPy,SciPy 和 matplotlib 上.

  9. 【ABAP系列】SAP ABAP7.40新语法简介第一篇

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP7.40新语法简 ...

随机推荐

  1. Informatica PowerCenter 常用转换组件一览表

    原文地址:https://blog.csdn.net/yongjian1092/article/details/52176018 转换类型: 积极转换(Active):可以更改通过它来传递的数据行数, ...

  2. 吴裕雄 python 神经网络——TensorFlow pb文件保存方法

    import tensorflow as tf from tensorflow.python.framework import graph_util v1 = tf.Variable(tf.const ...

  3. XCOJ1250: 语言战争

    1250: 语言战争 时间限制: 1 Sec  内存限制: 64 MB提交: 203  解决: 46 标签提交统计讨论版 题目描述 llc和yrc语言的优劣一直都是大家所争论的焦点,但它们之间最大的区 ...

  4. 【原】linux两台服务器之间免密登录方法

    搭建集群机器192.168.0.100和192.168.0.200里,需要两台机器中间相互拷贝文件: 方式一:下载192.168.0.100机器文件到本地,再将本地文件拷贝到B机器 方式二:192.1 ...

  5. 洗牌利器——random.shuffle()函数

    random.shuffle()是一个非常实用但是又非常容易被忽略的函数,shuffle在英语里是"洗牌"的意思,该函数非常形象地模拟了洗牌的过程,即: random.shuffl ...

  6. VUE项目开发中使用WebSocket

    初始化WebSocket initWebSocket(){ //初始化weosocket const wsuri = 'ws://10.100.45.8:8888/websocket';//ws地址 ...

  7. WCF 数据传输SIZE过大

    1.当客户端调用WCF服务时,接受数据过大,可通过以下配置解决 <basicHttpBinding> <binding name="BasicHttpBinding_Wcf ...

  8. 设计模式课程 设计模式精讲 3-6 单一职责原则Coding

    1 要点讲解 1.1 需要注意 2 代码演练 2.1 类的单一职责原则demo 2.2 接口的单一职责原则demo 2.3 方法的单一职责原则demo 1 要点讲解 1.1 需要注意 1.1.1 实际 ...

  9. 1-9springboot之thymeleaf常用语法(html页面)

    一.引用命名空间 <html xmlns:th="http://www.thymeleaf.org"> 在html中引入此命名空间,可避免编辑器出现html验证错误,虽 ...

  10. 前端面试:js数据类型

    js数据类型是js中的基础知识点,也是前端面试中一定会被考察的内容.本文旨在知识的梳理和总结,希望读者通过阅读本文,能够对这一块知识有更清晰的认识.文中如果出现错误,请在评论区指出,谢谢. js数据类 ...