赞
踩
国际权威的学术组织 the IEEE International Conference on Data Mining (ICDM) 早前评选出了数据挖掘领域的十大经典算法:C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, kNN, Naive Bayes, and CART。
在此,花哥我深入介绍下这些算法的原理及实践经验,并补充介绍下当下热门的集成学习与神经网络模型。
模型原理: C4.5 是决策树算法的一个扩展,它使用信息增益率来选择分裂属性。C4.5 可以处理连续和离散属性,并能处理具有缺失值的数据集。
训练过程:
从根节点开始,使用信息增益率选择最佳属性进行分裂。
递归地对每个分支的子集重复上述过程,直到满足停止条件(如所有实例都属于同一类,或没有剩余属性可用)。
优点:
易于理解和解释。
能够处理具有缺失值的数据。
缺点:
容易过拟合。
对属性的顺序敏感。
适用场景: 适用于处理连续和离散特征的分类任务,尤其是当解释性很重要时。
Python 示例代码: C4.5 算法的直接实现并不在 Scikit-learn 库中,但决策树算法与 C4.5 非常相似。
- from sklearn.datasets import load_iris
- from sklearn.tree import DecisionTreeClassifier
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score
-
- # 加载数据
- iris = load_iris()
- X = iris.data
- y = iris.target
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
-
- # 创建决策树分类器
- clf = DecisionTreeClassifier(criterion='entropy')
-
- # 训练模型
- clf.fit(X_train, y_train)
-
- # 预测测试集
- y_pred = clf.predict(X_test)
-
- # 评估模型
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
模型原理: k-Means 是一种无监督学习算法,用于将数据点划分为 k 个集群。它通过迭代更新每个集群的质心(即集群中所有点的均值)来工作。
训练过程:
随机选择 k 个点作为初始质心。
将每个点分配给最近的质心,形成 k 个集群。
重新计算每个集群的质心。
重复上述步骤,直到质心不再显著变化或达到预设的迭代次数。
优点:
简单、高效。
对大数据集有良好的可伸缩性。
缺点:
需要预先设定 k 值。
对初始质心的选择敏感。
可能陷入局部最优。
适用场景: 数据聚类,例如市场细分、图像分割等。
Python 示例代码:
- from sklearn.cluster import KMeans
- import numpy as np
-
- # 创建随机数据
- X = np.random.rand(100, 2)
-
- # 定义KMeans模型,设置k为3
- kmeans = KMeans(n_clusters=3, random_state=42)
-
- # 训练模型
- kmeans.fit(X)
-
- # 获取聚类标签和质心
- labels = kmeans.labels_
- centroids = kmeans.cluster_centers_
-
- print("Labels:", labels)
- print("Centroids:", centroids)
模型原理:
SVM(Support Vector Machine)是一种基于监督学习的分类算法,其核心思想是找到一个超平面,使得不同类别的样本之间的间隔最大化。这个间隔被称为“margin”,而位于 margin 上的样本点则被称为“支持向量”。通过最大化 margin,SVM 可以有效地处理高维数据,并且在很多情况下对噪声和异常值具有较好的鲁棒性。
对于非线性可分的数据,SVM 通过引入核函数(如线性核、多项式核、RBF 核等)将数据映射到高维空间,使其在高维空间中线性可分。这样,SVM 就能够处理复杂的非线性分类问题。
模型训练:
SVM 的训练过程涉及求解一个凸优化问题。具体来说,我们需要找到一组权重向量 w 和偏置项 b,使得分类函数 f(x) = w·x + b 能够将不同类别的样本正确分开,并且 margin 最大化。这通常通过求解一个二次规划问题来实现,其中目标函数是 margin 的平方,约束条件则是样本点被正确分类。
对于非线性 SVM,我们还需要选择合适的核函数,并通过求解对偶问题来找到最优的超平面。
优点:
在高维空间中表现良好,适用于特征维度较高的情况。
对噪声和异常值具有较好的鲁棒性。
通过引入核函数,能够处理非线性分类问题。
缺点:
当数据集规模较大时,训练过程可能较慢。
对参数(如惩罚系数 C 和核函数参数)的选择敏感,需要调参。
对于多分类问题,通常需要构建多个二分类器进行组合。
适用场景:
SVM 适用于中小规模数据集的分类问题,特别是当数据具有较高的维度或呈现非线性关系时。它在文本分类、图像识别、生物信息学等领域有广泛应用。
Python 示例代码:
- from sklearn import svm
- from sklearn.datasets import make_classification
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score
-
- # 生成分类数据集
- X, y = make_classification(n_samples=1000, n_features=20, n_informative=2, n_redundant=10, random_state=42)
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
-
- # 创建SVM分类器
- clf = svm.SVC(kernel='linear', C=1.0, random_state=42)
-
- # 训练模型
- clf.fit(X_train, y_train)
-
- # 预测测试集
- y_pred = clf.predict(X_test)
-
- # 评估模型
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
模型原理:Apriori 算法是一种用于发现频繁项集和关联规则的经典算法。它基于两个重要的性质来减少搜索空间:
如果一个项集是频繁的,那么它的所有子集也一定是频繁的。 如果一个项集是非频繁的,那么它的所有超集也一定是非频繁的。 利用这两个性质,Apriori 算法可以高效地找出所有的频繁项集。
训练过程:
初始化频繁项集列表,将每个单独的项目视为 1-项频繁集。 迭代生成更大的频繁项集,直到无法再生成新的频繁项集为止。 在每次迭代中,基于当前的频繁 k-项集生成候选的(k+1)-项集。 扫描数据库,计算每个候选集的支持度。 保留支持度大于或等于预设阈值的候选集作为新的频繁(k+1)-项集。
优点:
高效,利用性质减少了不必要的搜索。 易于理解和实现。
缺点:
可能产生大量的候选项集,尤其是当数据集很大或支持度阈值设置较低时。 对支持度阈值的选择敏感,不同的阈值可能会导致不同的结果。
适用场景:
市场篮子分析,用于发现商品之间的关联规则。 推荐系统,基于用户的历史行为推荐相关产品。
Python 示例代码:
- from mlxtend.frequent_patterns import apriori, association_rules
- import pandas as pd
-
- # 示例数据集
- dataset = [['牛奶', '面包', '黄油'],
- ['尿布', '啤酒', '鸡蛋'],
- ['牛奶', '尿布', '啤酒', '鸡蛋'],
- ['面包', '黄油', '尿布', '啤酒'],
- ['牛奶', '面包', '尿布', '啤酒']]
-
- # 将数据集转换为适合Apriori算法的格式
- df = pd.DataFrame.from_records(dataset)
-
- # 使用Apriori算法找出频繁项集
- frequent_itemsets = apriori(df, min_support=0.6, use_colnames=True)
-
- # 生成关联规则
- rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.7)
-
- # 打印频繁项集和关联规则
- print("频繁项集:")
- print(frequent_itemsets)
- print("\n关联规则:")
- print(rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']])
模型原理:
EM 算法是一种迭代优化策略,常用于概率模型参数的估计,尤其是当模型含有隐变量时。EM 算法通过交替执行 E 步(期望步)和 M 步(最大化步)来找到参数的最大似然估计或最大后验估计。
训练过程:
初始化模型参数。
E 步:根据当前参数估计,计算隐变量的期望或概率分布。
M 步:最大化 E 步中得到的期望似然函数,更新参数。
重复 E 步和 M 步,直到参数收敛或达到预设的迭代次数。
优点:
能够处理含有隐变量的概率模型参数估计问题。 迭代过程简单,易于实现。
缺点:
可能对初始参数敏感,不同的初始值可能导致不同的收敛结果。 可能存在局部最优解而非全局最优解。
适用场景:
高斯混合模型(GMM)的参数估计。
隐马尔可夫模型(HMM)的参数估计。
Python 示例代码:通常使用 Scikit-learn 库中的 GaussianMixture 类来实现高斯混合模型的 EM 算法。
- from sklearn.mixture import GaussianMixture
- import numpy as np
-
- # 创建模拟数据
- np.random.seed(0)
- n_samples = 300
- X = np.concatenate((np.random.randn(n_samples, 2) + [5, 2],
- np.random.randn(n_samples, 2) - [2, 2]))
-
- # 定义并训练高斯混合模型
- gmm = GaussianMixture(n_components=2).fit(X)
-
- # 预测数据点的类别标签
- labels = gmm.predict(X)
-
- # 打印结果
- print("预测标签:", labels)
模型原理: PageRank 是一种由 Google 创始人 Larry Page 和 Sergey Brin 在斯坦福大学开发的算法,用于评估网页的重要性或排名。该算法基于图论,将网页视为图中的节点,网页之间的链接视为边,并通过迭代计算每个节点的 PageRank 值来评估网页的重要性。PageRank 的核心思想是,一个网页的排名(即重要性)是由所有链接到它的网页的排名决定的,且一个网页链接到的其他网页越多,它的排名贡献就越小。
训练过程:
初始化每个网页的 PageRank 值为 1,并进行归一化处理,使得所有网页的 PageRank 值之和为 1。
对于每个网页,计算其出度(即链接出去的数量),并根据出度调整链接到其他网页的 PageRank 贡献值。
迭代更新每个网页的 PageRank 值,新的 PageRank 值是所有链接到该网页的网页的 PageRank 值与对应贡献值的乘积之和。
重复上述步骤,直到 PageRank 值收敛或达到预设的迭代次数。
优点:
无需人工标注数据,自动从网页链接结构中提取信息。
考虑了网页之间的链接关系,能够反映网页的实际重要性。
缺点:
对新网页不友好,新网页由于缺少链接,PageRank 值较低。
可能受到链接作弊(如链接农场、链接交换等)的影响。
适用场景:
搜索引擎中的网页排名。
社交网络分析,评估用户或内容的影响力。
Python 示例代码: PageRank 算法通常用于图数据结构,因此可以使用网络分析库如 NetworkX 来实现。
- import networkx as nx
-
- # 创建一个简单的图
- G = nx.DiGraph()
- edges = [('A', 'B'), ('B', 'C'), ('C', 'A'), ('A', 'D'), ('D', 'A')]
- G.add_edges_from(edges)
-
- # 计算PageRank值
- pagerank = nx.pagerank(G)
-
- # 打印每个节点的PageRank值
- for node, rank in pagerank.items():
- print(f"Node {node}: PageRank {rank:.4f}")
在实际应用中,网络结构通常更加复杂,可能需要考虑更多的因素,如阻尼因子、权重等。此外,对于大型网络,PageRank 的计算可能需要优化算法以提高效率。
原理:AdaBoost(Adaptive Boosting)是一种自适应的增强学习算法,它是集成学习算法-Boosting 算法的一种具体实现,通过组合多个弱学习器来形成一个强学习器,以提高预测精度和稳定性。(boosting 另一种模型是 GBDT,它通过梯度提升的方式集成弱学习器,在每一次迭代中拟合前一轮学习器的残差,从而逐步减小预测误差。)
AdaBoost 在训练过程中为每个样本赋予一个权重,并根据前一次迭代的分类结果调整这些权重,使得后续的分类器更加关注前一次分类错误的样本。
训练过程:
初始化样本权重。
重复以下步骤直到达到预定的分类器数量或满足其他停止条件:
使用当前样本权重训练一个弱分类器。
计算该分类器的错误率。
根据错误率计算该分类器的权重。
更新样本权重,增加错误分类样本的权重,减少正确分类样本的权重。
最终的强分类器是所有弱分类器的加权组合。
优点:简单有效,对弱分类器的类型没有限制,可以很好地处理不平衡数据集。
缺点:对噪声数据和异常值敏感,可能出现过拟合。
适用场景:用于分类问题,特别是在其他简单分类器效果不佳时。
Python 示例代码:
- from sklearn.datasets import make_classification
- from sklearn.model_selection import train_test_split
- from sklearn.ensemble import AdaBoostClassifier
- from sklearn.tree import DecisionTreeClassifier
- from sklearn.metrics import accuracy_score
-
- # 生成分类数据集
- X, y = make_classification(n_samples=1000, n_features=20, n_informative=2, n_redundant=10, random_state=42)
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
-
- # 初始化弱分类器(决策树)
- weak_clf = DecisionTreeClassifier(max_depth=1)
-
- # AdaBoost分类器
- ada_clf = AdaBoostClassifier(base_estimator=weak_clf, n_estimators=50, random_state=42)
-
- # 训练AdaBoost分类器
- ada_clf.fit(X_train, y_train)
-
- # 预测
- y_pred = ada_clf.predict(X_test)
-
- # 计算准确率
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
原理:kNN 是一种基于实例的学习,或者说是非参数学习。对于一个新的样本,它根据在训练集中离该样本最近的 k 个样本的类别来进行分类或回归。
训练过程:kNN 算法实际上没有显式的训练过程,它只是在训练阶段存储所有样本。在预测时,计算新样本与所有训练样本的距离,并选择最近的 k 个样本进行投票(分类)或平均(回归)。
优点:简单直观,无需参数估计,无需训练。
缺点:计算量大,尤其是当数据集很大时;对数据的尺度敏感;需要选择合适的 k 值。
适用场景:适用于样本数量不大且特征维度不高的分类或回归问题。
Python 示例代码:
- from sklearn.datasets import load_iris
- from sklearn.model_selection import train_test_split
- from sklearn.neighbors import KNeighborsClassifier
- from sklearn.metrics import accuracy_score
-
- # 加载iris数据集
- iris = load_iris()
- X = iris.data
- y = iris.target
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
-
- # 初始化kNN分类器
- knn_clf = KNeighborsClassifier(n_neighbors=3)
-
- # 训练kNN分类器
- knn_clf.fit(X_train, y_train)
-
- # 预测
- y_pred = knn_clf.predict(X_test)
-
- # 计算准确率
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
原理:Naive Bayes 基于贝叶斯定理和特征之间强(朴素)独立假设的分类方法。它计算每个类别下每个特征的概率,然后利用这些概率进行预测。
训练过程:计算每个特征在每个类别下的条件概率,以及每个类别的先验概率。
优点:实现简单,计算效率高,在文本分类等特定领域表现良好。
缺点:特征独立性假设在现实中往往不成立,可能导致分类性能下降。
适用场景:文本分类、垃圾邮件检测、情感分析等。
Python 示例代码:
- from sklearn.datasets import load_iris
- from sklearn.model_selection import train_test_split
- from sklearn.naive_bayes import GaussianNB
- from sklearn.metrics import accuracy_score
-
- # 加载iris数据集
- iris = load_iris()
- X = iris.data
- y = iris.target
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
-
- # 初始化Gaussian Naive Bayes分类器
- gnb = GaussianNB()
-
- # 训练分类器
- gnb.fit(X_train, y_train)
-
- # 预测
- y_pred = gnb.predict(X_test)
-
- # 计算准确率
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
原理:CART 是一种决策树算法,可用于分类和回归。它通过递归地将特征空间划分为两个或多个子空间来构建树,每个子空间对应一个类别(分类)或目标值(回归)。
由于 Cart 决策树的这些特性,它被广泛用在集成学习,通过构建并结合多个 Cart 的预测结果来进一步提高整体性能。
训练过程:
选择最优特征进行划分,使得划分后的子空间纯度最高(对于分类)或误差最小(对于回归)。
递归地在每个子空间上重复上述过程,直到满足停止条件(如达到最大深度、节点样本数过少等)。
对于分类树,通常使用多数投票法决定叶节点的类别;对于回归树,通常使用子空间内目标值的均值作为叶节点的输出。
优点:易于理解和解释;可以处理非线性关系;不需要特征缩放。
缺点:容易过拟合;对噪声数据敏感;不稳定(不同的训练样本可能导致不同的树结构)。
适用场景:分类和回归问题,特别是当特征之间的关系复杂且难以用线性模型描述时。
Python 示例代码(这里以分类为例):
- 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
-
- # 加载iris数据集
- iris = load_iris()
- X = iris.data
- y = iris.target
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
-
- # 初始化CART分类树
- cart_clf = DecisionTreeClassifier(criterion='gini')
-
- # 训练分类树
- cart_clf.fit(X_train, y_train)
-
- # 预测
- y_pred = cart_clf.predict(X_test)
-
- # 计算准确率
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
原理: 集成学习是一种训练方式,其原理在于将多个模型结合在一起以提升训练结果。它不是某种具体的训练方式或者算法,而是一种训练的思路。具体来说,集成学习通过结合数个“好而不同”的机器学习技术,形成一个预测模型,以此来降低方差(如 Bagging),减少偏差(如 Boosting),提升预测准确性。
集成学习模型主要分为:Bagging 模型(随机森林)、Boosting 模型(Adaboost、GBDT)。
训练过程:
构建基学习器:首先,通过某种方式(如随机采样、特征选择等)构建多个基学习器(如决策树、支持向量机等)。
训练基学习器:每个基学习器在训练集上进行独立训练。
结合预测结果:通过投票法(分类任务)或平均法(回归任务)等方式,将多个基学习器的预测结果结合起来,得到最终的预测结果。
优点:
提高预测精度和稳定性。
减少过拟合的风险。
对噪声和异常值有较好的鲁棒性。
缺点:
训练多个基学习器可能增加计算成本和时间。
可能需要调参来优化集成效果。
适用场景:
当数据集较大且计算资源充足时。
需要提高预测精度和稳定性的场景。
Python 示例代码:
- from sklearn.datasets import make_classification
- from sklearn.model_selection import train_test_split
- from sklearn.ensemble import RandomForestClassifier
- from sklearn.metrics import accuracy_score
-
- # 生成模拟数据
- X, y = make_classification(n_samples=1000, n_features=20, n_informative=2, n_redundant=10, random_state=42)
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
-
- # 初始化随机森林分类器(集成学习的一种)
- rf_clf = RandomForestClassifier(n_estimators=100, random_state=42)
-
- # 训练模型
- rf_clf.fit(X_train, y_train)
-
- # 预测
- y_pred = rf_clf.predict(X_test)
-
- # 计算准确率
- accuracy = accuracy_score(y_test, y_pred)
- print(f"Accuracy: {accuracy}")
原理:
神经网络是一种模拟人脑神经元结构和功能的计算模型,通过构建大量神经元之间的连接关系来处理信息。每个神经元接收输入信号,经过加权求和和激活函数处理后输出信号,通过多层神经元的组合和连接,形成复杂的网络结构。深度学习通过搭建多层的神经网络模型,无疑已成为近年来备受瞩目的热门领域。
训练过程:
前向传播:输入数据通过神经网络的每一层,逐层计算得到输出。
计算损失:比较网络输出与真实标签,计算损失函数值(如均方误差、交叉熵等)。
反向传播:根据损失函数的梯度信息,通过链式法则逐层计算参数的梯度,并更新神经网络的权重和偏置。
迭代优化:重复前向传播、计算损失和反向传播的过程,直到达到预设的训练轮数或满足停止条件。
优点:
能够逼近任意复杂的非线性关系。
对特征工程的要求相对较低,可以自动提取特征。
适用于大规模数据集和高维特征空间。
缺点:
需要大量的训练数据和计算资源。
训练过程可能不稳定,容易陷入局部最优。
模型结构和超参数的选择对性能影响较大。
适用场景:
图像识别、语音识别和自然语言处理等复杂任务。
需要自动提取特征或处理高维数据的场景。
Python 示例代码:
- import numpy as np
- from sklearn import datasets
- from sklearn.model_selection import train_test_split
- from sklearn.preprocessing import StandardScaler
- from tensorflow.keras.models import Sequential
- from tensorflow.keras.layers import Dense
- from tensorflow.keras.utils import to_categorical
-
- # 加载iris数据集
- iris = datasets.load_iris()
- X = iris.data
- y = iris.target
-
- # 数据标准化
- scaler = StandardScaler()
- X = scaler.fit_transform(X)
-
- # 将标签转换为one-hot编码
- y = to_categorical(y)
-
- # 划分训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
-
- # 创建神经网络模型
- model = Sequential()
- model.add(Dense(10, input_dim=4, activation='relu')) # 输入层到隐藏层
- model.add(Dense(3, activation='softmax')) # 隐藏层到输出层(3个类别)
-
- # 编译模型
- model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
-
- # 训练模型
- model.fit(X_train, y_train, epochs=50, batch_size=10)
-
- # 评估模型
- loss, accuracy = model.evaluate(X_test, y_test)
- print(f'Test loss: {loss}, Test accuracy: {accuracy}')
在本文中,我们对十大数据挖掘算法的原理进行了深入的剖析,这些算法涵盖了决策树、支持向量机、朴素贝叶斯、K-近邻、聚类分析、关联规则学习、集成学习以及深度学习等关键算法。
每种算法均具备其独特的核心思想和应用领域,通过深入解析这些算法的原理,我们在面对实际问题时能够选择最适合的算法,从而取得更好的应用效果。
- 往期精彩回顾
-
-
-
-
- 适合初学者入门人工智能的路线及资料下载(图文+视频)机器学习入门系列下载机器学习及深度学习笔记等资料打印《统计学习方法》的代码复现专辑
交流群
欢迎加入机器学习爱好者微信群一起和同行交流,目前有机器学习交流群、博士群、博士申报交流、CV、NLP等微信群,请扫描下面的微信号加群,备注:”昵称-学校/公司-研究方向“,例如:”张小明-浙大-CV“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~(也可以加入机器学习交流qq群772479961)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。