Python机器学习 学习笔记与实践
环境:win10 + Anaconda Python3.8
该篇总结各类监督学习算法的实践使用方法
1、二分类
线性模型也广泛应用于分类问题。我们首先来看二分类。这时可以利用下面的公式进行预测:
ŷ = w[0] * x[0] + w[1] * x[1] + …+ w[p] * x[p] + b > 0
如果函数值小于 0,我们就预测类别 -1;如果函数值大于 0,我们就预测类别 +1。对于所有用于分类的线性模型,这个预测规则都是通用的。
最常见的两种线性分类算法是 Logistic 回归(logistic regression)和线性支持向量机(linear support vector machine,线性 SVM。将 LogisticRegression 和 LinearSVC 模型应用到 forge 数据集上,并将线性模型找到的决策边界可视化,代码如下:
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
import mglearn
import matplotlib.pyplot as plt
#产生forge数据集
X, y = mglearn.datasets.make_forge()
fig, axes = plt.subplots(1, 2, figsize=(10, 3))
#画出决策边界
for model, ax in zip([LinearSVC(), LogisticRegression()], axes):
clf = model.fit(X, y)
mglearn.plots.plot_2d_separator(clf, X, fill=False, eps=0.5, ax=ax, alpha=.7)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)
ax.set_title("{}".format(clf.__class__.__name__))
ax.set_xlabel("Feature 0")
ax.set_ylabel("Feature 1")
axes[0].legend()
plt.show()
结果为:
(1)make_forge()函数定义如下:
def make_forge():
# a carefully hand-designed dataset lol
X, y = make_blobs(centers=2, random_state=4, n_samples=30)
y[np.array([7, 27])] = 0
mask = np.ones(len(X), dtype=np.bool)
mask[np.array([0, 1, 5, 26])] = 0
X, y = X[mask], y[mask]
return X, y
(2)plt.subplots函数简单解释如下:
fig, axes = plt.subplots(1, 2, figsize=(10, 3)) ,产生一行两列共两个子图。
该函数返回的是:
Returns:
fig:Figure
axes:axes.Axes or array of Axes
ax can be either a single Axes object or an array of Axes objects if more than one subplot was created.
(3)zip()函数的简单用法:
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
以下实例展示了 zip 的使用方法:
>>>a = [1,2,3]
>>>b = [4,5,6]
>>>c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
(4)两个模型得到了相似的决策边界。注意,两个模型中都有两个点的分类是错误的。两个模型都默认使用 L2 正则化,就像 Ridge 对回归所做的那样。决定正则化强度的权衡参数叫作 C。C 值越大,对应的正则化越弱。上面的结果是默认参数c=1的结果。下面给出C=100和C=0.01时的结果:
C=100:
C=0.01:
对比可见,C越大,则正则化约束越弱,直线越趋近于把所有的训练点正确的分类,这样一来直线的斜率可能会很大,容易发生过拟合。C越小,则直线越平稳、越保守,比较不容易过拟合。
2、多分类
将二分类算法推广到多分类算法的一种常见方法是“一对其余”(one-vs.-rest)方法。说白了,就是把每一个类别都用一条直线和其他的类别分开,最后决策的时候,在对应类别上分数最高的分类器“胜出”,将这个类别标签返回作为预测结果。
我们将“一对其余”方法应用在一个简单的三分类数据集上。我们用到了一个二维数据集,每个类别的数据都是从一个高斯分布中采样得出的。
代码如下:
from sklearn.datasets import make_blobs
from sklearn.svm import LinearSVC
import mglearn
import matplotlib.pyplot as plt
import numpy as np
#导入数据集并观察
X,y = make_blobs(random_state=42)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.legend(["Class 0", "Class 1", "Class 2"])
plt.show()
#训练模型
linear_svm = LinearSVC().fit(X, y)
print("Coefficient shape: ", linear_svm.coef_.shape)
print("Intercept shape: ", linear_svm.intercept_.shape)
#画图
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
line = np.linspace(-15, 15)
for coef, intercept, color in zip(linear_svm.coef_, linear_svm.intercept_,['b', 'r', 'g']):
plt.plot(line, -(line * coef[0] + intercept) / coef[1], c=color)
plt.ylim(-10, 15)
plt.xlim(-10, 8)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.legend(['Class 0', 'Class 1', 'Class 2', 'Line class 0', 'Line class 1','Line class 2'], loc=(1.01, 0.3))
plt.show()
运行结果:
产生的数据集如下:
模型训练之后的直线系数和截距的Array形状:
可视化图:
(1)从系数和截距的维度或从图中都可以明显地看到,确实产生了3条直线