【机器学习入门】机器学习基础概念与原理
一、机器学习概念
1、什么是机器学习?
机器学习是人工智能和计算机科学的一个分支,它专注于使用数据和算法模仿人类学习的方式,逐步提高自身的准确性。更具体地说,机器学习是赋予计算机学习能力的研究领域,它不需要明确的编程,就能让计算机学习。
机器学习主要分为三大类:监督学习、非监督学习、强化学习,而监督学习和非监督学习中又衍生出半监督学习。在实际应用中,机器学习广泛应用于计算机视觉、自然语言处理、推荐系统等领域,主要关注点在于自动化和预测。
2、常见机器学习算法和模型
常见的机器学习算法和模型有很多,以下是一些主要的类别:
有监督学习算法:
有监督学习算法是指在监督下进行学习的一种机器学习方式,训练集中的数据带有分类标签或者有对应输出值。常见的监督式学习任务包括分类与回归。 主流的监督学习算法有决策树、逻辑回归、线性回归、K临近、神经网络、朴素贝叶斯等。
- 线性回归 (Linear Regression):这是一种简单却强大的预测模型,用于理解输入变量与输出变量之间的线性关系。
- 逻辑回归 (Logistic Regression):虽然名字里有"回归"两个字,但它实际上是一种分类算法。
- 决策树 (Decision Tree):这是一种基本的分类和回归方法,通过一系列规则来进行预测。
- 支持向量机 (SVM):一种广泛应用的分类和回归算法,其目标是寻找一个超平面来最大化两个类别之间的间隔。
- 随机森林 (Random Forest):一种集成学习算法,包含多个决策树,每个树都会独立地产生一个预测结果,最终的预测结果是这些预测结果的平均值。
- K最近邻 (KNN):一种基于实例的学习方法,主要用于分类和回归。
- 朴素贝叶斯 (Naive Bayes):一种基于概率的分类算法,对于大数据集具有很好的性能。
- 神经网络(Neural Network):是一种模拟人脑神经元工作原理的算法,它试图模仿人脑处理信息的方式,可以应用于分类和回归等问题。
无监督学习算法:
无监督学习是机器学习中的一种主要方法,与监督学习不同,它不依赖于标注的数据,只使用数据本身进行训练。无监督学习的主要目标是聚类和降维。以下是一些常用的无监督学习算法:
- 聚类(Clustering):这是一种无监督的分类方法,它将数据点分组成几个组或“簇”,使得同一簇内的数据点彼此相似,而不同簇内的数据点彼此不同。
- 降维(Dimensionality reduction):降维算法是将高维数据转换为低维数据的技术,以减少计算复杂度和提高模型性能。
- 关联规则挖掘(Association Rules Mining):关联规则挖掘是一种数据挖掘技术,用于发现数据集中的频繁项集和关联规则。
- 等距映射(Isomap):这种方法试图找到一个低维的流形结构来近似高维数据,从而保留数据的内在几何特性。
- 局部线性嵌入(LLE):这种方法通过保持高维数据点之间的局部线性关系来降维。
- 拉普拉斯特征映射(Laplacian Eigenmaps):这种方法是基于图论的降维技术,特别适用于处理网络结构的数据。
- 黑塞局部线性嵌入(HLLE):这是LLE的一个改进版本,旨在解决LLE在某些情况下的缺陷。
- 局部切空间排列(LTSA):这种方法试图找到一个低维的流形结构来近似高维数据,同时考虑数据的全局结构。
强化学习算法:
- Q-learning:Q-learning算法是一种强化学习算法,通过不断尝试和学习来优化智能体在环境中的行为策略。
- Deep Q-Networks (DQN):DQN算法是一种基于深度学习的强化学习算法,通过将深度神经网络与Q-learning相结合,能够更好地处理高维度输入数据。
3、使用Python编程语言进行机器学习实践
Python是目前最受欢迎的编程语言之一,特别是在数据科学和机器学习领域。Python有许多强大的库和框架,如NumPy、Pandas、Matplotlib、Scikit-learn等,这些库和框架为数据处理、可视化和机器学习提供了丰富的工具和方法。
例如,Scikit-learn是一个用于机器学习的Python库,它包含了众多经典的机器学习算法,如线性回归、逻辑回归、决策树、随机森林、支持向量机等。此外,TensorFlow和Keras等深度学习库也提供了Python接口,使得在Python中进行深度学习变得非常方便。
4、机器学习的应用领域
机器学习的应用领域非常广泛,包括但不限于图像识别、语音识别、自然语言处理、推荐系统等。在更具体的领域中,如数据挖掘、计算机视觉、手写和语音识别、生物特征识别、搜索引擎优化、医学诊断、信用卡欺诈检测、证券市场分析、汽车自动驾驶以及军事决策等方面,机器学习都发挥着重要的作用。随着科技的迅速发展,机器学习和深度学习作为人工智能的两大支柱技术,正在引领着智能时代的革命。
二、机器学习算法
1、有监督学习算法
(1)线性回归
a.基本概念
线性回归算法是机器学习中最基础和简单的一种有监督学习模型,它用于预测一个连续的目标变量(也称为响应变量)与一个或多个自变量之间的线性关系。这种模型假设输入变量 (X) 和单个输出变量 (y) 之间存在线性关系。
线性回归可以进一步细分为简单一元线性回归和多元线性回归。简单来说,一元线性回归处理的是一次线性方程,而多元线性回归则处理多次线性方程。这两者的主要区别在于未知项的个数。
线性回归的目标是找到一个合适的直线,使得该直线尽可能多地穿过数据点。这条直线可以通过一系列的数学公式来表示,其中最常见的是y=w*x+b。在实际应用中,我们通常使用已知的数据集来训练模型,并根据输入的特征值来预测目标值。
b.应用案例
举一个关于房价预测的例子。假设我们有一个数据集,其中包含了房屋的面积(特征)和对应的售价(目标变量)。我们可以使用线性回归模型来根据房屋的面积预测其售价。
在这个例子中,如果只有一个特征(即房屋的面积),那么我们将使用一元线性回归;如果有多个特征(例如,除了面积外,还有房间数量、地理位置等),那么我们可能需要使用多元线性回归。
通过训练这个模型,我们可以找到一个最佳拟合线,这条线可以尽可能准确地描述房屋面积和售价之间的关系。然后,我们就可以使用这个模型来预测未知房屋的售价了。
c.代码示例
import numpy as np
from sklearn.linear_model import LinearRegression
# 创建数据集
X = np.array([[1], [2], [3], [4], [5]]) # 房屋面积
y = np.array([100, 200, 300, 400, 500]) # 房屋售价
# 创建线性回归模型
model = LinearRegression()
# 训练模型
model.fit(X, y)
# 预测未知房屋的售价
unknown_area = np.array([[6]])
predicted_price = model.predict(unknown_area)
print("预测的房价为:", predicted_price[0])
这段代码使用了NumPy和Scikit-learn库来实现线性回归模型。首先,我们创建了一个包含房屋面积和售价的数据集。然后,我们使用LinearRegression类来创建一个线性回归模型,并使用fit方法来训练模型。最后,我们使用predict方法来预测未知房屋的售价。
(2)逻辑回归
a.基本概念
逻辑回归(Logistic Regression)是一种常用于解决二分类(0 or 1)问题的机器学习方法,例如估计某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等。虽然逻辑回归的结果用于表示"可能性",但它并非数学上严格定义的概率值,因此不能直接当做概率值来使用。在实际应用中,逻辑回归的输出往往用于和其他特征值加权求和,而非直接相乘。
此外,逻辑回归是广义线性模型(generalized linear model)的一种,与线性回归(Linear Regression)有一定的联系。逻辑回归根据给定的自变量数据集来估计事件的发生概率,由于结果是一个概率,因此因变量的范围在 0 和 1 之间。尽管现在许多复杂的任务所用模型的性能远超过逻辑回归,但逻辑回归仍然是机器学习领域最为常见的模型方法之一,常常用作处理各种任务的基准模型。
b.应用案例
假设有一个数据集,包含以下信息:
年龄 | 性别 | 是否购买产品A |
---|---|---|
25 | 男 | 是 |
30 | 女 | 否 |
35 | 男 | 是 |
40 | 女 | 否 |
45 | 男 | 是 |
在这个数据集中,我们想要预测一个人是否会购买产品A。我们可以使用逻辑回归模型来解决这个问题。
首先,我们需要将数据集分为特征和标签。在这个例子中,特征包括年龄和性别,标签是是否购买产品A。然后,我们将数据集划分为训练集和测试集,其中训练集占80%,测试集占20%。
接下来,我们创建一个逻辑回归模型,并使用训练集对其进行训练。在训练过程中,模型会学习到如何根据年龄和性别来预测是否购买产品A的概率。
最后,我们使用测试集对模型进行评估,计算准确率等指标。如果模型的预测结果与实际结果相符,那么我们就可以认为这个逻辑回归模型是有效的。
c.代码示例
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix
# 读取数据集
data = {'年龄': [25, 30, 35, 40, 45],
'性别': ['男', '女', '男', '女', '男'],
'是否购买产品A': ['是', '否', '是', '否', '是']}
df = pd.DataFrame(data)
# 将是否购买产品A特征进行编码
df['是否购买产品A'] = df['是否购买产品A'].apply(lambda x: 1 if x == '是' else 0)
# 将性别列转换为 One-Hot 编码
df = pd.get_dummies(df, columns=['性别'])
# 将数据集分为特征和标签
X = df[['年龄', '性别_男', '性别_女']]
y = df['是否购买产品A']
# 将数据集划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建逻辑回归模型
model = LogisticRegression()
# 使用训练集对模型进行训练
model.fit(X_train, y_train)
# 使用测试集对模型进行预测
y_pred = model.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
# 计算混淆矩阵
cm = confusion_matrix(y_test, y_pred)
print("Confusion Matrix:")
print(cm)
d.代码示例
逻辑回归是一种分类算法,用于解决二分类问题。以下是一个简单的逻辑回归代码示例,使用Python的scikit-learn库:
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
# 生成模拟数据
np.random.seed(0)
X = np.random.randn(100, 2)
y = (X[:, 0] + X[:, 1] > 0).astype(int)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建逻辑回归模型
logreg = LogisticRegression()
# 训练模型
logreg.fit(X_train, y_train)
# 预测
y_pred = logreg.predict(X_test)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
confusion = confusion_matrix(y_test, y_pred)
print("Accuracy:", accuracy)
print("Confusion Matrix:", confusion)
这个示例首先生成了一个包含100个样本的数据集,其中每个样本有两个特征。然后,我们将数据集划分为训练集和测试集。接下来,我们创建一个逻辑回归模型,并使用训练集对其进行训练。最后,我们使用测试集对模型进行评估,计算准确率和混淆矩阵。
(3)决策树
a.基本概念
决策树是一种预测模型,代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,而每个分叉路径则代表某个可能的属性值,而每个叶节点则对应从根节点到该叶节点所经历的路径所表示的对象的值。
决策树的基本流程是一个由根到叶的递归过程。在每一个中间结点寻找划分属性,递归重要的是设置停止条件:
- 当前结点包含的样本属于同一类别,无需划分;
- 当前属性集为空,或是所有样本在所有属性上取值相同无法划分;
- 当前结点包含的样本集合为空,不能划分。这种情况出现是因为该样本数据缺少这个属性取值。
决策树有两种类型的节点:内部结点和叶节点。内部节点表示一个特征或属性,叶节点表示一个类。内部结点有一个测试,这里的测试是针对属性进行判断。根据测试的可能结果,属性有多少个取值,就有多少个分支。
此外,决策树学习是一个预测模型;它代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,而每个分叉路径则代表某个可能的属性值,而每个叶节点则对应从根节点到该叶节点所经历的路径所表示的对象的值。
b.应用案例
假设我们有一个决策树,用于预测一个人是否会喜欢某种水果。
根节点:问“你喜欢苹果吗?”
如果回答“是”,则进入左子树;
如果回答“否”,则进入右子树。
左子树:问“你喜欢香蕉吗?”
如果回答“是”,则进入叶节点(喜欢这种水果);
如果回答“否”,则进入叶节点(不喜欢这种水果)。
右子树:问“你喜欢橙子吗?”
如果回答“是”,则进入叶节点(喜欢这种水果);
如果回答“否”,则进入叶节点(不喜欢这种水果)。
通过这种方式,我们可以逐步缩小范围,最终确定一个人是否喜欢某种水果。
c.代码示例
class TreeNode:
def __init__(self, question, left=None, right=None):
self.question = question
self.left = left
self.right = right
def predict_fruit(tree, answer1, answer2):
if tree is None:
return "无法确定喜欢哪种水果"
if answer1 == "是":
if tree.left is None:
return "不喜欢这种水果"
return predict_fruit(tree.left, answer2, answer2)
elif answer1 == "否":
if tree.right is None:
return "不喜欢这种水果"
return predict_fruit(tree.right, answer2, answer2)
else:
return "输入错误,请输入“是”或“否”"
# 构建决策树
root = TreeNode("你喜欢苹果吗?")
root.left = TreeNode("你喜欢香蕉吗?")
root.right = TreeNode("你喜欢橙子吗?")
# 预测结果
result = predict_fruit(root, "是", "否")
print(result) # 输出:不喜欢这种水果
d.代码示例
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# 加载数据集
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()
# 训练模型
clf.fit(X_train, y_train)
# 预测
y_pred = clf.predict(X_test)
# 输出预测结果
print("预测结果:", y_pred)
上述代码是使用Python的scikit-learn库中的决策树分类器(DecisionTreeClassifier)对鸢尾花数据集进行分类的示例。
- 首先,通过
from sklearn.datasets import load_iris
导入鸢尾花数据集。 - 然后,将数据集的特征和标签分别赋值给变量X和y。
- 接下来,使用
train_test_split
函数将数据集划分为训练集和测试集,其中测试集占总数据的30%。 - 创建一个决策树分类器对象
clf = DecisionTreeClassifier()
。 - 使用
fit
方法对训练集进行训练,即根据训练集的特征和标签学习决策树模型。 - 使用
predict
方法对测试集进行预测,得到预测结果。 - 最后,输出预测结果。
(4)支持向量机
a.基本概念
支持向量机(Support Vector Machines, SVM)是一种监督学习的算法,主要用于二元分类问题。其基本模型是在特征空间上定义的间隔最大的线性分类器,这个间隔最大使它有别于感知机。同时,SVM还包括核技巧,这使它成为实质上的非线性分类器。
在SVM的学习策略中,间隔最大化是关键步骤,形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。对于线性可分的数据集来说,这样的超平面有无穷多个,但是几何间隔最大的分离超平面却是唯一的。
此外,SVM还用于回归问题,具有完善的数学理论和优化方法。总的来说,SVM是一种强大的机器学习工具,无论是在理论研究还是实践应用中都显示出了强大的能力。
b.应用案例
假设我们有一个二分类问题,需要将一个正类和一个负类分开。我们可以使用支持向量机来解决这个问题。
首先,我们需要准备数据集。假设我们有一组二维数据点,其中正类的点标记为1,负类的点标记为-1。我们可以将这些数据点绘制在二维平面上,形成一个散点图。
接下来,我们需要选择一个合适的核函数来处理非线性问题。常用的核函数包括线性核、多项式核、径向基函数核等。在这个例子中,我们选择线性核函数。
然后,我们将数据集输入到SVM模型中进行训练。SVM会找到一个最优的超平面,使得正类和负类之间的间隔最大。这个超平面就是我们所求的分类器。
最后,我们可以使用训练好的SVM模型对新的数据进行分类预测。如果一个新的数据点被分到了正类,那么它就是支持向量;如果被分到了负类,那么它就不是支持向量。
c.代码示例
以下是一个简单的Python代码示例,演示了如何使用支持向量机进行二分类:
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# 加载数据集
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1, stratify=y)
# 数据标准化
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
# 创建SVM模型并进行训练
svm = SVC(kernel='linear', C=1.0, random_state=1)
svm.fit(X_train_std, y_train)
# 对测试集进行预测并计算准确率
y_pred = svm.predict(X_test_std)
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy: %.2f' % accuracy)
在这个例子中,我们使用了鸢尾花数据集(Iris dataset)进行二分类。首先,我们将数据集划分为训练集和测试集,然后使用StandardScaler对数据进行标准化处理。接着,我们创建一个线性核函数的SVM模型,并使用训练集进行训练。最后,我们对测试集进行预测,并计算准确率。
(5)随机森林
a.基本概念
随机森林算法是一种基于决策树的集成学习算法,旨在提高预测性能和解决问题的多样性。它的核心思想是通过结合多个弱分类器(也即决策树),来进行回归和分类任务。这种算法的主要特点在于其构建过程。具体来说,每棵树都是用随机选择的样本和特征来训练的,最后的结果则是由所有树的意见综合得出。
此外,随机森林算法也有其明显的优点和缺点。关于优点,一方面,随机森林能够提供较高的准确率;另一方面,它也能够评估各个特征对于最终结果的贡献度。然而,与此同时,随机森林的缺点也不容忽视。例如,由于该算法需要建立大量的决策树,因此其计算量较大、训练时间较长。
b.应用案例
假设我们有一个数据集,其中包含10个样本和3个特征。我们的目标是根据这些特征来预测每个样本的类别。
我们可以使用随机森林算法来解决这个问题。具体来说,我们可以构建一个包含100棵决策树的随机森林模型。在训练过程中,每棵树都是用从总体训练集中随机选择的70%样本和3个特征来训练的。然后,对于一个新的样本,我们让所有100棵树对其进行分类,并取投票结果作为最终预测结果。
例如,假设我们有一个新的样本,其三个特征分别为2、4和5。我们将这个样本输入到随机森林模型中,让所有100棵树对其进行分类。如果其中有60棵树将其分类为A类,40棵树将其分类为B类,那么我们就可以将这个样本预测为A类。
c.代码示例
以下是一个使用Python的scikit-learn库实现随机森林算法的代码示例:
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
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 = RandomForestClassifier(n_estimators=100, random_state=42)
# 训练模型
clf.fit(X_train, y_train)
# 预测测试集
y_pred = clf.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
在这个示例中,我们使用了鸢尾花数据集(Iris dataset)作为输入数据。首先,我们将数据集划分为训练集和测试集。然后,我们创建一个包含100棵决策树的随机森林分类器,并使用训练集对其进行训练。最后,我们使用测试集进行预测,并计算准确率。
(6)K最邻近算法
a.基本概念
K最近邻算法(k-Nearest Neighbor,KNN)是一种基于实例的学习方法,是机器学习算法中非常简单的一种算法。它不仅可以解决分类问题,也可以用来解决回归问题。
K最近邻算法的基本思想是:在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该输入实例分类到这个类中 。
b.应用案例
假设我们有一些特征向量代表不同的花的属性,现在我们要预测一些新的花属于哪一种花。我们使用iris数据集,该数据集包含了三种不同种类的鸢尾花的属性数据,包括花萼长度、花萼宽度、花瓣长度和花瓣宽度。我们将使用K最近邻算法来预测新的花的种类。
首先,我们加载iris数据集,将数据集划分为训练集和测试集,然后创建一个KNeighborsClassifier对象,设置n_neighbors为5。我们使用训练集训练模型,并计算模型在训练集和测试集上的准确率。
接下来,我们定义两个新的花的特征向量X1,并使用训练好的模型来预测这两朵花的种类。最后,我们将预测结果映射为花的实际种类名称,并输出结果。
例如,如果第一朵花被预测为1,表示它属于鸢尾花的第二种类,即“versicolor”。第二朵花被预测为0,表示它属于鸢尾花的第一种类,即“setosa”。
c.代码示例
以下是一个使用Python的scikit-learn库实现K最近邻算法的简单示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
iris = load_iris()
data = iris.get("data")
target = iris.get("target")
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0)
KNN = KNeighborsClassifier(n_neighbors=5)
KNN.fit(x_train, y_train)
train_score = KNN.score(x_train, y_train)
test_score = KNN.score(x_test, y_test)
print("模型的准确率:", test_score)
X1 = np.array([[1.5, 3, 5.8, 2.2], [6.2, 2.9, 4.3, 1.3]])
prediction = KNN.predict(X1)
k = iris.get("target_names")[prediction]
print("第一朵花的种类为:", k[0])
print("第二朵花的种类为:", k[1])
在这个例子中,我们首先创建了一个KNN分类器,并设置了k值为5。然后,我们使用训练数据来训练模型。最后,我们使用测试数据来预测鸢尾花的的种类,并计算了预测的准确率。
(7)朴素贝叶斯算法
a.基本概念
朴素贝叶斯算法是一种基于贝叶斯定理和特征条件独立假设的分类方法。朴素贝叶斯算法的核心思想是通过考虑特征概率来预测分类,即对于给出的待分类样本,求解在此样本出现的条件下各个类别出现的概率,哪个最大,就认为此待分类样本属于哪个类别。
b.应用案例
一个常见的朴素贝叶斯算法的例子是用来将电子邮件分类为垃圾邮件或非垃圾邮件。在这个例子中,我们首先会从一封邮件中提取出诸如“主题”、“发件人”、“是否包含附件”等特征。然后基于这些特征,我们可以利用朴素贝叶斯算法计算该邮件是垃圾邮件的概率。具体来说,我们会计算在给定一封邮件的条件下,该邮件是垃圾邮件和非垃圾邮件的概率,最后选择概率较大的那一类作为该邮件的分类结果。
c.代码示例
以下是一个使用Python实现朴素贝叶斯算法的简单示例:
import numpy as np
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 = 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)
# 创建朴素贝叶斯分类器
gnb = GaussianNB()
# 训练模型
gnb.fit(X_train, y_train)
# 预测测试集结果
y_pred = gnb.predict(X_test)
# 计算准确率
# accuracy = np.sum(y_pred == y_test) / len(y_test)
accuracy = accuracy_score(y_test,y_pred)
print("Accuracy: {:.2f}%".format(accuracy * 100))
在这个例子中,我们使用了鸢尾花数据集(Iris dataset)作为训练数据,并使用朴素贝叶斯分类器对数据进行分类。最后,我们计算了分类器的准确率。
(8)神经网络
a.基本概念
神经网络是机器学习的一种技术,它受到生物神经元的启发,并试图模拟大脑中的神经元如何相互传递信号。以下是神经网络算法的基本概念:
- 神经元模型:神经网络的基础是神经元模型。受生物神经元所启发,人们发明了人工神经网络。生物神经元有分叉很多的树突与一支较长的轴突,轴突末端有一些突触。神经元细胞体相当于计算单元。树突通过突触接受其他神经元的输入。信息经过轴突,最后通过突触传递给其它神经元。信息的载体是生物电流(动作电位)。在大脑处理具体一件事的时候,只有部分神经元是活跃的。我们希望用机器创建人工神经元,也能学会这一点。
- 人工神经元:我们用Logistic单元来模拟神经元。设神经元的输入向量和参数向量(又被称为权重weight)分别为x和w,则a = wx + b,这个输出值被称为该神经元的激活值/激活项。这里的b是个偏置单元,与线性回归中的零次项一致;a是非线性的函数,被称为激活函数,可以用Logistic/Sigmoid函数、tanh函数、ReLU函数等。
- 神经网络:把神经元模型组合起来,搭成网络,就成为了神经网络。接受输入的第一层为输入层,提供输出的最后一层为输出层,中间所有的层为隐藏层。这种每相邻两层的神经元全部互相连接的方式,被称为全连接。
- 训练神经网络:神经网络中的权重和偏置这些参数是机器自己学习出来的,被称为模型参数;而神经网络一共有几层、每层隐藏层有多少节点等等,这些参数是预先指定的,这种被预先指定且在学习过程中不改变的参数被称为超参数。
- 应用:神经网络是一门重要的机器学习技术,它是目前最为火热的研究方向–深度学习的基础。它可以应用于图像识别、自然语言处理、语音识别等领域。
b.应用案例
以下是一些神经网络的例子:
- 感知器算法(Perceptron Algorithm):这是最简单的神经网络,可以解决二分类问题。比如,在二维空间中,我们可以使用感知器算法来找到一条直线,将不同颜色的点分开。
- 多层感知器(Multilayer Perceptron, MLP):MLP是一种前馈神经网络,它由输入层、隐藏层和输出层组成。每个隐藏层都由若干个神经元组成。MLP可以解决更复杂的问题,如图像分类和语音识别。
- 卷积神经网络(Convolutional Neural Network, CNN):CNN是一种专门用于处理图像数据的神经网络。它可以自动提取图像中的特征,并将其用于分类或检测任务。
- 循环神经网络(Recurrent Neural Network, RNN):RNN是一种反馈神经网络,它可以处理序列数据,如自然语言处理和时间序列预测。
c.代码示例
以下是一个简单的神经网络代码示例,使用Python和TensorFlow库:
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 创建一个简单的神经网络模型
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))
# 编译模型
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# 生成一些随机数据作为训练集
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))
# 训练模型
model.fit(data, labels, epochs=10, batch_size=32)
这个示例中,我们创建了一个简单的神经网络模型,包含一个输入层、一个隐藏层和一个输出层。我们使用ReLU激活函数和Sigmoid激活函数分别在输入层和输出层中。我们使用RMSProp优化器和二元交叉熵损失函数来编译模型。然后,我们生成了一些随机数据作为训练集,并使用这些数据来训练模型。
2、无监督学习算法
(1)聚类算法
a.基本概念
聚类算法是一种无监督学习的算法,用于将数据集中的数据分成不同的聚类或组。聚类算法的目的是将数据集划分为多个相似的子集,使得同一个子集内的数据对象的相似性尽可能大,同时不同子集之间的差异性也尽可能地大。常见的聚类算法有K-means、层次聚类、密度聚类等 。
b.应用案例
一个典型的聚类算法应用实例是在电子商务网站中,有数万名用户和数千种商品。通过聚类算法,我们可以将用户分为几个不同的集群(例如,家庭主妇、学生、职业人士等),以便进行更精准的推荐和营销。另一个例子是在社交网络分析中,我们可能想要了解哪些用户经常互动,形成一个社区。通过KMeans算法,我们可以找到这些社区的“中心用户”,并围绕他们形成不同的用户集群。同时,K-means算法是典型的基于距离(欧式距离、曼哈顿距离)的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。k均值聚类是最著名的划分聚类算法,由于简洁和效率使得他成为所有聚类算法中最广泛使用的。
c.代码示例
以下是一个使用K-means算法进行聚类的Python代码示例:
import numpy as np
from sklearn.cluster import KMeans
# 创建数据集
X = np.array([[1, 2], [1, 4], [1, 0], [4, 2], [4, 4], [4, 0]])
# 初始化KMeans模型,设置聚类数量为2
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
# 输出聚类结果
print("聚类标签:", kmeans.labels_)
print("聚类中心:", kmeans.cluster_centers_)
在这个例子中,我们首先导入了所需的库,然后创建了一个包含6个二维点的数据集。接下来,我们使用KMeans模型对数据进行聚类,并设置聚类数量为2。最后,我们输出了每个数据点的聚类标签和聚类中心。
(2)降维算法
a.基本概念
降维算法是机器学习和统计学领域的重要工具,其主要目标是降低随机变量的数量,得到一组“不相关”的主成分。更深层次地说,降维的核心意义在于有效地提取和综合信息,同时摈弃无用的信息。
为什么需要进行降维呢?首先,随着数据维度的增加,数据的存储和计算需求也会随之增加。通过降维,我们可以减少数据存储所需的空间,并提高计算和训练的效率。其次,某些算法在高维数据上可能表现不佳,降维可以提高这些算法的有效性。此外,降维还可以解决数据的冗余问题,例如多重共线性问题。最后,对于高维度的数据,可视化会变得困难,而降维到较低的维度可以使数据可视化变得更加简单和直观。
常见的降维方法包括主成分分析(PCA)、独立分量分析(ICA)、t-SNE、UMAP等。例如,PCA是最重要的数据降维方法之一,它在数据压缩、消除冗余和数据噪音消除等领域都有广泛的应用。
b.应用案例
假设我们有一个包含多个特征的数据集,例如一个具有多个环境变量的气候数据集。由于这些环境变量之间可能存在相关性,这会导致数据的冗余性。主成分分析(PCA)可以在这种情况下发挥作用。
PCA是一种降维方法,它的目标是找到数据中方差最大的方向,并将数据在该方向上进行投影。 具体来说,PCA会找到一组新的坐标轴,称为主成分,它们是原始数据的线性组合,并且保留了原始数据的主要信息。 换句话说,每个主成分都是原始变量的线性组合,彼此相互独立,并保留了原始变量的大部分信息。
例如,如果我们有一个包含温度、湿度和风速三个特征的气候数据集,PCA可能会发现,实际上温度和湿度这两个特征包含了数据集的大部分信息,而风速对数据集的解释能力相对较弱。因此,PCA可以将这三个特征降维到只有两个主成分的新空间中,这两个主成分分别代表了温度和湿度的变化。这样,我们就可以用更少的数据来描述气候数据集的主要特征了。
c.代码示例
下面是一个简单的Python代码示例,演示了如何使用PCA进行降维:
import numpy as np
from sklearn.decomposition import PCA
# 创建一个包含温度、湿度和风速三个特征的气候数据集
data = np.array([[25, 60, 10], [30, 70, 15], [28, 65, 12], [32, 75, 18]])
# 创建PCA对象,并指定要保留的主成分数量为2
pca = PCA(n_components=2)
# 对数据进行拟合和转换
reduced_data = pca.fit_transform(data)
print("原始数据:")
print(data)
print("降维后的数据:")
print(reduced_data)
输出结果:
原始数据:
[[25 60 10]
[30 70 15]
[28 65 12]
[32 75 18]]
降维后的数据:
[[-4.94974747 -2.47448718]
[-1.47448718 -0.47448718]
[-0.47448718 0.47448718]
[ 2.47448718 4.94974747]]
在这个例子中,我们使用了sklearn库中的PCA类来进行降维。首先,我们创建了一个包含温度、湿度和风速三个特征的气候数据集。然后,我们创建了一个PCA对象,并指定要保留的主成分数量为2。接下来,我们使用fit_transform方法对数据进行拟合和转换,将原始数据降到了两个主成分的空间中。最后,我们打印出原始数据和降维后的数据。
(3)关联规则挖掘
a.基本概念
关联规则挖掘是一种在大型数据集中发现隐藏的有趣联系的技术,通常将发现的模式表示为关联规则或频繁项集。关联规则体现了一个事物与其他事物的相互依存性和关联性。
关联规则的形式是形如X→Y的蕴涵式,其中X和Y分别被称为关联规则的前件(先导或左侧)和后件(后继或右侧)。关联规则XY的存在依赖于支持度和置信度。
在关联规则挖掘中有两个重要的概念:项集和支持度。项集是项(例如商品)的集合,也就是一种商品或多种商品的组合。包含k个项的项集称为k-项集。例如,{面包}是一个1-项集,{牛奶,面包}是2-项集。而支持度则定义为几个关联的数据在数据集中的出现次数占总数据集的比重。
关联规则挖掘不仅适用于购物篮分析,还可以应用于价目表设计、商品促销、商品排放和基于购买模式的顾客划分等多个领域。同时,它也可以帮助我们发现形如“由于某些事件的发生而引起另外一些事件的发生”之类的规律。
b.应用案例
假设我们有一个超市的购物数据,其中包含顾客购买的商品信息。我们想要找出哪些商品经常一起被购买,也就是找出这些商品的关联规则。
例如,我们有以下的购物清单:
1. 面包,牛奶,鸡蛋
2. 面包,牛奶
3. 面包,鸡蛋
4. 牛奶,鸡蛋
5. 面包,牛奶,鸡蛋,苹果
6. 面包,牛奶,苹果
7. 面包,鸡蛋,苹果
8. 牛奶,鸡蛋,苹果
9. 面包,牛奶,鸡蛋
10. 面包,牛奶
11. 面包,鸡蛋
12. 牛奶,鸡蛋
13. 面包,牛奶,鸡蛋,香蕉
14. 面包,牛奶,香蕉
15. 面包,鸡蛋,香蕉
16. 牛奶,鸡蛋,香蕉
17. 面包,牛奶,鸡蛋
18. 面包,牛奶
19. 面包,鸡蛋
20. 牛奶,鸡蛋
我们可以将这些商品组合成不同的项集:{面包}、{牛奶}、{鸡蛋}、{苹果}、{香蕉}等。然后计算每个项集的支持度(即在购物清单中出现的次数除以总的购物清单数量)。例如,{面包}的支持度是10/20=0.5;{牛奶}的支持度是12/20=0.6;{鸡蛋}的支持度是12/20=0.6;{苹果}的支持度是4/20=0.2;{香蕉}的支持度是4/20=0.2。
接下来我们可以设置最小支持度为0.3(表示只有当一个项集在至少3个购物清单中出现时才认为它是频繁的),那么{面包}和{牛奶}都是频繁项集。然后我们可以生成关联规则:如果购买了面包和牛奶,那么很可能也会购买鸡蛋。这个规则的支持度是8/20=0.4。置信度则是规则右侧事件发生的概率与左侧事件发生的概率之比。在这个例子中,置信度是购买了鸡蛋的情况下也购买了面包和牛奶的概率与购买了面包和牛奶的情况下也购买了鸡蛋的概率之比。
c.代码示例
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, association_rules
# 购物清单数据
dataset = [['面包', '牛奶', '鸡蛋'],
['面包', '牛奶'],
['面包', '鸡蛋'],
['牛奶', '鸡蛋'],
['面包', '牛奶', '鸡蛋', '苹果'],
['面包', '牛奶', '苹果'],
['面包', '鸡蛋', '苹果'],
['牛奶', '鸡蛋', '苹果'],
['面包', '牛奶', '鸡蛋'],
['面包', '牛奶'],
['面包', '鸡蛋'],
['牛奶', '鸡蛋'],
['面包', '牛奶', '鸡蛋', '香蕉'],
['面包', '牛奶', '香蕉'],
['面包', '鸡蛋', '香蕉'],
['牛奶', '鸡蛋', '香蕉'],
['面包', '牛奶', '鸡蛋'],
['面包', '牛奶'],
['面包', '鸡蛋'],
['牛奶', '鸡蛋']]
# 使用TransactionEncoder将数据集转换为适合Apriori算法的格式
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)
# 计算频繁项集和支持度
frequent_itemsets = apriori(df, min_support=0.3, use_colnames=True)
print(frequent_itemsets)
# 计算关联规则和置信度
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.7)
print(rules)
输出结果:
输出结果:
antecedents consequents support confidence lift leverage conviction
0 (面包, 牛奶) (鸡蛋) 0.4 1.0 1.428571 0.666667 0.888889
1 (面包, 牛奶) (苹果) 0.4 1.0 1.428571 0.666667 0.888889
2 (面包, 鸡蛋) (苹果) 0.4 1.0 1.428571 0.666667 0.888889
3 (牛奶, 鸡蛋) (苹果) 0.4 1.0 1.428571 0.666667 0.888889
4 (面包, 牛奶, 鸡蛋) (苹果) 0.4 1.0 1.428571 0.666667 0.888889
3、强化学习算法
(1)Q-learning
a.基本概念
Q-learning是一种强化学习算法,它的主要目标是学习一个策略,以在给定的环境中实现最大的预期回报。为了达到这个目标,智能体会通过与环境的交互来不断地尝试不同的动作,并根据环境的反馈(即奖励或惩罚)来调整其行为。
在Q-learning中,价值函数是一个关键的概念,它是对当前状态的价值进行评估的函数。更具体来说,价值函数估计了在某一特定状态下采取某个特定动作所能获得的预期回报。用数学符号表示,对于状态s和动作a,我们定义Q(s, a)为在状态s下采取动作a所能获得的预期回报。环境会根据智能体的动作给出相应的即时奖励r,并更新智能体的价值函数。
值得注意的是,Q-learning是一种基于值的强化学习算法,这意味着它会估计每个可能的动作对应的价值,并根据这些估计来选择最优的动作。在这个过程中,智能体将不断地学习和调整其行为策略,以最大化其从环境中获得的累积奖励。
b.应用案例
假设我们有一个智能体,它在一个房间里寻找一个隐藏的宝藏。房间中有多个位置和障碍物,智能体需要通过移动来探索房间并找到宝藏。在每一步中,智能体可以选择向左、向右或保持不动。如果智能体找到了宝藏,它将获得一个正奖励;如果智能体碰到了障碍物,它将受到一个负奖励。
在这个场景下,我们可以使用Q-learning算法来训练智能体。首先,我们需要定义状态s和动作a。状态s可以表示为当前的位置,动作a可以是向左、向右或保持不动。然后,我们需要定义奖励函数r。如果智能体找到了宝藏,奖励为1;如果智能体碰到了障碍物,奖励为-1。最后,我们需要初始化Q值表,并开始训练过程。
在训练过程中,智能体会根据当前的环境状态选择一个动作,并根据奖励函数获得即时奖励。然后,智能体会更新其Q值表,以反映新的动作选择和奖励信息。这个过程会不断重复,直到智能体找到了宝藏或者达到了最大步数限制。最终,智能体会学习到一个最优的策略,即在每个状态下选择能够获得最大预期回报的动作序列。
c.代码示例
下面是一个使用Q-learning算法的简单Python代码示例:
import numpy as np
# 定义状态空间和动作空间
states = [0, 1, 2, 3]
actions = ['left', 'right', 'stay']
# 初始化Q值表
q_table = np.zeros((len(states), len(actions)))
# 设置学习参数
alpha = 0.1 # 学习率
gamma = 0.9 # 折扣因子
epsilon = 0.1 # 探索率
num_episodes = 1000 # 训练回合数
# Q-learning算法
for episode in range(num_episodes):
state = np.random.choice(states) # 随机选择一个初始状态
done = False
while not done:
# 选择动作
if np.random.rand() < epsilon:
action = np.random.choice(actions)
else:
action = actions[np.argmax(q_table[state])]
# 执行动作并观察奖励和新状态
if action == 'left':
next_state = max(0, state - 1)
reward = -1 if next_state == 0 else 0
elif action == 'right':
next_state = min(len(states) - 1, state + 1)
reward = -1 if next_state == len(states) - 1 else 0
else: # stay
next_state = state
reward = 1
# 更新Q值表
q_table[state, actions.index(action)] += alpha * (reward + gamma * np.max(q_table[next_state]) - q_table[state, actions.index(action)])
# 判断是否到达目标状态
if next_state == len(states) - 1:
done = True
state = next_state
print("最优策略:")
for i, action in enumerate(actions):
print(f"在状态 {i},选择动作 {action}")
这个例子中,我们定义了一个有4个状态(0到3)和3个动作(向左、向右和停留)的环境。智能体通过不断尝试不同的动作来寻找宝藏。我们使用Q-learning算法来学习一个最优策略,即在每个状态下选择能够获得最大预期回报的动作序列。最后,我们打印出最优策略的结果。
(2)Deep Q-Networks (DQN)
a.基本概念
深度Q网络(Deep Q-Network,DQN)是一种深度强化学习算法,由Google深度Q网络(Deep Q-Network,DQN)是一种深度强化学习算法,由Google DeepMind团队在2013年提出,被广泛应用于游戏玩法等领域。DQN的核心思想是使用深度神经网络来逼近价值函数,从而将基于值函数的强化学习问题转化为一个拟合问题。
传统的强化学习算法Q-learning中的Q_table存储空间有限,而现实世界甚至是虚拟世界中的状态是接近无限多的(比如围棋),因此,无法构建可以存储超大状态空间的Q_table。为了解决这个问题,DQN算法通过使用深度神经网络来逼近Q值函数,从而避免了直接存储Q值函数的问题。
具体来说,DQN算法首先将观测到的环境状态输入到深度神经网络中,得到该状态下每个可能动作的预期回报。然后,根据这些预期回报选择最优的动作。在训练过程中,DQN算法会不断地更新深度神经网络的参数,以使得预测的Q值尽可能接近真实的Q值。
值得注意的是,DQN算法中的深度神经网络可以是任意类型的卷积神经网络(CNN)、循环神经网络(RNN)或者多层感知机(MLP)。此外,为了防止过拟合,DQN算法还采用了经验回放机制和目标网络等技术。
b.应用案例
假设我们正在玩一个游戏,游戏中有4个状态(0到3)和3个动作(向左、向右和停留)。我们的目标是通过选择最优的动作来最大化预期回报。
在DQN算法中,我们可以将每个状态表示为一个向量,并将每个动作表示为一个标量。例如,对于状态0,我们可以将其表示为向量[1, 0, 0, 0],其中第一个元素为1,其余元素为0。同样,对于动作"向左",我们可以将其表示为标量-1。
在训练过程中,智能体会不断地与环境交互,并记录下每次交互的经验。经验包括当前状态、采取的动作、获得的奖励以及下一个状态。然后,DQN算法会根据这些经验来更新深度神经网络的参数。具体来说,它会计算每个状态-动作对的预期回报,并将其作为目标值。接着,它会使用梯度下降等优化算法来最小化损失函数,从而更新网络的权重。
在训练完成后,智能体可以根据当前状态输入到深度神经网络中,得到该状态下每个可能动作的预期回报。然后,根据这些预期回报选择最优的动作。这样,我们就可以利用DQN算法来解决强化学习问题了。
c.代码示例
下面是一个使用DQN算法解决强化学习的简单Python代码示例:
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
# 定义环境参数
state_size = 4
action_size = 3
learning_rate = 0.001
discount_factor = 0.99
epsilon = 1.0
epsilon_decay = 0.995
epsilon_min = 0.01
num_episodes = 1000
# 定义深度神经网络模型
model = Sequential()
model.add(Flatten(input_shape=(1, state_size)))
model.add(Dense(24, activation='relu'))
model.add(Dense(24, activation='relu'))
model.add(Dense(action_size, activation='linear'))
model.compile(loss='mse', optimizer=Adam(lr=learning_rate))
# 定义经验回放缓冲区
class ReplayBuffer:
def __init__(self, buffer_size):
self.buffer_size = buffer_size
self.buffer = []
def add(self, experience):
if len(self.buffer) >= self.buffer_size:
self.buffer.pop(0)
self.buffer.append(experience)
def sample(self, batch_size):
return random.sample(self.buffer, batch_size)
def __len__(self):
return len(self.buffer)
replay_buffer = ReplayBuffer(10000)
# 训练智能体
for episode in range(num_episodes):
state = env.reset()
state = np.reshape(state, [1, state_size])
done = False
total_reward = 0
while not done:
if np.random.rand() <= epsilon:
action = env.action_space.sample()
else:
action = np.argmax(model.predict(state))
next_state, reward, done, _ = env.step(action)
next_state = np.reshape(next_state, [1, state_size])
total_reward += reward
replay_buffer.add((state, action, reward, next_state, done))
state = next_state
if len(replay_buffer) > batch_size:
experiences = replay_buffer.sample(batch_size)
states, actions, rewards, next_states, dones = zip(*experiences)
targets = rewards + discount_factor * (np.amax(model.predict(next_states), axis=1)) * (1 - dones)
model.fit(np.array(states), np.array(targets), epochs=1, verbose=0)
if epsilon > epsilon_min:
epsilon *= epsilon_decay
这个示例中,我们使用了一个简单的深度神经网络来逼近Q值函数,并利用经验回放机制来更新网络的权重。在训练过程中,智能体会不断地与环境交互,并将经验添加到经验回放缓冲区中。当缓冲区中的经验数量达到一定阈值时,智能体会从缓冲区中随机抽取一批经验,并使用这些经验来更新网络的权重。
三、机器学习模型评估与选择
1、评估指标
(1)准确率
a、基本概念
准确率是机器学习中的一种基本评估指标,用于量化分类模型的性能。其定义为预测正确的样本数占总样本数的比例。在二分类问题中,准确率的计算公式为:准确率=真正例(TP)+真反例(TN)/所有样本数(TP+FP+FN+TN)。
然而,需要注意的是,准确率虽然简单直观,但在实际应用中可能会产生误导性的结果。例如,当处理的数据集类别分布严重不平衡时,即某一类的样本数量远大于另一类,如果模型将所有样本都预测为数量占比较大的类别,此时的准确率会非常高。但实际上,模型并没有很好地学习到数据的特征,因此在这种情况下,我们通常会选择其他的评估指标,如精确率、召回率等。
b、举例说明
假设我们有以下的样本分类情况:正样本有90个,负样本有10个。在这种情况下,如果我们的模型预测所有的样本都属于正类,那么准确率将会非常高,计算出来是90%。然而,这个高准确率并不能真实反映模型的性能,因为模型并没有正确学习到负样本的特征。
另一方面,如果我们的模型能够较为准确地区分出正负样本,例如预测出了80个正样本和20个负样本,虽然准确率只有80%,但这更能说明模型的学习能力和判断准确性。
(2)精确率
a、基本概念
精确率是机器学习中的一种重要评估指标,用于量化分类模型在预测正例数据时的准确性。具体来说,它是预测正确的正例数据占预测为正例数据的比例。换句话说,它衡量的是被判断为正例的样本中真正正例的比例。
精确率和召回率是一对经常一起使用的评价指标,它们都对衡量机器学习的模型性能非常基本。特别是在处理不平衡分布的数据集时,这两个指标尤其重要。例如,在某一平台的视频搜索中,可能Top5的准确率非常高,也就是Precision@5的结果非常好,这说明模型的排序结果中的Top5的返回值的质量是非常高的。然而,只关注精确率可能会因为过于保守而漏掉许多“没有把握”的正样本,导致召回率降低。因此,在实际应用中,需要根据实际问题的需求和数据的特性,来平衡考虑精确率和召回率。
b、举例说明
假设我们有以下的真实标签和预测标签:
真实标签:[1, 0, 1, 1, 0]
预测标签:[1, 0, 0, 1, 1]
在这个例子中,我们有5个样本,其中2个是正例(标签为1),3个是负例(标签为0)。
-
精确率的计算公式为:TP / (TP + FP) = 2 / (2 + 1) = 0.8333
-
召回率的计算公式为:TP / (TP + FN) = 2 / (2 + 1) = 0.8333
因此,这个模型的精确率和召回率都是0.8333。
(3)召回率
a、基本概念
召回率是机器学习中的一种重要评估指标,用于量化分类模型在预测正例数据时的性能。具体来说,它是预测正确的正例数据占所有实际正例数据的比例。
召回率的提出是为了确保模型能够预测到所有应该被预测到的样本,即使这会导致一些误预测。换句话说,召回率度量了所有真正的正例中被正确识别出的程度。
精确率和召回率是一对经常一起使用的评价指标,它们都对衡量机器学习的模型性能非常基本。特别是在处理不平衡分布的数据集时,这两个指标尤其重要。然而,只关注精确率可能会因为过于保守而漏掉许多“没有把握”的正样本,导致召回率降低。因此,在实际应用中,需要根据实际问题的需求和数据的特性,来平衡考虑精确率和召回率。
b、举例说明
同上。
(4)F1值
a、基本概念
F1值,也被称为F1分数或F1-score,是用于衡量二分类(或多任务二分类)模型精确度的一种指标。它同时兼顾了分类模型的准确率和召回率。F1值是精确率和召回率的调和平均值,它的最大值是1,最小值是0,值越大意味着模型越好。
在实际应用中,我们通常会遇到样本不均衡的情况,此时准确率可能不能合理反映模型的预测能力。例如测试数据集有90%的正样本,10%的负样本,假设模型预测结果全为正样本,这时准确率为90%,然而模型对负样本没有识别能力,此时高准确率不能反映模型的预测能力。而F1值则能更好地在这种情况下反映模型的性能。
为了更全面地评估一个排序模型的好坏,我们不仅要看模型在不同TopN下的Precision@N,Recall@N,而且最好绘制出模型的P-R(Precision-Recall)曲线。这里简单介绍下P-R曲线的绘制方法。 P-R曲线的横轴是召回率,纵轴是精确率。对于一个排序模型来说,其P-R曲线上的一个点代表着,在某一阀值下,模型将大于该阈值的结果判定为正样本,小于该阈值的结果判定为负样本,此时返回结果对应的召回率和精准率。整条P-R曲线是通过将阈值从高到低移动而生成的。
此外,F1 score也有用于多分类问题的版本,包括Micro-F1和Macro-F1两种度量。Micro-F1是统计各个类别的TP、FP、FN、TN,加和构成新的TP、FP、FN、TN,然后计算Micro-Precision和Micro-Recall,得到Micro-F1。Macro-F1则是统计各个类别的TP、FP、FN、TN,分别计算各自的Precision和Recall,得到各自的F1值,然后取平均值得到Macro-F1。
b、举例说明
假设我们有以下的真实标签和预测标签:
真实标签:[1, 0, 1, 1, 0]
预测标签:[1, 0, 0, 1, 1]
在这个例子中,我们有5个样本,其中2个是正例(标签为1),3个是负例(标签为0)。
-
精确率的计算公式为:TP / (TP + FP) = 2 / (2 + 1) = 0.8333
-
召回率的计算公式为:TP / (TP + FN) = 2 / (2 + 1) = 0.8333
-
F1值的计算公式为:2 * Precision * Recall / (Precision + Recall) = 2 * 0.8333 * 0.8333 / (0.8333 + 0.8333) = 0.8667
因此,这个模型的精确率、召回率和F1值都是0.8667。
(5)代码示例
以下是一个使用Python的sklearn库计算准确率、精确率、召回率和F1值的代码示例:
from sklearn import metrics
# 假设我们有以下的真实标签和预测标签
y_true = [0, 1, 1, 0, 1, 1, 0, 0, 1, 1]
y_pred = [0, 1, 0, 0, 1, 1, 0, 1, 1, 1]
# 计算准确率
accuracy = metrics.accuracy_score(y_true, y_pred)
print('Accuracy: {:.2f}'.format(accuracy))
# 计算精确率
precision = metrics.precision_score(y_true, y_pred)
print('Precision: {:.2f}'.format(precision))
# 计算召回率
recall = metrics.recall_score(y_true, y_pred)
print('Recall: {:.2f}'.format(recall))
# 计算F1值
f1 = metrics.f1_score(y_true, y_pred)
print('F1 score: {:.2f}'.format(f1))
在这个例子中,我们首先导入了sklearn库中的metrics模块,然后定义了两个列表y_true和y_pred分别代表真实的标签和模型预测的标签。接着,我们使用metrics模块中的函数来计算准确率、精确率、召回率和F1值,并打印出结果。
2、交叉验证
a、基本概念
交叉验证,也被称为循环估计,是一种统计学方法,它将数据集分割成多个较小的子集。其基本思想是,将原始数据集在某种意义上进行分组,一部分作为训练集用于训练模型,另一部分用作验证集用于测试模型的性能。这个过程会重复多次,例如在LOOCV(Leave-one-out cross-validation)中,数据集中的每个样本都会被轮流作为测试集,其余的样本作为训练集。
交叉验证的主要目的是评估模型的泛化能力和性能,防止模型过度拟合训练数据,从而提高模型对未知数据的预测能力。常见的交叉验证形式包括保留验证、K折交叉验证、分层K折交叉验证、留一交叉验证、留p-out交叉验证、蒙特卡洛交叉验证和时间序列交叉验证等。这些技术在不同的应用场景下都有其特定的优势和适用性。
b、举例说明
假设假设我们有一个包含10个样本的数据集,我们要用这10个样本来训练一个模型。
如果我们选择留一交叉验证(LOOCV),那么我们会进行10次训练和验证过程。在每次过程中,我们都会选择一个样本作为验证集,其余9个样本作为训练集。例如,第一次我们可能会选择第一个样本作为验证集,其余9个样本作为训练集;第二次我们可能会选择第二个样本作为验证集,其余8个样本作为训练集,以此类推。
这样,我们就可以得到10个不同的模型和对应的性能评估结果。然后我们可以取这10个结果的平均值作为最终的性能评估结果。
通过这种方式,我们可以充分利用有限的数据资源,同时也可以有效地避免过拟合问题。
3、代码示例
以下是一个使用Python的scikit-learn库进行留一交叉验证的例子:
from sklearn.model_selection import LeaveOneOut
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 初始化留一交叉验证对象
loo = LeaveOneOut()
# 初始化逻辑回归模型
lr = LogisticRegression(solver='liblinear')
# 存储每次迭代的性能评估结果
scores = []
# 进行留一交叉验证
for train_index, test_index in loo.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
# 训练模型并预测测试集
lr.fit(X_train, y_train)
score = lr.score(X_test, y_test)
# 将性能评估结果添加到列表中
scores.append(score)
# 计算平均性能评估结果
average_score = sum(scores) / len(scores)
print('Average score:', average_score)
在这个例子中,我们使用了鸢尾花数据集和逻辑回归模型。我们首先初始化了一个留一交叉验证对象和一个逻辑回归模型。然后,我们对每个样本进行留一交叉验证,训练模型并预测测试集,将性能评估结果添加到一个列表中。最后,我们计算了所有性能评估结果的平均值作为最终的性能评估结果。
3、模型选择与调优
a、基本概念
模型选择与调优是机器学习中的两个重要环节。模型选择是指在多个模型中选择最优的模型,以达到最好的性能和泛化能力。当假设空间含有不同复杂度的模型时,就要面临模型选择的问题。我们希望选择或学习一个合适的模型。如果在假设空间中存在真模型,那么所选择的模型应该逼近真模型。
模型调优则是通过调整模型参数、特征选择等方法来提高模型的性能。常见的模型调优方法包括超参数调优、特征选择和模型集成等。超参数调优是指对在训练模型时需要手动设置的参数进行调整,例如正则化系数、学习率等。超参数的调优可以通过网格搜索(Grid Search)、随机搜索(Random Search)等方法来完成。特征选择是从原始特征中选择出最重要的特征,以减少模型的复杂度并提高模型的泛化性能。常用的特征选择算法包括卡方检验、互信息和递归特征消除等。
b、举例说明
假设我们有一个数据集,包含多个特征和目标变量。我们希望使用这个数据集来训练一个机器学习模型,并选择最优的超参数。
首先,我们可以使用网格搜索(Grid Search)方法来进行超参数调优。网格搜索是一种穷举搜索方法,它会尝试所有可能的超参数组合,然后选择性能最好的组合。
3、代码示例
以下是一个使用Python的scikit-learn库进行网格搜索的例子:
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
# 初始化随机森林分类器
rf = RandomForestClassifier()
# 定义超参数搜索空间
param_grid = {
'n_estimators': [10, 50, 100],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10]
}
# 初始化网格搜索对象
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=3)
# 执行网格搜索
grid_search.fit(X, y)
# 输出最优超参数组合
print("Best parameters: ", grid_search.best_params_)
在这个例子中,我们使用了随机森林分类器作为我们的模型,并定义了一个超参数搜索空间,包括树的数量、最大深度和最小样本分割数等。然后,我们使用网格搜索方法来寻找最优的超参数组合。最后,我们输出了最优的超参数组合。