二、【Python】机器学习-监督学习

关键词

  • 分类(Classification)
  • 回归(Regression)
  • 泛化(Generalize)
  • 过拟合(Overfitting)
  • 欠拟合(Underfitting)

2.1 分类与回归

监督机器学习问题分为两类:分类(Classification)与回归(Regression)

分类:目的是预测类别标签,这些标签来自预定义的可选列表。分类问题一般分为二分类(Binary Classification)和多分类(Multiclass classfication)。

  • 在二分类问题中,将其中的一个类别称为正类(Positive Class)。另一个称之为反类(Negative Class)。

回归:目的是预测一个连续值。区分分类和回归的方法就是看问题的输出是否具有一定的连续性

2.2 泛化、过拟合与欠拟合

泛化(Generalize):我理解为是一种拓展。如果一个模型能够对新数据做出准确的预测,那么我们就说该模型能够从训练集泛化到测试集。
过拟合(Overfitting):在创建并测试模型时,得到一个在训练集表现很好的模型,但是不可以泛化到新数据的模型,则该模型存在过拟合。
欠拟合(Underfitting):与过拟合相反,模型在训练集表现很差,更不能泛化到预测新数据,则称之为欠拟合。

模型复杂度和数据集大小的关系:数据点的变化范围越大在不发生过拟合的前提下,模型就可以越复杂。

2.3 监督学习算法

知识点

  • 解释这些算法如何预测
  • 模型复杂度如何变化
  • 概述每个算法如何构建模型
  • 算法的优缺点
  • 最适应用于哪类数据
  • 解释其中最重要参数的意义

分类数据集
下面的例子使用内置的forge数据集,说明二分类。

import mglearn
import matplotlib as plt
import numpy as np
# 生成内置的forge数据集,并将其两个特征赋给X和y。
X,y = mglearn.datasets.make_forge()
mglearn.discrete_scatter(X[:,0],X[:,1],y)
print("X shape:{}".format(X.shape))
plt.pyplot.xlabel("First Feature")
plt.pyplot.ylabel("Second Feature")
X shape:(26, 2)


c:\users\helli\appdata\local\programs\python\python37\lib\site-packages\sklearn\utils\deprecation.py:85: DeprecationWarning: Function make_blobs is deprecated; Please import make_blobs directly from scikit-learn
  warnings.warn(msg, category=DeprecationWarning)





Text(0, 0.5, 'Second Feature')

上面的数据点可以看出,X_shape带有26个数据点和两个特征。


回归算法
模拟wave数据集来说明,wave是只有一个输入特征和一个连续的目标变量(或响应),后者是模型想要预测的对象。

import matplotlib as plt
X,y = mglearn.datasets.make_wave(n_samples=40)
plt.pyplot(X,y,'o')
plt.ylim(-3,3)[]f

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

 in 
      1 import matplotlib as plt
      2 X,y = mglearn.datasets.make_wave(n_samples=40)
----> 3 plt.pyplot(X,y,'o')
      4 plt.ylim(-3,3)


TypeError: 'module' object is not callable
import matplotlib as plt
print("{}".format(.__version__))
3.0.2

2.3.1 K近邻算法

k-NN算法是最简单的,构建模型只需要保存训练数据集即可。
最简单,最易理解的就是我们只考虑一个最近邻情况,即我们想要预测的点最近的训练数据点。预测结果就是这个训练数据点的已知输出。

# n_neighbors的参数是相邻近的点
mglearn.plots.plot_knn_classification(n_neighbors=4)
c:\users\helli\appdata\local\programs\python\python37\lib\site-packages\sklearn\utils\deprecation.py:85: DeprecationWarning: Function make_blobs is deprecated; Please import make_blobs directly from scikit-learn
  warnings.warn(msg, category=DeprecationWarning)

除了最近邻,还可以考虑任意个(k个)邻居。这也是k近邻算法名字的来历。在多个邻居时,用"投票法"(Voting)指定标签。对于每个测试点,我们数一数多少个邻居属于类别0,多少个邻居属于类别1。然后将出现次数更多的类别作为预测结果。

from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

# 从mglearn获取数据
# 将数据3:1分为训练和测试
X,y = mglearn.datasets.make_forge()
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
# 调用方法,设定三个邻居个数
clf = KNeighborsClassifier(n_neighbors=3)
# 利用训练集对这个分类器进行拟合,对于KNeighborsClassifier来说就是保存数据集,以便在预测时计算与邻居的距离
clf.fit(X_train,y_train)
# 调用predict方法来对测试数据进行预测。对于测试集中的每个数据点,都要计算它在训练集的最近邻然后找出其中出现次数最多的类别。
print("Test set prediction:{}".format(clf.predict(X_test)))
# 数据泛化能力
print("Test set accuracy:{:.2f}".format(clf.score(X_test,y_test)))
Test set prediction:[1 0 1 0 1 0 0]
Test set accuracy:0.86


