机器学习 #1

· 1939字 · 4分钟

机器学习 🔗

K-近邻算法 🔗

K近邻算法(K-Nearest Neighbors,简称KNN)是一种简单且有效的分类和回归算法。以下是K近邻算法的基本流程:

数据准备: 🔗

  • 收集数据:准备训练数据集和测试数据集。每个数据点需要有明确的标签(分类问题)或目标值(回归问题)。
  • 预处理数据:包括数据清洗、特征选择和特征缩放(如标准化或归一化),以确保各特征具有相同的尺度。

选择参数K: 🔗

  • 确定K值:K表示选择最近的K个邻居。K值的选择需要综合考虑,K值过小容易受噪声影响,K值过大则会使分类边界过于平滑。

计算距离: 🔗

  • 计算待分类数据点与训练数据集中每个数据点之间的距离。常用的距离度量方法包括欧氏距离、曼哈顿距离等。

选择最近的K个邻居: 🔗

  • 根据计算的距离,将训练数据集中的数据点按照距离从小到大排序,选择前K个最近的邻居。

投票机制(分类问题): 🔗

  • 分类问题:统计K个邻居中各类别出现的频率,选择频率最高的类别作为待分类数据点的预测类别。
  • 回归问题:计算K个邻居的平均值或加权平均值作为待预测数据点的目标值。

评估模型: 🔗

  • 使用测试数据集对模型进行评估,常用的评估指标包括准确率(分类问题)、均方误差(回归问题)等。
  • 如果模型效果不理想,可以调整K值或对数据进行进一步处理。

模型应用: 🔗

  • 在实际应用中,将新的数据点输入模型,按照上述步骤进行预测。

K近邻算法的优点在于简单直观,不需要显式的训练过程,但其缺点是计算复杂度高,尤其是在数据量大时,效率较低。此外,KNN对数据的尺度和噪声敏感,因此数据预处理非常重要。

使用sklearn的样例代码 🔗

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt

# 生成简单的二维数据集
np.random.seed(42)
X, y = np.array([[np.random.rand(), np.random.rand()] for _ in range(100)]), np.random.randint(0, 2, 100)

# 将数据集分成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建KNN分类器,选择K值为3
knn = KNeighborsClassifier(n_neighbors=3)

# 训练模型
knn.fit(X_train, y_train)

# 进行预测
y_pred = knn.predict(X_test)

# 计算并打印准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")

# 可视化数据和分类边界
h = .02  # 网格中的步长

# 创建颜色映射
cmap_light = plt.cm.Pastel1
cmap_bold = plt.cm.Set1

# 为绘图准备网格
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))

# 在网格上进行预测
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.figure()
plt.pcolormesh(xx, yy, Z, cmap=cmap_light)

# 绘制训练点和测试点
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cmap_bold, edgecolor='k', s=20, label="Training points")
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cmap_bold, edgecolor='k', s=50, marker='*', label="Testing points")

plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("3-Class classification (k = 3)")
plt.legend()
plt.show()

决策树 🔗

决策树算法是一种常用于分类和回归任务的监督学习算法。决策树通过将数据集分成更小的子集,同时逐渐构建关联决策的树结构。以下是决策树算法的基本流程:

数据准备: 🔗

  • 收集数据:准备训练数据集和测试数据集。每个数据点需要有明确的标签(分类问题)或目标值(回归问题)。
  • 预处理数据:包括数据清洗、特征选择和特征转换。

选择最佳分割特征和分割点: 🔗

  • 计算特征的重要性:对于每个特征,根据不同的分割点计算分割前后的信息增益(Information Gain)、基尼不纯度(Gini Impurity)或均方误差(Mean Squared Error)。
  • 选择最佳分割特征和分割点:选择能够最大化信息增益或最小化基尼不纯度、均方误差的特征及其分割点。

创建节点: 🔗

  • 根节点:在初始阶段,选择最佳特征和分割点作为根节点,将数据集分成两部分。
  • 子节点:对于每个子集,重复步骤2,创建新的节点,继续将数据集划分成更小的子集,形成树的分支。

递归分割: 🔗

  • 递归创建子节点:对每个子节点重复上述步骤,直到满足停止条件。常见的停止条件包括:
    • 达到最大树深度。
    • 每个节点的数据点数量小于预设的最小样本数。
    • 所有数据点的标签相同(分类问题)或误差在可接受范围内(回归问题)。

构建树: 🔗

  • 叶节点:当达到停止条件时,将当前节点标记为叶节点。叶节点的值为该节点中数据点的多数类(分类问题)或平均值(回归问题)。

预测: 🔗

  • 通过树进行预测:对于新的数据点,从根节点开始,根据特征值进行分支,直到到达叶节点,叶节点的值即为预测结果。

评估模型: 🔗

  • 使用测试数据集评估模型性能:分类问题中常用准确率、精确率、召回率等指标,回归问题中常用均方误差等指标。

剪枝(可选): 🔗

  • 剪枝以防止过拟合:可以通过预剪枝(Pre-pruning)或后剪枝(Post-pruning)方法来简化决策树结构,防止过拟合。
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

# 加载鸢尾花数据集
iris = load_iris()
X, y = iris.data, iris.target

# 将数据集分成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建决策树分类器
clf = DecisionTreeClassifier(max_depth=3)

# 训练模型
clf.fit(X_train, y_train)

# 进行预测
y_pred = clf.predict(X_test)

# 计算并打印准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")

# 可视化决策树
plt.figure(figsize=(12, 8))
plot_tree(clf, filled=True, feature_names=iris.feature_names, class_names=iris.target_names)
plt.show()

# 可视化数据点和分类边界(仅限于二维特征可视化)
# 由于鸢尾花数据集有四个特征,这里我们选择其中两个特征进行可视化
X_2d = X[:, :2]  # 选择前两个特征进行可视化
X_train_2d, X_test_2d = X_train[:, :2], X_test[:, :2]

clf_2d = DecisionTreeClassifier(max_depth=3)
clf_2d.fit(X_train_2d, y_train)

x_min, x_max = X_2d[:, 0].min() - 0.1, X_2d[:, 0].max() + 0.1
y_min, y_max = X_2d[:, 1].min() - 0.1, X_2d[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
                     np.arange(y_min, y_max, 0.01))

Z = clf_2d.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.Paired)
plt.scatter(X_train_2d[:, 0], X_train_2d[:, 1], c=y_train, edgecolor='k', label="Training points")
plt.scatter(X_test_2d[:, 0], X_test_2d[:, 1], c=y_test, edgecolor='k', marker='*', s=100, label="Testing points")
plt.legend()
plt.title("Decision Tree Classification with Iris Dataset")
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.show()