学习目标:
◇ 监督学习的概念
◇ K近邻算法
◇ 朴素贝叶斯模型
◇ 决策树模型
◇ 线性模型
◇ 逻辑回归
◇ 支持向量机
◇ 集成学习方法
◇ 神经网络
◇ 分类器的不确定度
学习内容:
1.线性清单
使用Logistic Regression模型对乳腺癌数据集进行分类,并分析不同C值对模型性能的影响:
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
#对于LogisticRegression和LinearSVC,决定正则化强度的权衡参数叫作C。C值越大,对应的正则化越弱。在乳腺癌数据集上详细分析LogisticRegression
# 加载乳腺癌数据集
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=42)
# 训练默认参数的 Logistic Regression 模型:#C=1的默认值给出了相当好的性能,在训练集和测试集上都达到95名的精度。但由于训练集和测试集的性能非常接近,所以模型很可能是欠拟合的。尝试增大C来拟合一个更灵活的模型
logreg = LogisticRegression(max_iter=10000).fit(X_train, y_train)
print("Training set score (default C=1): {:.3f}".format(logreg.score(X_train, y_train)))
print("Test set score (default C=1): {:.3f}".format(logreg.score(X_test, y_test)))
# 增大 C 值为 100 的 Logistic Regression 模型:
logreg100 = LogisticRegression(C=100, max_iter=10000).fit(X_train, y_train)
print("Training set score (C=100): {:.3f}".format(logreg100.score(X_train, y_train)))
print("Test set score (C=100): {:.3f}".format(logreg100.score(X_test, y_test)))
# 减小 C 值为 0.01 的 Logistic Regression 模型
logreg001 = LogisticRegression(C=0.01, max_iter=10000).fit(X_train, y_train)
print("Training set score (C=0.01): {:.3f}".format(logreg001.score(X_train, y_train)))
print("Test set score (C=0.01): {:.3f}".format(logreg001.score(X_test, y_test)))
2.逻辑回归分类
逻辑回归分类是一种常用的机器学习算法,用于解决二分类问题,即将数据分为两个不同的类别。它基于逻辑函数(也称为sigmoid函数)将输入特征映射到0和1之间的概率值。
在逻辑回归分类中,有两个主要的部分:模型训练和预测。在模型训练阶段,我们使用带有标记类别的训练数据来学习特征与类别之间的关系。逻辑回归模型通过计算每个特征的权重,以及一个偏置项来对数据进行拟合。训练过程中使用的优化算法通常是梯度下降,目标是最小化损失函数(通常使用对数损失函数)。通过反复迭代和调整参数,我们不断优化模型,使其能够更好地预测数据的类别。
在预测阶段,使用训练好的模型来对新的未标记数据进行分类。根据特征的权重和偏置项,我们计算出数据属于某个类别的概率。如果概率大于一个阈值(通常是0.5),我们将其预测为正类别;否则,我们将其预测为负类别。
逻辑回归分类的优势包括:
- 算法简单且计算效率高,适用于大规模的数据集。
- 可以估计类别的概率,而不仅仅是进行二分类预测。
- 可以使用正则化方法来防止过拟合,并提高泛化能力。
from math import exp
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets._samples_generator import make_blobs
from torch import sigmoid
def sigmoid(num):
if type(num) == int or type(num) == float:
return 1.0 / (1 + exp(-1 * num))
else:
raise ValueError('only int or float data can compute sigmoid')
class logistic():
def __init__(self, x, y):
if type(x) == type(y) == list:
self.x = np.array(x)
self.y = np.array(y)
elif type(x) == type(y) == np.ndarray:
self.x = x
self.y = y
else:
raise ValueError('input data error')
def sigmoid(self, x):
s = np.frompyfunc(lambda x: sigmoid(x), 1, 1)
return s(x)
def train_with_punish(self, alpha, errors, punish=0.0001):
self.punish = punish
dimension = self.x.shape[1]
self.theta = np.random.random(dimension)
compute_error = 100000000
times = 0
while compute_error > errors:
res = np.dot(self.x, self.theta)
delta = self.sigmoid(res) - self.y
self.theta = self.theta - alpha * np.dot(self.x.T, delta) - punish * self.theta
compute_error = np.sum(delta)
times += 1
def predict(self, x):
x = np.array(x)
if self.sigmoid(np.dot(x, self.theta)) > 0.5:
return 1
else:
return 0
def test():
x, y = make_blobs(n_samples=200, centers=2, n_features=2, random_state=0, center_box=(10, 20))
x1 = []
y1 = []
x2 = []
y2 = []
for i in range(len(y)):
if y[i] == 0:
x1.append(x[i][0])
y1.append(x[i][1])
elif y[i] == 1:
x2.append(x[i][0])
y2.append(x[i][1])
p = logistic(x, y)
p.train_with_punish(alpha=0.00001, errors=0.005, punish=0.01)
x_test = np.arange(10, 20, 0.01)
y_test = (-1 * p.theta[0] / p.theta[1]) * x_test
plt.plot(x_test, y_test, c='g', label='logistic_line')
plt.scatter(x1, y1, c='r', label='positive')
plt.scatter(x2, y2, c='b', label='negative')
plt.legend(loc=2)
plt.title('punish value =' + p.punish.__str__())
plt.show()
if __name__ == '__main__':
test()
3.支持向量机
支持向量机(Support Vector Machine,SVM)是一种广泛应用于机器学习和模式识别领域的监督学习算法。它可以用于解决分类和回归问题。
SVM的核心思想是将数据点映射到高维空间,并在新的高维空间中找到一个最优的超平面,用于将不同类别的数据点分开。该超平面可以将数据点分为两个类别,使得离超平面最近的数据点到超平面的距离最大。
在SVM中,这些离超平面最近的数据点被称为“支持向量”,它们对于定义超平面和分类决策非常关键。SVM的目标是找到一个最大间隔超平面(最大化支持向量到超平面的距离),以获得最好的分类效果。
SVM拥有以下特点和优势:
- 可用于线性可分和线性不可分的数据。
- 在高维空间中进行计算,能更好地处理复杂的数据关系。
- 对于小样本和高维数据集表现良好。
- 通过使用核函数,SVM可以进行非线性分类。
SVM的应用非常广泛,包括文本分类、图像分类、人脸识别、手写数字识别等。它在许多实际问题中表现出色,具有很强的泛化能力和较低的风险。
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np
X, y = make_blobs(n_samples=50, centers=2, random_state=0, cluster_std=0.6)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plt.show()
xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plt.plot(xfit, xfit+0.65, '-k')
plt.plot(xfit, 0.5*xfit+1.6, '-k')
plt.plot(xfit, -0.2*xfit+2.9, '-k')
plt.xlim(-1, 3.5)
plt.show()
from sklearn. svm import SVC# "Support vector classifier"#支持向量机分类器
model = SVC(kernel = 'linear',C= 1E10)
model.fit(X,y)
#画出支持向量
def plot_svc_decision_function(model,ax = None, plot_support = True):
"""Plot the decision function for a 2D svc"""
if ax is None:
ax =plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
x =np. linspace(xlim[ 0],xlim[ 1],30)
y =np. linspace(ylim[ 0], ylim[1],30)
Y,X =np. meshgrid(y, x)
xy = np.vstack([ X.ravel(), Y.ravel()]).T
P=model. decision_function(xy) .reshape( X.shape)
ax.contour(X,Y, P,colors = 'k', levels = [ -1,0,1],alpha = 0.5, linestyles =['--', '-', '--'])
if plot_support:
ax.scatter(model.support_vectors_[:,0],model. support_vectors_[ :, 1],s=300,linewidth= 1, facecolors = 'none')
ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.scatter(X[:,0],X[:,1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model)
plt.show()
print(model.support_vectors_)
def plot_svm(N=10, ax=None):
X, y = make_blobs(n_samples=200, centers=2, random_state=0, cluster_std=0.60)
X = X[:N]
y = y[:N]
model = SVC(kernel='linear', C=1E10)
model.fit(X, y)
ax = ax or plt.gca()
ax.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
ax.set_xlim(-1, 4)
ax.set_ylim(-1, 6)
plot_svc_decision_function(model, ax)
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
for axi, N in zip(ax, [60, 120]):
plot_svm(N, axi)
axi.set_title('N= {0}'.format(N))
plt.show()
4.核SVM分类
核支持向量机(Kernel Support Vector Machine,Kernel SVM)是支持向量机(SVM)算法的一种扩展,用于解决非线性分类问题。与传统的线性SVM不同,核SVM通过使用核函数对输入数据进行非线性映射,将数据从原始空间映射到一个更高维的特征空间,以便在特征空间中找到一个最佳的超平面来分离不同的类别。
核函数是核SVM的核心概念。它定义了如何将原始输入数据映射到高维特征空间中。常用的核函数包括线性核函数、多项式核函数、高斯核函数(RBF核函数)和sigmoid核函数等。这些核函数能够处理各种复杂的非线性关系,使得核SVM能够更好地适应实际问题的分类需求。
核SVM的训练过程与线性SVM类似,目标是找到一个最大间隔超平面,使得离超平面最近的数据点到超平面的距离最大。不同的是,核SVM将这个过程应用于特征空间中的数据点,而不是原始输入空间中的数据点。
核SVM具有以下特点和优势:
- 能够处理非线性分类问题,适用于各种复杂的数据关系。
- 具有很强的泛化能力,能够处理小样本和高维数据。
- 通过适当选择和调整核函数,可以灵活地适应不同的数据特点。
- 在实际应用中取得了很好的效果,被广泛用于文本分类、图像分类、生物信息学、金融预测等领域。
from sklearn.datasets import make_circles
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
def plot_svc_decision_function(model, ax=None, plot_support=True):
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape)
ax.contour(X, Y, P, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
if plot_support:
ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=300, linewidth=1, facecolors='none')
ax.set_xlim(xlim)
ax.set_ylim(ylim)
X, y = make_circles(100, factor=0.1, noise=0.1)
clf = SVC(kernel='linear').fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(clf, plot_support=False)
plt.show()
from mpl_toolkits import mplot3d
import numpy as np
r = np.exp(-(X** 2).sum(1))
def plot_3D(elev=30, azim=30, X=X, y=y):
ax = plt.subplot(projection='3d')
ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='autumn')
ax.view_init(elev=elev, azim=azim)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plot_3D(elev=45, azim=45, X=X, y=y)
plt.show()
#核变换
from sklearn.svm import SVC
# 引入径向基函数,进行核变换
clf = SVC(kernel='rbf', C=1E6) # 引入径向基函数
clf.fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=300, lw=1, facecolors='none')
plt.show()
5.SVM回归
SVM回归(Support Vector Machine Regression,SVM回归)是支持向量机(SVM)算法的一种应用,用于解决回归问题。与传统的线性回归方法不同,SVM回归通过构建一个最优的超平面,最大化离超平面最近的训练样本的间隔来进行回归预测。
SVM回归的目标是找到一个超平面,使得训练样本与超平面之间的距离最小,并且预测值与真实值之间的误差最小。与分类问题不同,SVM回归的目标是使得训练样本落在超平面的边界上或在间隔内,而不是完全分开。
SVM回归的基本思想是通过引入一个惩罚项来控制预测误差和模型的复杂度。常用的惩罚项有ε-insensitive loss函数和平方惩罚函数。在训练过程中,SVM回归通过调整支持向量和超平面的位置,以最小化训练样本的误差,并且尽量满足间隔最大化的条件。
SVM回归具有以下特点和优势:
- 能够处理非线性回归问题,适用于各种复杂的数据关系。
- 具有很强的泛化能力,能够处理小样本和高维数据。
- 通过控制惩罚项,可以控制模型的复杂度,避免过拟合问题。
- 在实际应用中取得了很好的效果,被广泛用于金融预测、生态学建模、天气预测等领域。
然而,SVM回归也有一些挑战和注意事项。与分类问题相比,回归问题更加复杂,需要更多的计算资源和时间来训练模型。此外,在选择核函数和调整惩罚项的参数时,需要根据具体问题和数据特点进行优化。正确选择合适的核函数和参数可以提高模型的性能,而错误的选择可能导致预测性能下降。因此,合理的模型调参和交叉验证是SVM回归中重要的步骤。
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR
# 加载波士顿房价数据集
boston = fetch_openml(name='boston')
# 将数据分割成训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=33, test_size=0.25)
# 标准化特征
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)
# 使用不同核函数训练和评估SVR模型
svr_linear = SVR(kernel='linear')
svr_linear.fit(x_train, y_train)
linear_score = svr_linear.score(x_test, y_test)
print("线性核函数得分:", linear_score)
svr_poly = SVR(kernel='poly')
svr_poly.fit(x_train, y_train)
poly_score = svr_poly.score(x_test, y_test)
print("多项式核函数得分:", poly_score)
svr_rbf = SVR(kernel='rbf')
svr_rbf.fit(x_train, y_train)
rbf_score = svr_rbf.score(x_test, y_test)
print("高斯径向基核函数得分:", rbf_score)
6.SVM参数
常用的SVM模型参数的介绍:
-
Kernel(核函数):SVM模型通过将数据映射到高维空间来处理非线性问题。核函数用于定义这个映射关系。常用的核函数包括线性核(linear)、多项式核(polynomial)、高斯径向基函数(radial basis function,RBF)等。选择合适的核函数取决于数据的特征和问题的性质。
-
C(惩罚参数):C是SVM模型中的一个重要参数,用于控制错误分类的惩罚程度。较大的C值表示更严格的惩罚,模型将更倾向于选择更复杂的决策边界,容易导致过拟合。较小的C值将导致模型选择较简单的决策边界,可能导致欠拟合。
-
Gamma(高斯核参数):当选择高斯径向基函数作为核函数时,需要调整Gamma参数。Gamma参数控制高斯核的宽度,即决策边界的曲率。较大的Gamma值会导致决策边界更加复杂,可能导致过拟合。较小的Gamma值会导致决策边界更加平滑,可能导致欠拟合。
-
Degree(多项式核参数):当选择多项式核作为核函数时,需要调整Degree参数。Degree参数控制多项式核的阶数。较高的Degree值可以捕捉更复杂的模式,但也会增加模型的计算复杂度。
-
Support Vectors(支持向量):支持向量是SVM模型中最重要的样本点,决定了模型的决策边界。支持向量的数量和位置取决于核函数的选择和参数的调整。较少的支持向量数量通常表示模型具有较好的泛化能力。
from sklearn.datasets import make_blobs
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
# 定义画决策边界的函数
def plot_svc_decision_function(model, ax=None):
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# 创建网格来评估模型
x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape)
# 绘制决策边界和边界的两侧
ax.contour(X, Y, P, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
# 生成数据集
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.8)
# 将离散度改为0.8
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plt.show()
# 比较C的大小对结果的影响
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.8)
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
for axi, C in zip(ax, [20, 0.2]):
# 将C分别设定为20和0.2,看其对结果的影响
model = SVC(kernel='linear', C=C).fit(X, y)
axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=300, lw=1, facecolors='none')
axi.set_title('C ={0:.1f} '.format(C), size=14)
plt.show()
# 调节参数gamma
X, y = make_blobs(n_samples = 100, centers = 2, random_state =0, cluster_std= 1.1)
fig,ax =plt.subplots(1, 2,figsize=(16,6))
fig. subplots_adjust( left = 0.0625, right = 0.95, wspace = 0.1)
for axi,gamma in zip(ax,[20,0.1]):
#比较gamma为20和0.1对结果的影响
model = SVC(kernel = 'rbf', gamma = gamma).fit(X, y)
axi.scatter(X[:,0], X[:,1], c=y, s=50, cmap = 'autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[ :, 0], model. support_vectors_[ :,1],s = 300, lw=1,facecolors = 'none')
axi.set_title( 'gamma={0:.1f}'.format(gamma),size = 14)
plt.show()
7.集成方法分类器
集成方法(ensemble methods)是一种将多个分类器组合在一起进行分类的机器学习技术。集成方法在实践中通常比单个分类器表现更好,因为它可以通过结合多个分类器的预测结果来减少模型的偏差和方差。以下是几种常见的集成方法分类器:
-
随机森林(Random Forest):随机森林是一种基于决策树的集成方法。它通过对训练数据进行自助采样(bootstrap)生成多个训练集,然后针对每个训练集构建一个决策树。最后,通过投票或平均预测结果来进行分类。随机森林具有很强的泛化能力和抗过拟合能力。
-
提升方法(Boosting):提升方法是一种迭代的集成方法,通过训练一系列弱分类器(如决策树)来构建一个强分类器。每个分类器的训练都会根据前一个分类器的结果进行调整,使得集成模型的性能逐步提升。常见的提升方法包括AdaBoost、梯度提升(Gradient Boosting)和XGBoost。
-
装袋法(Bagging):装袋法是一种基于自助采样的集成方法,通过对训练数据进行有放回抽样生成多个训练集,并使用这些训练集训练多个基分类器。最后,通过投票或平均预测结果来进行分类。常见的装袋法包括随机森林和Bagging分类器。
-
Stacking:Stacking是一种将多个分类器组合起来进行分类的集成方法。与其他方法不同,Stacking不仅仅是简单地通过投票或平均结果来进行分类,而是将多个分类器的预测结果作为输入,训练一个元分类器来进行最终的分类。Stacking可以通过交叉验证来选择最佳的组合。
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_moons
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
X, y = make_moons(n_samples=100, noise=0.25, random_state=3)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
log_clf = LogisticRegression()
rnd_clf = RandomForestClassifier()
svm_clf = SVC()
voting_clf = VotingClassifier(estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)], voting='hard')
for clf in (log_clf, rnd_clf, svm_clf, voting_clf):
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(clf.__class__.__name__, accuracy_score(y_test, y_pred))
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
# 确保 max_samples 不超过训练集样本数量
max_samples = min(100, len(X_train)) # 假设设置最大样本数量为100或者训练集样本数量,取较小值
bag_clf = BaggingClassifier(DecisionTreeClassifier(), n_estimators=500, max_samples=max_samples, bootstrap=True, n_jobs=-1)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)
8.随机森林
随机森林(Random Forest)是一种基于决策树的集成学习方法。随机森林在机器学习和数据挖掘领域广泛应用,因其在处理大规模数据和高维数据时表现出色,并且具有很好的泛化能力和鲁棒性。
随机森林由多个决策树组成,每个决策树都是由对训练集进行自助采样(bootstrap)得到的子样本训练而成。随机森林的核心思想是通过组合多个决策树的预测结果,来减少模型的偏差和方差。
在构建每个决策树时,随机森林引入了两个随机性源:特征随机性和样本随机性。特征随机性指的是在每个决策树的节点处,随机选择一部分特征进行划分。这样可以确保每个决策树都使用了不同的特征子集,增强了模型的多样性。样本随机性指的是从训练集中随机选择一部分样本进行训练,这样在某个节点进行划分时,仅考虑该节点所包含的样本。
随机森林的预测结果是通过对每个决策树的预测结果进行投票或平均得到的。对于分类问题,采用投票机制,多数决定最终的分类结果;对于回归问题,采用平均机制,对所有决策树的预测结果进行平均。
随机森林具有以下特点:
- 具有很好的泛化能力,能有效处理大规模数据和高维数据;
- 对于离群点和噪声具有一定的鲁棒性;
- 能够评估特征的重要性,可以用于特征选择;
- 可以并行处理,提高训练速度和效率。
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
def plot_feature_importances_cancer(model):
n_features = cancer.data.shape[1]
plt.barh(range(n_features), model.feature_importances_, align='center')
plt.yticks(range(n_features), cancer.feature_names)
plt.xlabel("Feature Importance")
plt.ylabel("Feature")
plt.show()
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)
# 使用BaggingClassifier
bag_clf = BaggingClassifier(DecisionTreeClassifier(), n_estimators=500, max_samples=100, bootstrap=True, n_jobs=-1)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)
# 使用RandomForestClassifier
forest = RandomForestClassifier(n_estimators=100, random_state=0)
forest.fit(X_train, y_train)
print("Accuracy on training set: {:.3f}".format(forest.score(X_train, y_train)))
print("Accuracy on test set: {:.3f}".format(forest.score(X_test, y_test)))
plot_feature_importances_cancer(forest)
from sklearn.ensemble import AdaBoostClassifier
ada_clf = AdaBoostClassifier(
DecisionTreeClassifier(max_depth= 1),n_estimators = 200,algorithm = "SAMME.R", learning_rate=0.5)
ada_clf.fit(X_train, y_train)
from sklearn.tree import DecisionTreeRegressor
tree_reg1 = DecisionTreeRegressor(max_depth= 2)
tree_reg1.fit(X,y)
#针对第一个预测器的残差训练第二个回归器
y2 =y - tree_reg1.predict(X)
tree_reg2 =DecisionTreeRegressor( max_depth= 2)
tree_reg2.fit(X,y2)
#针对第二个预测器的残差训练第三个回归器
y3 =y2 - tree_reg2.predict(X)
tree_reg3 = DecisionTreeRegressor(max_depth= 2)
tree_reg3.fit(X,y3)
#对新实例进行预测
y_pred = sum(tree.predict(X) for tree in(tree_reg1, tree_reg2,tree_reg3))
9.梯度提升法
梯度提升法(Gradient Boosting)是一种基于决策树的集成学习方法,它通过迭代地训练多个弱学习器来构建一个强学习器。与随机森林不同,梯度提升法是通过优化损失函数来构建模型,而不是通过投票或平均来组合多个模型的预测结果。
梯度提升法的核心思想是通过迭代的方式不断优化模型的预测结果。每一轮迭代中,梯度提升法使用一个弱学习器(通常是决策树)去拟合当前模型的残差(预测结果与真实值之间的差异),然后将这个弱学习器的预测结果与当前模型的预测结果进行加权累加,得到新的预测结果。这个过程类似于梯度下降,不断地朝着最小化损失函数的方向优化模型。
在构建每个弱学习器时,梯度提升法采用了一种贪心算法,即每一步只关注当前最优的拟合。同时,梯度提升法引入了学习率参数来控制每个弱学习器的贡献程度,通过缩小学习率可以增加模型的鲁棒性和泛化能力。
梯度提升法具有以下特点:
- 强大的预测能力,能够处理各种类型的数据;
- 相比于随机森林,梯度提升法对于噪声和离群点更加敏感;
- 可以处理高维稀疏特征;
- 能够评估特征的重要性。
梯度提升法在实践中广泛应用于回归问题和分类问题,尤其在Kaggle等数据竞赛中取得了很好的成绩。常见的梯度提升法包括XGBoost、LightGBM和CatBoost等。
from sklearn.ensemble import GradientBoostingRegressor
gbrt = GradientBoostingRegressor(max_depth= 2,n_estimators= 3, learning_rate= 1.0)
gbrt. fit(X, y)
#超参数learning_rate对每棵树的贡献进行缩放。如果你将其设置为低值,比如0.1,#则需要更多的树来拟合训练集,但是预测的泛化效果通常更好
#下面是在乳腺癌数据集上应用GradientBoostingClassifier的示例.默认使用#100棵树,最大深度是3,学习率为0.1
from sklearn.ensemble import GradientBoostingClassifier
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target,random_state= 0)
gbrt = GradientBoostingClassifier(random_state= 0)
gbrt. fit(X_train, y_train)
print("Accuracy on training set:{:.3f}".format(gbrt.score(X_train, y_train)))
print("Accuracy on test set: {:.3f}". format(gbrt.score(X_test, y_test)))
#由于训练集精度达到100 %,所以很可能存在过拟合.为了降低过拟合,可以限制最大深#度来加强预剪枝,这里将max depth=1
gbrt = GradientBoostingClassifier(random_state = 0, max_depth = 1)
gbrt.fit(X_train, y_train)
print( "Accuracy on training set:{:.3f}".format(gbrt.score(X_train, y_train)))
print(" Accuracy on test set: {:.3f}". format(gbrt.score(X_test, y_test)))
#也可以降低学习率,将学习率设为0.01
gbrt = GradientBoostingClassifier(random_state = 0, learning_rate=0.01)
gbrt.fit(X_train, y_train)
print( "Accuracy on training set:{:.3f}". format( gbrt.score(X_train,y_train)))
print(" Accuracy on test set:{:.3f}". format( gbrt.score(X_test, y_test)))
gbrt = GradientBoostingClassifier(random_state = 0,max_depth = 1)
gbrt. fit(X_train, y_train)
plot_feature_importances_cancer(gbrt)
10.激活函数
激活函数是神经网络中非线性变换的关键组成部分,它将输入信号综合成输出信号,并且在神经网络的节点之间传递。激活函数的引入使得神经网络具备了强大的非线性拟合能力,能够解决复杂的模式识别和回归问题。
常见的激活函数有以下几种:
-
Sigmoid函数:Sigmoid函数是最早使用的一种激活函数,它将输入信号压缩到[0, 1]的范围内。它的数学表达式为:f(x) = 1 / (1 + exp(-x))。Sigmoid函数在处理二分类问题和神经网络的隐藏层中仍然有一定的应用。
-
双曲正切函数(Tanh函数):Tanh函数将输入信号压缩到[-1, 1]的范围内,它的数学表达式为:f(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))。Tanh函数在处理多分类问题中常用。
-
ReLU函数:ReLU函数(Rectified Linear Unit)在神经网络中应用广泛。它将负数输入压缩到0,而正数输入则保持不变。ReLU函数的数学表达式为:f(x) = max(0, x)。ReLU函数解决了梯度消失问题和加速训练的问题,但是在处理负数输入时会失活,引入了一些改进的版本,如Leaky ReLU和Parametric ReLU等。
-
Softmax函数:Softmax函数主要用于多类别分类问题中,它将输入信号转化为概率分布,使得输出满足概率的要求。Softmax函数的数学表达式为:f(x) = exp(xi) / Σ(exp(xj)),其中xi为输入向量的第i个元素。
line= np.linspace(-3,3,100)
plt.plot(line, np.tanh( line),label = "tanh")
plt.plot(line,np. maximum( line,0),label = "relu")
plt.legend( loc= "best")
plt.xlabel("x")
plt.ylabel( "relu(x), tanh(x)")
11.神经网络手写数字识别
神经网络手写数字识别是一种应用深度学习技术的图像识别任务,目标是将手写数字的图像输入神经网络模型,并输出对应的数字标签。
该任务通常使用卷积神经网络(CNN)来完成。CNN是一种专门用于图像处理的深度学习模型,具有良好的特征提取和模式识别能力。
神经网络手写数字识别的工作流程如下:
-
数据准备:首先,需要收集手写数字的图像数据集,通常使用的是MINST数据集,该数据集包含了大量的手写数字图像和对应的标签。将数据集划分为训练集和测试集,用于模型的训练和评估。
-
网络架构设计:设计一个适合手写数字识别任务的神经网络架构。通常使用卷积层提取图像的特征,然后通过全连接层将特征映射到输出类别。
-
模型训练:使用训练集来训练神经网络模型。训练过程中,通过反向传播算法不断调整网络的参数,使得模型能够适应手写数字的特征。训练过程通常需要多个轮次,直到达到一定的准确率。
-
模型评估:使用测试集来评估训练好的模型的性能。通过计算模型在测试集上的准确率、精确度、召回率等指标来判断模型的效果。
-
预测应用:训练好的模型可以用于预测新的手写数字图像。将待预测的图像输入模型,模型将输出对应的数字标签。
#需要的第三方包
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split#用于划分训练集和测试集
from sklearn. neural_network import MLPClassifier#多层感知机模型
#获取手写数字的数据集
digits = datasets. load_digits()#得到手写数字的数据集
print(digits.data.shape)#样本数和特征数
print(digits.target.shape)#标签数
print(digits.images.shape)
def draw():
#显示前面36个
for i in range( 36):
plt.subplot(6,6,i+1)#以6行6列进行显示,并从1开始(i=0)
plt.imshow(digits.images[i])#图片绘制
plt.show()#图片显示
pass
draw()
运行结果为手写数字0-9,上述仅展示部分输出。
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
digits = load_digits()
x = digits.data # 获取特征数据
y = digits.target # 获取标签数据
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2) # 将数据集划分为训练集和测试集
mlp = MLPClassifier(hidden_layer_sizes=(300,), activation='relu') # 构建MLP模型
mlp.fit(x_train, y_train) # 训练模型
y_predict = mlp.predict(x_test) # 得到预测结果
print(y_predict) # 预测结果
print(y_test) # 真实结果
score = mlp.score(x_test, y_test) # 计算准确率
print(score)
12.神经网络分类
神经网络分类是指使用神经网络模型对输入数据进行分类的任务。分类问题是机器学习中最常见的问题之一,其目标是将输入数据划分到预定义的类别中。
通常,神经网络分类任务的工作流程如下:
-
数据准备:收集和准备用于分类的数据集。数据集包含一个或多个特征(即输入)和相应的标签(即输出类别)。数据集被分为训练集和测试集,用于训练和评估模型。
-
网络架构设计:设计适合分类任务的神经网络架构。常见的架构包括多层感知机(MLP)、卷积神经网络(CNN)和循环神经网络(RNN)等。根据问题的复杂性和数据的特征,选择合适的架构。
-
模型训练:使用训练集来训练神经网络模型。训练过程中,通过反向传播算法更新网络的权重和偏置,使得模型能够适应数据特征并学习分类的决策边界。训练过程可能需要多个轮次(称为迭代),直到达到一定的准确率或损失收敛。
-
模型评估:使用测试集来评估训练好的模型的性能。通过计算模型在测试集上的准确率、精确度、召回率、F1得分等指标来评估模型的效果。如果模型性能不够好,可以进行调参、增加数据量或添加其他正则化方法等来改进模型。
-
预测应用:将新的未标记数据输入训练好的模型,模型将输出对应的类别标签。这些预测结果可用于不同的应用领域,如图像分类、文本分类、声音分类等。
神经网络分类广泛应用于图像识别、文本分类、情感分析、语音识别等领域,并且其在大规模数据和复杂问题上的优势使其成为当前机器学习和深度学习应用中的重要技术。
from sklearn. neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt
cancer= load_breast_cancer()
x_train, X_test, y_train, y_test =train_test_split(cancer.data,cancer. target,random_state= 0)
mlp =MLPClassifier(random_state= 42)
mlp.fit(X_train, y_train)
print( "Accuracy on training set:{:.2f}".format(mlp.score(X_train, y_train)))
print( "Accuracy on test set:{:.2f}".format(mlp.score(X_test, y_test)))
#计算训练集中每个特征的平均值
mean_on_train = X_train.mean(axis = 0)
#计算训练集中每个特征的标准差
std_on_train = X_train.std( axis = 0)
#减去平均值,然后乘以标准差的倒数
#如此运算之后,mean= 0, std= 1
X_train_scaled=(X_train - mean_on_train) / std_on_train
#对测试集做相同的变换(使用训练集的平均值和标准差)
X_test_scaled= (X_test - mean_on_train) / std_on_train
mlp = MLPClassifier(random_state = 0)
mlp.fit(X_train_scaled , y_train)
print( "Accuracy on training set:{:.3f}".format(mlp. score(X_train_scaled, y_train)))
print( " Accuracy on test set: {:.3f}".format(mlp.score(X_test_scaled, y_test)))
mlp = MLPClassifier(max_iter= 1000,random_state = 0)
mlp.fit(X_train_scaled, y_train)
print( "Accuracy on training set:{:.3f}".format(mlp.score(X_train_scaled, y_train)))
print( "Accuracy on test set:{:.3f}".format(mlp.score(X_test_scaled, y_test)))
mlp=MLPClassifier(max_iter = 1000,alpha = 1, random_state= 0)
mlp.fit(X_train_scaled, y_train)
print( "Accuracy on training set:{:.3f}".format(mlp.score(X_train_scaled, y_train)))
print( " Accuracy on test set:{:.3f}". format(mlp. score(X_test_scaled,y_test)))
13.分类器的不确定度
分类器的不确定度是指分类器对于某个样本预测所表现出的不确定性或不可信程度。在分类问题中,不同的样本可能具有不同的不确定度。
分类器的不确定度可以通过以下几个方面来衡量:
-
置信度或概率:一些分类器可以输出样本属于每个类别的概率或置信度。较高的置信度意味着分类器对于预测结果较为确定,较低的置信度则表示分类器对于预测结果存在疑虑。一些常见的分类器如朴素贝叶斯和逻辑回归可以输出概率值。
-
决策边界:分类器对于样本的预测结果可能会受到样本在决策边界附近的位置影响。如果样本在决策边界附近,分类器可能对于预测结果存在较大的不确定度。
-
样本噪声:如果输入数据中存在噪声或异常值,分类器可能对于这些样本的预测结果存在较大的不确定度。
-
数据分布:分类器在对于某些数据分布的样本进行分类时可能表现出较高的不确定度。例如,在训练数据中未见过的样本,或者在边界附近的样本,分类器对于这些样本的预测结果可能会更加不确定。
对于分类器的不确定度,我们可以使用一些方法来处理:
-
模型融合:使用多个分类器进行集成学习,例如使用投票或平均的方式来综合多个分类器的预测结果,以减少不确定度。
-
置信度阈值:设定一个置信度阈值,只接受那些置信度高于阈值的样本预测结果,从而减少不确定度较高的预测结果的使用。
-
数据清洗:通过对数据进行清洗、去除异常值或噪声的方式,可以降低不确定度。
from sklearn. ensemble import GradientBoostingClassifier
from sklearn.datasets import make_circles
X,y =make_circles(noise = 0.25, factor = 0.5,random_state = 1)
#为了便于说明,将两个类别重命名为"blue”和"red”
y_named = np.array(["blue", "red"])[y]
#可以对任一个数组调用train_test_split#所有数组的划分方式都是一致的
X_train, X_test, y_train_named, y_test_named, y_train, y_test = train_test_split(X,y_named, y, random_state= 0)
#构建梯度提升模型
gbrt = GradientBoostingClassifier(random_state = 0)
gbrt.fit(X_train, y_train_named)
print("x_test.shape:{}".format(X_test.shape))
print( "Decision function shape: {}".format(gbrt.decision_function(X_test).shape))
print(y_test[:6])
#对于类别1来说,这个值表示模型对该数据点属于"正"类的置信程度。
#类的偏好,负值表示对"反"类(其他类)的偏好
#显示decision_function的前几个元素
print("Decisionfunction:\n{}".format(gbrt.decision_function(X_test)[:6]))
print("Thresholded decision function:\n{}".format(gbrt.decision_function(X_test)>0))
print("Shape of probabilities:{}".format(gbrt.predict_proba(X_test).shape))
print("Predicted probabilities:\n{}".format(gbrt.predict_proba(X_test[:6])))
学习总结
支持向量机(Support Vector Machine)是一种常用的机器学习算法,在分类和回归问题中都有广泛的应用。它的核心思想是找到一个最优的超平面来将不同类别的样本分开,使得样本点到超平面的距离最大化。支持向量机的优点是能够处理高维数据和非线性问题,同时对于小样本数据具有较好的泛化能力。
集成学习方法(Ensemble Learning)是一种将多个弱分类器组合成强分类器的技术。通过对多个分类器的预测结果进行综合,可以获得更准确的预测结果。常见的集成学习方法有随机森林、Adaboost等。集成学习的优点是可以降低模型的方差,减少过拟合的风险。
神经网络(Neural Network)是一种模拟人脑神经系统工作方式的模型。神经网络由多个神经元组成,每个神经元接收多个输入,并通过激活函数将输入转化为输出。神经网络的优点是可以处理大规模的数据和复杂的非线性关系,具有很强的拟合能力。但是神经网络的训练需要大量的数据和计算资源,且模型的可解释性较差。
分类器的不确定度是指分类器对于预测样本的确定程度。分类器的不确定度可以用来评估分类器的可靠性和鲁棒性。常用的评估不确定度的方法有熵、基尼系数等。通过对分类器的不确定度进行分析,可以帮助我们更好地理解模型的预测结果和调整模型的参数。