目录python
机器学习是用数据科学的计算能力和算法能力去弥补统计学的不足。git
基本统计学概念:误差(bias)、方差(variance)、过拟合(overfitting)和欠拟合(underfitting)算法
机器学习通常分为:有监督学习和无监督学习。
有监督学习分为:分类和回归任务,分类任务中,标签都是离散值;回归任务中标签都是连续值。
无监督学习分为:聚类和降维任何。聚类算法将数据分红不一样的组别;降维算法追求更简洁的方式表现数据。
半监督学习,一般在标签数据不完整时使用。api
机器学习是从数据建立模型的学问,所以你首先须要了解怎样表示数据才能让计算机理解。sklearn认为数据表示最好的方法就是用数据表的形式。数组
# 基本的数据表示二维网格数据,其中每一行表示数据集的样本,而列表示构成每一个样本的相关特征。 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 |
# 这个表格经过二维数组或矩阵的形式将信息清晰底表达出来,咱们记此类矩阵为特征矩阵。特征矩阵一般被简记为X。 # 它是维度为[n_samples, n_features]的二维矩阵。samples--样本(行数),features--特征数(列数) # 1、样本(即每一行)一般是指数据集中的每个对象。 # 2、特征(即每一列)一般是指每一个样本都具备的某种量化观测值。通常,特征都是实数值,但有时也多是布尔值或离散值。
# 除了特征矩阵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,)
sklearn api主要遵循如下设计原则:dom
统一性:全部对象使用共同接口链接一组方法和统一的文档。
内省:全部参数都是公共属性。
限制对象层级:只有算法才能用Python类表示。数据集都用标准的数据类型(NumPy数组、Pandas DataFrame、SciPy稀疏矩阵)表示,参数名称用标准的Python字符串。
函数组合:许多机器学习任务均可以用一串基本算法实现,sklearn尽可能支持这种可能。
明智的默认值:当模型须要用户设置参数时,sklearn预先设置合适的默认值。
sklearn中的全部机器学习算法都是用过评估器API实现的,它为机器学习应用提供统一的接口机器学习
sklearn评估器API的经常使用步骤以下:函数
(1)经过从sklearn中导入适当的评估器类,选择模型类。
(2)用合适的数值对模型类进行实例化,配置模型超参数。
(3)整理数据,获取特征矩阵和目标数组。
(4)调用模型实例的fit()方法对数据进行拟合。
(5)对新数据应用模型:
在有监督学习模型中,一般使用predict()方法预测新数据的标签;
在无监督学习模型中,一般使用transform()或predict()方法转换或推断数据的性质。学习
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>]
# 咱们将使用高斯朴素贝叶斯方法来训练鸢尾花数据集,这个方法假设每一个特征中属于每一类的观测值都符合高斯分布。 # 由于高斯朴素贝叶斯方法速度很快,并且不须要选择超参数,因此一般适合做为初步分类手段,在借助复杂模型进行优化以前使用。 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
# 对鸢尾花数据集进行降维,以便能更方便地对数据进行可视化 # 降维的任务是要找到一个能够保留数据本质特征的低维矩阵来表示高维数据。 # 降维一般用于辅助数据可视化的工做,毕竟二维数据画图比多维甚至更高维的数据画图更方便。 # 主成分分析(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>
# 聚类方法是要对没有标签的数据集进行分组。 # 使用一个强大的聚类方法----高斯混合模型(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>
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]
# 虽然咱们想对具备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)
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%以上 # 可能须要借助更加复杂的算法,例如支持向量机、随机森林,或者其余分类算法。