c:\users\helli\appdata\local\programs\python\python37\lib\site-packages\sklearn\utils\deprecation.py:85: DeprecationWarning: Function make_blobs is deprecated; Please import make_blobs directly from scikit-learn
  warnings.warn(msg, category=DeprecationWarning)

2.3.2 分析KNeighborsClassifier

对于二维数据集,可以在xy平面画出所有可能的测试点的预测结果。根据每个点所属的类别进行着色,这个可以查看决策边界(decision boundary)

# 对1,3,9个邻居三种情况进行决策边界的可视化。
fig, axes = plt.pyplot.subplots(1,3,figsize=(10,3))

for n_neighbors, ax in zip([1,3,9], axes):
    clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X,y)
    mglearn.plots.plot_2d_separator(clf,X,fill=True,eps=0.5,ax=ax,alpha=.4)
    mglearn.discrete_scatter(X[:,0],X[:,1],y,ax=ax)
    ax.set_title("{} neighbor(s)".format(n_neighbors))
    ax.set_xlabel("feature 0")
    ax.set_ylabel("feature 1")

从上图可以看出,neighbor越大,决策边界越平滑,相邻值小,对应更高的模型复杂度;相邻值大,对应更低的模型复杂度。

from sklearn.datasets import load_breast_cancer

cancer = load_breast_cancer()
X_train,X_test,y_train,y_test = train_test_split(cancer.data,cancer.target,stratify=cancer.target,random_state=66)

training_accuracy = []
test_accuracy=[]
n_s = range(1,11)
for n_neighbors in n_s:
    clf = KNeighborsClassifier(n_neighbors=n_neighbors)
    clf.fit(X_train,y_train)
    training_accuracy.append(clf.score(X_train,y_train))
    test_accuracy.append(clf.score(X_test,y_test))
    
plt.pyplot.plot(n_s, training_accuracy,label="training")
plt.pyplot.plot(n_s,test_accuracy,label="test",linestyle='--',color='g')
plt.pyplot.xlabel("n_s")
plt.pyplot.ylabel("Accuracy")
plt.pyplot.legend()

2.3.3 K近邻回归

使用wave数据集

mglearn.plots.plot_knn_regression(n_neighbors=3)

from sklearn.neighbors import KNeighborsRegressor
X,y = mglearn.datasets.make_wave(n_samples=40)
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
reg = KNeighborsRegressor(n_neighbors=3)
reg.fit(X_train,y_train)
print("pre:{}".format(reg.predict(X_test)))
print("score:{:.2f}".format(reg.score(X_test,y_test)))
pre:[-0.05396539  0.35686046  1.13671923 -1.89415682 -1.13881398 -1.63113382
  0.35686046  0.91241374 -0.44680446 -1.13881398]
score:0.83
fig, axes = plt.pyplot.subplots(1,3,figsize=(10,3))
# 创建1000个数据点,在-3,3之间均匀分布
line = np.linspace(-3,3,1000).reshape(-1,1)
for n_neighbors, ax in zip([1,3,9], axes):
    clf = KNeighborsRegressor(n_neighbors=n_neighbors).fit(X_train,y_train)
    ax.plot(line,clf.predict(line))
    ax.plot(X_train,y_train,'^',c=mglearn.cm2(0),markersize=8)
    ax.plot(X_test,y_test,marker='v',c=mglearn.cm2(1),markersize=8)
    ax.set_title("{} neighbor(s)\n{:.2f}train score.{:.2f}testscore".format(n_neighbors,clf.score(X_train,y_train),clf.score(X_test,y_test)))
    ax.set_xlabel("feature 0")
    ax.set_ylabel("feature 1")

2.3.4 优缺点

KNeighbors分类器有两个重要参数:邻居个数和数据点之间距离的度量方法,一般3-5个邻居数都会得到比较好的结果。
K-NN有点之一就是模型很容易理解。不需要过多的调节,就可以得到不错的效果。这是最大的有点。简单易学好上手。
但是对于很多特征的数据集,该算法就会无能为力了,而且速度较慢,因此一般不会应用到实践中。

你可能感兴趣的:(二、【Python】机器学习-监督学习)