目录
多分类任务(Multi-class Classification):
多标签分类任务(Multi-label Classification):
Voting Classifier 和 Soft Voting Classifier
写在前面的话
通过本篇文章的学习,大家可以对机器学习这门学科的基本框架有一个初步的了解。
非常适合初识机器学习的小伙伴。
当然它也是人工智能、大模型、深度学习、神经网络、这些目前特别热且前沿的技术的基石。
在算法部分,每个经典算法都有具体实例代码演练,希望初次学习的小伙伴可以下载搭建基础的运行环境来实操一下,尤其是数字识别、人脸识别那一部分,还是很有趣味性的。
文章也会涉及到一些数学知识,如函数应用,因为机器学习很多算法的原理就是数学函数求解来的。所以学习机器学习,数学是根本绕不开的,不会推导数学函数的只需知道这个函数的具体作用即可。
还有就是文章篇幅字数都很长,阅读前可以先看一下目录,可以有一个初步的框架。
好了废话不多说,开启学习之旅吧。
一、机器学习的基本任务与方法分类
机器学习的概念和定义
机器学习是一种人工智能(AI)的分支领域,旨在让计算机系统通过学习数据模式和规律,从而进行预测、分类、识别等任务,而无需明确地编程这些任务的规则。
具体来说,机器学习的过程通常包括以下几个步骤:
-
数据收集:收集与问题相关的数据样本,这些数据样本包含了输入特征和对应的目标输出。数据可以来自各种来源,包括传感器、数据库、API等。
-
数据预处理:对收集到的数据进行清洗、转换和规范化等预处理操作,以保证数据的质量和一致性。预处理包括处理缺失值、异常值、数据平滑、特征缩放等。
-
特征工程:选择合适的特征,并进行特征提取、特征选择、特征变换等操作,以提高模型的性能和泛化能力。特征工程对机器学习模型至关重要,它直接影响到模型的表现和效果。
-
选择模型:根据问题的性质和数据的特点选择合适的机器学习模型。常见的机器学习模型包括线性回归、逻辑回归、决策树、支持向量机、神经网络等。
-
模型训练:使用训练数据集对选定的模型进行训练。训练过程中,模型通过学习数据样本的模式和规律来调整自身的参数,以最小化预测结果与真实标签之间的差异。
-
模型评估:使用评估数据集对训练好的模型进行评估,以验证模型的性能和泛化能力。常用的评估指标包括准确率、精确率、召回率、F1分数、ROC曲线等。
-
模型调优:根据评估结果对模型进行调优,包括调整超参数、改进特征工程、调整模型结构等操作,以提高模型的性能和泛化能力。
-
模型部署:将训练好的模型部署到实际应用环境中,并与其他系统集成。在部署过程中需要考虑模型的性能、稳定性、安全性等因素。
综上所述,机器学习的核心目标是利用数据和算法构建模型,从而实现对未知数据的预测和分类。机器学习技术已经被广泛应用于各个领域,包括医疗、金融、电商、智能驾驶等,为人类提供了更加智能化的服务和决策支持。
基本任务
机器学习的分类任务可以根据输出结果的类型和特点分为以下几类:
-
二分类任务(Binary Classification):
- 特点:输出结果为两个类别之一,通常表示为正类(positive)和负类(negative)。
- 示例:垃圾邮件识别、疾病诊断(是否患有某种疾病)、欺诈检测(是否存在欺诈行为)等。
-
多分类任务(Multi-class Classification):
- 特点:输出结果为多个类别中的一个,可以是三个或三个以上的类别。
- 示例:手写数字识别(数字0-9的识别)、图像分类(动物种类识别)、语音识别(语音指令识别)等。
-
多标签分类任务(Multi-label Classification):
- 特点:每个样本可以属于多个类别,输出结果为多个二进制标签。
- 示例:新闻主题分类(一篇新闻可以同时属于多个主题)、图像标签分类(一张图片可以包含多个物体)等。
-
回归任务(Regression):
- 特点:输出结果是一个连续的数值。
- 示例:房价预测、股票价格预测、销售额预测等。
方法分类
监督学习
概念:训练数据具有明确的标签或答案,机器学习算法通过这些标签来学习模式和关系,以便对新数据进行预测或分类。
应用场景:广泛应用于分类和回归问题,如垃圾邮件分类、房价预测等。
算法选择:根据数据类型和问题需求选择合适的监督学习算法,例如分类问题可选用逻辑回归、决策树等,回归问题可选用线性回归、多项式回归等。
非监督学习
概念:训练数据没有明确的标签,机器学习算法需要自行发现数据中的模式和结构,通常通过聚类等方法进行分析。
应用场景:用于发现数据中的隐藏模式、聚类、降维等任务,如市场分析、用户分群等。
算法选择:根据任务需求选择合适的非监督学习算法,例如K均值聚类、DBSCAN聚类、主成分分析(PCA)等。
半监督学习
概念:一部分数据拥有“标记”或者答案,另一部分数据没用有。
应用场景:当标注数据成本高昂或难以获取时,半监督学习可以利用少量标记数据和大量未标记数据来提高模型性能。
算法选择:半监督学习算法包括基于图的半监督学习、自训练、生成式模型等。
增强学习
概念:根据周围的环境情况,采取行为,根据采取行动的结果,学习行动方式。直白讲就是 一圈一圈的跑,不断的自动优化。监督学习和非监督学习是它的基础。
应用场景:适用于需要在复杂环境中做出决策和行动的问题,例如智能游戏玩家、无人驾驶汽车等。
算法选择:增强学习算法包括Q学习、策略梯度方法、深度强化学习等。
批量学习与在线学习
批量学习就是使用大量的数据资料生成固定的生产环境模型,优点是简单,缺点是没法适应环境的变化,一但变化需要重新跑大量的数据重新生成模型。
在线学习就是每次生成模型的输入和输出结果都是训练的数据,缺点就是新的数据(不好、不准确的结果)有可能给模型带来不好的结果和影响,解决方案就是对数据进行监控。
应用场景:批量学习适用于数据量较小、稳定的场景,而在线学习适用于数据量较大、动态变化的场景。
算法选择:批量学习常用的算法有梯度下降、牛顿法等,而在线学习常用的算法有随机梯度下降、在线学习向量量化等。
参数学习与非参数学习
参数学习对模型做出一定假设,并学习这些假设的参数,例如线性回归、逻辑回归等。 一旦学到了参数,就不再需要原有的数据集
非参数学习不对模型进行过多的假设,非参数不等于没参数,根据数据自行学习模型的复杂性,例如决策树、随机森林等。
应用场景:参数学习通常用于对数据具有一定先验假设的情况,非参数学习则更适用于数据分布不确定的情况。
算法选择:参数学习的算法有限,如线性回归、逻辑回归等,而非参数学习的算法更灵活,如决策树、随机森林等。
机器学习相关的“哲学”思考
机器学习主要处理一些不确定的一些问题,这和我们传统的一些经典算法不同,经典的算法都是有唯一固定的答案的,但是机器学习不同,它面对的是高度不确定的问题。数据和算法是提升机器学习能力的的两大因素。
算法的选择:奥卡姆剃刀(简单的就是好的),脱离具体问题,谈哪个算法好是没用意义的,在面对一个具体问题的时候,尝试使用多种算法进行对比实验,是必要的。
面对不确定的世界,怎么看待使用机器学习进行预测的结果?
二、部署安装基础运行环境
安装anaconda集成环境
Anaconda是一个用于科学计算的开源软件包管理器和环境管理器,它是Python和R编程语言的发行版,包含了数千个常用的Python和R软件包,以及数据科学和机器学习工具,如NumPy、Pandas、Matplotlib、Scikit-learn等。
允许用户创建多个独立的环境,每个环境可以有不同的Python版本和软件包集合,以满足不同项目的需求。
支持Windows、Linux和macOS等主流操作系统,用户可以在不同平台上使用相同的开发环境和工具。
Anaconda是一个功能强大的科学计算平台,它为用户提供了方便快捷的软件包管理和环境管理工具,使得Python和R编程变得更加简单和高效。
官方下载地址:https://www.anaconda.com/download
安装pycharm编辑器
官方下载地址:PyCharm:JetBrains为专业开发者提供的Python IDE
pycharm包含收费版和社区版,社区版是开源可以免费使用的
测试运行环境
import numpy
import matplotlib
import sklearn
import pandas
print("Hello Machine Learning!")
注意:如果运行报错依赖包找不到,检查pycharm的python解释器是否conda环境,如果不是需要添加conda环境的解释器,conda 自带了以上测试代码的依赖包,如果是系统环境或者其它,pip安装以上依赖包也是可以的。
jupter Notebook 的基础使用以及一些魔术方法
Jupyter Notebook是一个交互式的笔记本环境,支持多种编程语言,最常用的是Python。下面是关于Jupyter Notebook的基础使用以及一些常用的技巧和魔术命令:
1. 基础使用:
- 启动Jupyter Notebook:在命令行中输入
jupyter notebook
并回车,将会在默认浏览器中打开Jupyter Notebook的主界面。 - 创建新的Notebook:在主界面点击右上角的"New"按钮,选择要创建的Notebook类型(如Python、R等)。
- 执行代码:在代码单元格中输入代码,按Shift + Enter执行代码并移动到下一个单元格,按Ctrl + Enter执行代码并停留在当前单元格。
- 插入新的输入框:在菜单栏中选择"Insert" -> "Insert Cell Below"(在当前单元格下方插入新的单元格)或者"Insert" -> "Insert Cell Above"(在当前单元格上方插入新的单元格)。
- 删除单元格:选择要删除的单元格,点击菜单栏中的"Edit" -> "Delete Cells"或者按下键盘上的D键两次。
2. 快捷键操作:
- 运行单元格:Shift + Enter(执行并移动到下一个单元格)或者Ctrl + Enter(执行并保留在当前单元格)。
- 插入新的单元格:在命令模式下按A(在当前单元格上方插入)或者B(在当前单元格下方插入)。
- 删除单元格:在命令模式下按D两次。
- 切换单元格模式:在命令模式下按Y切换到代码模式,按M切换到Markdown模式。
- 保存Notebook:按Ctrl + S保存当前Notebook。
3. 常用魔法命令:
%run
:运行外部Python脚本。%timeit
:测量代码执行时间。%matplotlib inline
:在Notebook中显示Matplotlib图形。%reset
:清除所有变量的名称空间。%%writefile
:将单元格中的内容写入文件。%load
:加载外部Python脚本或模块。%pwd
:显示当前工作目录路径。%cd
:更改当前工作目录。%ls
:列出当前目录的文件和子目录。
三、基础数据科学工具库
在学习机器学习中我们需要Python中用于科学计算的一个重要工具包,它们提供了高效的相关操作函数。下面只是介绍了比较常用的和下面文章中用到的几个依赖包。
1. NumPy基础操作
NumPy是Python中用于科学计算的一个重要工具包,它提供了高效的多维数组对象和相应的操作函数。以下是一些基础操作:
- 创建数组和矩阵:使用
np.array()
函数创建数组,使用np.matrix()
函数创建矩阵。 - 基本属性:数组的形状、维度、数据类型等属性。
- 数据访问:索引和切片操作访问数组中的元素。
- 合并与分隔:使用
np.concatenate()
和np.split()
函数合并和分隔数组。 - 维度修改:使用
np.reshape()
函数修改数组的维度。
2. NumPy数组的运算
NumPy数组支持各种数学运算,包括向量和矩阵的运算、聚合运算、数学函数运算等。
- 数组运算:加减乘除、乘方、求余等。
- 数学函数运算:绝对值、正弦、余弦、正切、指数等数学函数运算。
- 矩阵运算:矩阵乘法、逆矩阵、伪逆矩阵等。
3. Matplotlib基础
Matplotlib是Python中用于绘制数据图表的库,常用于数据可视化。
- 绘制线图、散点图、柱状图等:使用
plt.plot()
、plt.scatter()
、plt.bar()
等函数进行绘制。 - 设置坐标轴、标题和标签:使用
plt.xlabel()
、plt.ylabel()
、plt.title()
等函数设置图表属性。 - 添加图例:使用
plt.legend()
函数添加图例以标识不同的数据系列。
4. sklearn.datasets
sklearn.datasets
模块包含了一些常用的数据集,可以用于机器学习任务的训练和测试。
- 加载数据集:使用
sklearn.datasets.load_*()
函数加载对应的数据集。 - 查看数据集文档:通过查看相应函数的文档,了解数据集的属性、特征和标签等信息。
四、最基础的分类算法kNN
kNN邻近算法:两个(或者多个)特征的数据集,计算新的数据点邻近或者属于哪一类的特征数据集。
特点:适合入门机器学习、思想极度简单、应用数学知识少、可以解释机器学习算法使用过程中的很多细节问题、更完整的刻画机器学习应用流程。
1、欧拉距离
欧拉距离是一种用于衡量两个点之间的距离的方法,通常用于几何学和机器学习等领域。简单来说,欧拉距离表示两个点在空间中的直线距离,就像我们在地图上测量两个地点之间的直线距离一样。无论是在二维平面还是在更高维的空间都适用。
2、使用代码实现knn算法的实现过程
import numpy as np
import matplotlib.pyplot as plt
#查看raw_data_x原始数据集的特征点
aw_data_x = [[3.37086107,2.18526045],
[3.55642876,1.72918867],
[1.58794548,3.49198377],
[3.38792636,4.91105222],
[2.40416776,2.63642478],
[7.40395068,4.65064059],
[5.52275251,3.73818019],
[9.79558531,2.72280788],
[7.41003511,3.88750517],
[7.3726532,0.62106226]]
raw_data_y = [0,0,0,0,0,1,1,1,1,1] #0为蓝色特征 1 为红色特征
x_train = np.array(raw_data_x)
y_train = np.array(raw_data_y)
plt.scatter(x_train[y_train==0,0],x_train[y_train==0,1],color='g')
plt.scatter(x_train[y_train==1,0],x_train[y_train==1,1],color='r')
plt.show() #得到以下特征散点图
x = np.array([8.09565541,3.52106226]) #又来了新的数据,判断是红色的一类还是绿色的一类
plt.scatter(x_train[y_train==0,0],x_train[y_train==0,1],color='g')
plt.scatter(x_train[y_train==1,0],x_train[y_train==1,1],color='r')
plt.scatter(x[0],x[1],color='b')
plt.show() #查看新的数据在散点图的位置
knn实现过程(求蓝色点属于哪一类特征)
from math import sqrt
from collections import Counter
#### 第一步 计算 x 新的 点 和 矩阵里每个点的 欧拉距离
### 分步骤解析
distances = [] #新的x数据与所有点的距离容器
for arr in x_train:
a = (arr - x) # 原始数据 arr[a,b]- 新的数据 x[a,b]
b = a**2 # 平方 [x,y]
c = sqrt(np.sum(b)) # a[x,y] 开方(x + y) = 欧拉距离
distances.append(c) # 赋值
distances = [sqrt(np.sum((arr - x)** 2)) for arr in x_train] # 简写 同上效果一样
distances
#### 第二步 求 离新的点最近的两个点
nearest = np.argsort(distances)#点的距离又近到远排序拿到索引 = distances 排序(正序) 并 获取 distances 的索引
k = 6
topk_y = [y_train[i] for i in nearest[:k]] #循环nearest 拿到 y_train对应的类型值 [1, 1, 1, 1, 1, 0]
votes = Counter(topk_y) # Counter({1: 5, 0: 1}) 统计 topk_y 类型的数量(数组元素的数量)
most = votes.most_common(1) #找到票数最多的 1 个元素 [(1, 5)] 类型 1 为 5 次
most[0][0] #取出邻近最终类型 1 红色特征
3、自行封装kNN邻近算法并测试
使用pycharm编辑器创建conda解释器kNN_function包,封装kNN_classify方法
mport numpy as np
from math import sqrt
from collections import Counter
def kNN_classify(k,X_train,y_train,x):
assert 1 <= k <= X_train.shape[0], \
"the size if X_train must equal to the size of y_train"
assert X_train.shape[1] == x.shape[0], \
"the feature number if x nust be equal to X_train"
distances = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]
nearest = np.argsort(distances)
topK_y = [y_train[i] for i in nearest[:k]]
votes = Counter(topK_y)
return votes.most_common(1)[0][0]
以下是jupyter NotBook 新建的测试kNN方法的代码,注意测试的py文件需要和kNN_function包在
同一目录下
import numpy as np
import matplotlib.pyplot as plt
raw_data_x = [[3.37086107,2.18526045],
[3.55642876,1.72918867],
[1.58794548,3.49198377],
[3.38792636,4.91105222],
[2.40416776,2.63642478],
[7.40395068,4.65064059],
[5.52275251,3.73818019],
[9.79558531,2.72280788],
[7.41003511,3.88750517],
[7.3726532,0.62106226]]
raw_data_y = [0,0,0,0,0,1,1,1,1,1]
X_train = np.array(raw_data_x)
y_train = np.array(raw_data_y)
x = np.array([8.09565541,3.52106226])
%run kNN_function/kNN.py #加载kNN.py文件
predict_y = kNN_classify(6,X_train,y_train,x)
predict_y
4、使用scikit-learn中的kNN
from sklearn.neighbors import KNeighborsClassifier #引用scikit-learn中的 KNeighborsClassifier 类
knnClassfierObj = KNeighborsClassifier(n_neighbors=6)
knnClassfierObj.fit(X_train,y_train)
x_predict = x.reshape(1,-1) #一维转矩阵
y_predict = knnClassfierObj.predict(x_predict)# 传入新的数据
y_predict[0]
5、仿照scikit-learn封装kNN
import numpy as np
from math import sqrt
from collections import Counter
from .metrics import accuracy_score
class KNNClassifier:
def __init__(self, k):
"""初始化kNN分类器"""
assert k >= 1, "k must be valid"
self.k = k
self._X_train = None
self._y_train = None
def fit(self, X_train, y_train):
"""根据训练数据集X_train和y_train训练kNN分类器"""
assert X_train.shape[0] == y_train.shape[0], \
"the size of X_train must be equal to the size of y_train"
assert self.k <= X_train.shape[0], \
"the size of X_train must be at least k."
self._X_train = X_train
self._y_train = y_train
return self
def predict(self, X_predict):
"""给定待预测数据集X_predict,返回表示X_predict的结果向量"""
assert self._X_train is not None and self._y_train is not None, \
"must fit before predict!"
assert X_predict.shape[1] == self._X_train.shape[1], \
"the feature number of X_predict must be equal to X_train"
y_predict = [self._predict(x) for x in X_predict]
return np.array(y_predict)
def _predict(self, x):
"""给定单个待预测数据x,返回x的预测结果值"""
assert x.shape[0] == self._X_train.shape[1], \
"the feature number of x must be equal to X_train"
distances = [sqrt(np.sum((x_train - x) ** 2))
for x_train in self._X_train]
nearest = np.argsort(distances)
topK_y = [self._y_train[i] for i in nearest[:self.k]]
votes = Counter(topK_y)
return votes.most_common(1)[0][0]
def score(self, X_test, y_test):
"""根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""
y_predict = self.predict(X_test)
return accuracy_score(y_test, y_predict)
def __repr__(self):
return "KNN(k=%d)" % self.k
6、使用sklearn数据集测试封装的算法
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
iris = datasets.load_iris() # 获取 sklearn datasets 的 莺尾花测试数据集
X = iris.data # (150,4) 矩阵
y = iris.target # (150,)数组
# train_test_split 拆分数据集 1 训练数据集 2 测试数据集
shuffle_indexes = np.random.permutation(len(X)) # 拿到 X 数据集 随机的 索引
test_ratio = 0.2 #训练数据集和测试数据集分配比例
test_size = int(len(X) * test_ratio)
test_indexes = shuffle_indexes[:test_size] #测试数据集索引
train_indexes = shuffle_indexes[test_size:]#训练数据集索引
#训练数据集
x_train = X[train_indexes]
y_train = y[train_indexes]
#测试数据集
x_test = X[test_indexes]
y_test = y[test_indexes]
from playML.kNN import KNNClassifier
my_knn_clf = KNNClassifier(k=3)
my_knn_clf.fit(x_train, y_train)
y_predict = my_knn_clf.predict(x_test)
print(y_predict)
similarity = sum(y_predict == y_test) / len(y_test)#训练出的数据与测试数据集相似度
#使用sklearn.model_selection 类库生成 训练和测试数据集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
print(len(X_train))
print(len(X_test))
7、输出结果分类的准确度
当我们有了准确的训练数据集和测试数据集,那么我们怎么验证自己写的算法输出的结果是否标准呢,就用到了结果分类的准确度,通过准确度验证结果和测试数据的相似程度。
下面是代码实现验证过程
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
digits = datasets.load_digits()# 加载 sklearn datasets 下的 digits 数据集
X = digits.data #原始数据集
y = digits.target #数据特征分类 target
#可视化查看一下数据的特性
import matplotl