前言

机器学习(Machine Learning)本质上就是让计算机自己在数据中学习规律,并根据所得到的规律对未来数据进行预测。机器学习包括如聚类、分类、决策树、贝叶斯、神经网络、深度学习(Deep Learning)等算法。机器学习的基本思路是模仿人类学习行为的过程,如我们在现实中的新问题一般是通过经验归纳,总结规律,从而预测未来的过程。

机器学习涉及到线性代数、微积分、概率和统计。学习机器学习需要掌握一定的数学和编程基础。以下是一些建议,帮助您开始学习机器学习:

  • 学习数学基础:了解线性代数、概率论和统计学等数学概念。这些概念在机器学习中非常重要,可以帮助您理解算法和模型背后的原理。
  • 学习编程语言:掌握至少一种常用的编程语言,如Python或R。这些语言在机器学习中广泛使用,具有丰富的机器学习库和工具。
  • 学习机器学习算法:了解常见的机器学习算法,如线性回归、决策树、支持向量机、神经网络等。学习它们的原理、应用和优缺点。
  • 学习机器学习工具和框架:熟悉常用的机器学习工具和框架,如scikit-learn、TensorFlow、PyTorch等。掌握它们的使用方法和基本操作。

一、机器学习介绍

1.1 发展历史

在这里插入图片描述

1.2 分类

机器学习经过几十年的发展,衍生出了很多种分类方法,这里按学习模式的不同,可分为监督学习、半监督学习、无监督学习和强化学习。

1.2.1 监督学习

监督学习(Supervised Learning)是从有标签的训练数据中学习模型,然后对某个给定的新数据利用模型预测它的标签。如果分类标签精确度越高,则学习模型准确度越高,预测结果越精确。其主要用于回归和分类。

  • 常见的监督学习的回归算法有线性回归、回归树、K邻近、Adaboost、神经网络等。
  • 常见的监督学习的分类算法有朴素贝叶斯、决策树、SVM、逻辑回归、K邻近、Adaboost、神经网络等。

1.2.2 半监督学习

半监督学习(Semi-Supervised Learning)是利用少量标注数据和大量无标注数据进行学习的模式。其侧重于在有监督的分类算法中加入无标记样本来实现半监督分类。

常见的半监督学习算法有Pseudo-Label、Π-Model、Temporal Ensembling、Mean
Teacher、VAT、UDA、MixMatch、ReMixMatch、FixMatch等。

1.2.3 无监督学习

无监督学习(Unsupervised Learning)是从未标注数据中寻找隐含结构的过程。其主要用于关联分析、聚类和降维。

常见的无监督学习算法有稀疏自编码(Sparse Auto-Encoder)、主成分分析(Principal Component
Analysis, PCA)、K-Means算法(K均值算法)、DBSCAN算法(Density-Based Spatial
Clustering of Applications with Noise)、最大期望算法(Expectation-Maximization
algorithm, EM)等。

1.2.4 强化学习

强化学习(Reinforcement Learning)类似于监督学习,但未使用样本数据进行训练,是是通过不断试错进行学习的模式。

在强化学习中,有两个可以进行交互的对象:智能体(Agnet)和环境(Environment),还有四个核心要素:策略(Policy)、回报函数(收益信号,Reward Function)、价值函数(Value Function)和环境模型(Environment Model),其中环境模型是可选的。

强化学习常用于机器人避障、棋牌类游戏、广告和推荐等应用场景中。

1.3 应用场合

机器学习的应用场景非常广泛,几乎涵盖了各个行业和领域。以下是一些常见的机器学习应用场景的:

  1. 自然语言处理(NLP)
  2. 医疗诊断与影像分析
  3. 金融风险管理
  4. 预测与推荐系统
  5. 制造业和物联网
  6. 能源管理与环境保护
  7. 决策支持与智能分析
  8. 图像识别与计算机视觉

1.4 开发步骤

有5个基本步骤用于执行机器学习任务:

  1. 收集数据:无论是来自excel,access,文本文件等的原始数据,这一步(收集过去的数据)构成了未来学习的基础。相关数据的种类,密度和数量越多,机器的学习前景就越好。
  2. 准备数据:任何分析过程都会依赖于使用的数据质量如何。人们需要花时间确定数据质量,然后采取措施解决诸如缺失的数据和异常值的处理等问题。探索性分析可能是一种详细研究数据细微差别的方法,从而使数据的质量迅速提高。
  3. 练模型:此步骤涉及以模型的形式选择适当的算法和数据表示。清理后的数据分为两部分 - 训练和测试(比例视前提确定); 第一部分(训练数据)用于开发模型。第二部分(测试数据)用作参考依据。
  4. 评估模型:为了测试准确性,使用数据的第二部分(保持/测试数据)。此步骤根据结果确定算法选择的精度。检查模型准确性的更好测试是查看其在模型构建期间根本未使用的数据的性能。
  5. 提高性能:此步骤可能涉及选择完全不同的模型或引入更多变量来提高效率。这就是为什么需要花费大量时间进行数据收集和准备的原因。

无论是任何模型,这5个步骤都可用于构建技术,
在这里插入图片描述

二、scikit-learn

这里我们使用scikit-learn来讲解机器学习

  1. Python语言机器学习工具
  2. Scikit-learn包括许多智能的机器学习算法的实现
  3. Scikit-learn文档完善,容易上手,丰富的API接口函数
  4. Scikit-learn官网
  5. Scikit-learn中文文档
  6. scikit-learn中文社区

安装细则请参考安装教程,这里仅给出pip安装指令。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scikit-learn

Scikit-learn包含的内容有:
在这里插入图片描述

三、数据集

3.1 常用数据集

3.1.1 内置数据集

数据量小,数据在sklearn库的本地,只要安装了sklearn,不用上网就可以获取。
在这里插入图片描述
波士顿房价数据集因涉及种族问题现已无法使用了。

这里以内置的鸢尾花数据集为例:

from sklearn.datasets import load_iris

iris = load_iris()
'''
data 特征
feature_names 特征描述
target  目标
target_names  目标描述
DESCR 数据集的描述
filename 下后到本地保存后的文件名
'''
print(iris.data[:10])
print(iris.target)
print(iris.feature_names)
print(iris.target_names)
print(iris.DESCR)
print(iris.filename)

运行结果如下:
在这里插入图片描述
在这里插入图片描述

3.1.2 在线数据集

数据量大,数据只能通过网络获取。
在这里插入图片描述
从网上下载的数据集可以通过以下命令查看所存储的位置:

from sklearn import datasets
datasets.get_data_home()  #查看数据集默认存放的位置

由于这些数据集通常比较大,一般推荐事先下载好后,在运行时指定路径读取。以下方代码为例:

from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(data_home='D:\mytemp\sklearn_datasets\src',subset='all')
print(news.data[0])

其中使用到的api有:

  • sklearn.datasets.fetch_20newsgroups(data_home,subset)
    函数参数说明:
    data_home
  • 默认值为None,代表下载的文件路径为“C:/Users/ADMIN/scikit_learn_data/20news-bydate_py3.pkz”
  • 也可自定义路径 例如“./src”, 下载的文件路径为“./src/20news-bydate_py3.pkz”

subset

  • “train”,只下载训练集
  • “test”,只下载测试集
  • “all”, 下载的数据包含了训练集和测试集

return_X_y,决定着返回值的情况

参数类型为布尔型,默认值 False

函数返值说明:

当参数return_X_y值为False时, 函数返回Bunch对象,Bunch对象中有以下属性

  • *data:特征数据集, 长度为18846的列表list, 每一个元素就是一篇新闻内容, 共有18846篇
  • *target:目标数据集,长度为18846的数组ndarray, 第一个元素是一个整数,整数值为[0,20)
  • *target_names:目标描述,长度为20的list
  • *filenames:长度为18846的ndarray, 元素为字符串,代表新闻的数据位置的路 径
    当参数return_X_y值为True时,函数返回值为元组,元组长度为2, 第一个元素值为特征数据集,第二个元素值为目标数据集

示例代码如下:

from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(data_home='D:\mytemp\sklearn_datasets\src',subset='all')
print(news.data[0])
print(news.target[0])
print(news.target_names)
print(news.DESCR)

3.2 自建数据集

我们也可读取本地数据集,其文件格式通常为.csv。

  • 方式1:打开计事本,写出如下数据,数据之间使用英文下的逗号, 保存文件后把后缀名改为csv。
  • 方式2:创建excel 文件, 填写数据,以csv为后缀保存文件。

使用pandas的read_csv(“文件路径”)函数可以加载csv文件,得到的结果为数据的DataFrame形式。

import pandas as pd
csv=pd.read_csv('.\mydata.csv')
print(csv)

3.3 数据集划分

通常我们需要将数据集划分为训练集与测试集时,可以使用sklearn中api进行快捷划分。

  • **sklearn.model_selection.train_test_split(*arrays,options)
    参数:
  • array 这里用于接收1到多个"列表、numpy数组、稀疏矩阵或padas中的DataFrame"。

  • options, 关键字参数有:

    • test_size:值为0.0到1.0的小数,表示划分后测试集占的比例。
    • random_state:值为任意整数,表示随机种子,使用相同的随机种子对相同的数据集多次划分结果是相同的。否则多半不同。
    • shuffle : 布尔值,默认为True。表示在划分之前是否打乱数据。如果为False,则不会打乱数据,且stratify参数必须为None。
  • stratify : 数组型(array-like)或None,默认为None。如果传入标签数组,则划分后的训练集和测试集将保持与原始数据相同的类别比例。对于x,y型数据集一般填y即可。

  • 返回值说明:
    返回值为列表list, 列表长度与形参array接收到的参数数量相关联,
    形参array接收到的是什么类型,list中对应被划分出来的两部分就是什么类型

示例代码如下:

from sklearn.model_selection import train_test_split
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=22)
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

运行结果如下:
在这里插入图片描述

四、特征工程

特征工程是将任意数据(如文本或图像)转换为可用于机器学习的数字特征,比如:字典特征提取(特征离散化)、文本特征提取、图像特征提取。。一般使用pandas来进行数据清洗和数据处理、使用sklearn来进行特征工程。

特征工程步骤为:

  • 特征提取, 如果不是像dataframe那样的数据,要进行特征提取,比如字典特征提取,文本特征提取
  • 无量纲化(预处理)
    • 归一化
    • 标准化
  • 降维
    • 底方差过滤特征选择
    • 主成分分析-PCA降维

4.1 特征工程api

实例化转换器对象,转换器类有很多,都是Transformer的子类, 常用的子类有:

DictVectorizer  	字典特征提取
CountVectorizer 	文本特征提取
TfidfVectorizer 	TF-IDF文本特征词的重要程度特征提取 
MinMaxScaler 		归一化
StandardScaler 		标准化
VarianceThreshold 	底方差过滤降维
PCA  				主成分分析降维

转换器对象调用fit_transform()进行转换, 其中fit用于计算数据,transform进行最终转换。fit_transform()可以使用fit()和transform()代替,例如:

data_new = transfer.fit_transform(data)
# 可写成
transfer.fit(data)
data_new = transfer.transform(data)

4.2 DictVectorizer 字典列表特征提取

  • 稀疏矩阵:稀疏矩阵是指一个矩阵中大部分元素为零,只有少数元素是非零的矩阵。在数学和计算机科学中,当一个矩阵的非零元素数量远小于总的元素数量,且非零元素分布没有明显的规律时,这样的矩阵就被认为是稀疏矩阵。由于稀疏矩阵中零元素非常多,存储和处理稀疏矩阵时,通常会采用特殊的存储格式,以节省内存空间并提高计算效率。
  • 三元组表 (Coordinate List, COO):三元组表就是一种稀疏矩阵类型数据,存储非零元素的行索引、列索引和值,形如(行,列) 数据,表示除了列出的有值, 其余全是0。
  • 非稀疏矩阵(稠密矩阵):非稀疏矩阵,或称稠密矩阵,是指矩阵中非零元素的数量与总元素数量相比接近或相等,也就是说矩阵中的大部分元素都是非零的。在这种情况下,矩阵的存储通常采用标准的二维数组形式,因为非零元素密集分布,不需要特殊的压缩或优化存储策略。

二者区别如下:

稀疏矩阵稠密矩阵
存储使用特定的存储格式来节省空间使用常规的数组存储所有元素,无论其是否为零
计算进行计算时可以利用零元素的特性跳过不必要的计算,从而提高效率稠密矩阵在计算时需要处理所有元素,包括零元素
应用领域常见于大规模数据分析、图形学、自然语言处理、机器学习等领域在数学计算、线性代数等通用计算领域更为常见

4.2.1 api

  • 创建转换器对象:
 sklearn.feature_extraction.DictVectorizer(sparse=True)
  • 参数:

    • sparse=True返回类型为csr_matrix的稀疏矩阵。
    • sparse=False表示返回的是数组,数组可以调用.toarray()方法将稀疏矩阵转换为数组。
  • 转换器对象:
    转换器对象调用fit_transform(data)函数,参数data为一维字典数组或一维字典列表,返回转化后的矩阵或数组,通过对象的get_feature_names_out()方法获取特征名。

4.2.2 示例

from sklearn.feature_extraction import DictVectorizer
data = [{'city': '北京', 'temperature': 20}, 
        {'city': '上海', 'temperature': 40}, 
        {'city': '深圳', 'temperature': 30}
]
transformer = DictVectorizer(sparse=True) # sparse=False表示返回的是一个二维数组,sparse=True表示返回的是一个稀疏矩阵
data_new = transformer.fit_transform(data)
print(data_new)
print(transformer.get_feature_names_out())

在这里插入图片描述

4.3 CountVectorizer 文本特征提取

4.3.1 api

sklearn.feature_extraction.text.CountVectorizer

​ 构造函数关键字参数stop_words,值为list,表示词的黑名单(不提取的词),fit_transform函数的返回值为稀疏矩阵。

4.3.2 示例

  • 英文文本提取
data = ["stu is well, stu is great", "You like stu"]
transformer = CountVectorizer()
data_new = transformer.fit_transform(data)
print(data_new.toarray())
print(transformer.get_feature_names_out())

在这里插入图片描述

  • 中文文本提取
    中文文本不像英文文本,中文文本文字之间没有空格,所以要先分词,一般使用jieba分词。
import jieba

def cut_words(data):
    return " ".join(jieba.cut(data))

data = ["机器学习本质上就是让计算机自己在数据中学习规律,并根据所得到的规律对未来数据进行预测。",
        "机器学习包括如聚类、分类、决策树、贝叶斯、神经网络、深度学习等算法",
        "机器学习的基本思路是模仿人类学习行为的过程",
        "机器学习经过几十年的发展可分为监督学习、半监督学习、无监督学习和强化学习。"
]
data2=[cut_words(i) for i in data]
transformer = CountVectorizer()
data_new = transformer.fit_transform(data2)
print(data_new.toarray())
print(transformer.get_feature_names_out())

在这里插入图片描述

4.4 TfidfVectorizer TF-IDF文本特征词的重要程度特征提取

词频(Term Frequency, TF), 表示一个词在当前篇文章中的重要性;
逆文档频率(Inverse Document Frequency, IDF), 反映了词在整个文档集合中的稀有程度,即这个词对文档的区分度。

在这里插入图片描述

sklearn.feature_extraction.text.TfidfVectorizer()
# 构造函数关键字参数stop_words,表示词特征黑名单
# fit_transform函数的返回值为稀疏矩阵
  • 示例代码:
def cut_words(text):
    return " ".join(list(jieba.cut(text)))
    
data = ["事业教育学会会长期间,坚定支持民办教育事业!",  "教育热忱关切、扶持民办学校发展事业","事业做出重大贡献!"]
data_new = [cut_words(v) for v in data]
transfer = TfidfVectorizer(stop_words=['期间', '做出',"重大贡献"]) 
data_final = transfer.fit_transform(data_new)

pd.DataFrame(data_final.toarray(), columns=transfer.get_feature_names_out())

在这里插入图片描述

  • 补充:在sklearn库中 TF-IDF算法做了一些细节的优化

词频 (TF)
词频是指一个词在文档中出现的频率。通常有两种计算方法:

  1. 原始词频:一个词在文档中出现的次数除以文档中总的词数。
  2. 平滑后的词频:为了防止高频词主导向量空间,有时会对词频进行平滑处理,例如使用 1 + log(TF)
  3. 在 TfidfVectorizer 中,TF 默认是:直接使用一个词在文档中出现的次数也就是CountVectorizer的结果

逆文档频率 (IDF)
逆文档频率衡量一个词的普遍重要性。如果一个词在许多文档中都出现,那么它的重要性就会降低。
IDF 的计算公式是:
I D F ( t ) = log ⁡ ⁡ ( 总文档数 包含词 t 的文档数 + 1 ) IDF(t)=\log⁡(\dfrac{总文档数}{包含词t的文档数+1}) IDF(t)=log(包含词t的文档数+1总文档数)
在 TfidfVectorizer 中,IDF 的默认计算公式是:
I D F ( t ) = log ⁡ ⁡ ( 总文档数 + 1 包含词 t 的文档数 + 1 ) + 1 IDF(t)=\log⁡(\dfrac{总文档数+1}{包含词t的文档数+1})+1 IDF(t)=log(包含词t的文档数+1总文档数+1)+1
在 TfidfVectorizer 中还会进行归一化处理(采用的L2归一化)

L2归一化
x 1 归一化后的数据 = x 1 x 1 2 + x 2 2 + . . . x n 2 x_1归一化后的数据=\dfrac{x_1}{\sqrt{x_1^2+x_2^2+...x_n^2}} x1归一化后的数据=x12+x22+...xn2 x1

4.5 无量纲化

无量纲,即没有单位的数据。无量纲化包括"归一化"和"标准化", 为什么要进行无量纲化呢?

通常我们接收到的数据都是带单位的,但我们一般并不关心这些数据究竟有多少,而仅关注这些数据与数据集中其他数据的相对大小,这时我们就可对数据进行无量纲化。

如果保留单位可能会出现如下情况:

这是一个男士的数据表:

编号id身高 h收入 s体重 w
11.75(米)15000(元)120(斤)
21.5(米)16000(元)140(斤)
31.6(米)20000(元)100(斤)

假设算法中需要求它们之间的欧式距离, 这里以编号1和编号2为示例:

L = ( 1.75 − 1.5 ) 2 + ( 15000 − 16000 ) 2 + ( 120 − 140 ) 2 L = \sqrt{(1.75-1.5)^2+(15000-16000)^2+(120-140)^2} L=(1.751.5)2+(1500016000)2+(120140)2

从计算上来看, 发现身高对计算结果没有什么影响, 基本主要由收入来决定了,但是现实生活中,身高是比较重要的判断标准. 所以需要无量纲化.

常用方法如下:

4.4.1 MinMaxScaler 归一化

通过对原始数据进行变换把数据映射到指定区间(默认为0-1)

<1>归一化公式:

在这里插入图片描述

这里的 𝑥min 和 𝑥max 分别是每种特征中的最小值和最大值,而 𝑥是当前特征值,𝑥scaled 是归一化后的特征值。

若要缩放到其他区间,可以使用公式:x=x*(max-min)+min;

比如 [-1, 1]的公式为:在这里插入图片描述

<2>归一化API:
  • sklearn.preprocessing.MinMaxScaler(feature_range)
    参数:默认feature_range=(0,1) 归一化后的值域,可以自己设定

fit_transform函数归一化的原始数据类型可以是list、DataFrame和ndarray, 不可以是稀疏矩阵。fit_transform函数的返回值为ndarray。

<3>归一化示例
from sklearn.preprocessing import MinMaxScaler

data=[[1,2,4],
      [5,1,8],
      [3,9,1]]
transformer = MinMaxScaler(feature_range=())
data_new = transformer.fit_transform(data)
print(data_new)

在这里插入图片描述

<4>缺点

最大值和最小值容易受到异常点影响,所以鲁棒性较差。所以常使用标准化的无量钢化

4.4.2 normalize归一化

api:

from sklearn.preprocessing import normalize
normalize(data, norm='l2', axis=1)
#data是要归一化的数据
#norm是使用那种归一化:"l1"  "l2"  "max
#axis=0是列  axis=1是行
  • L1归一化:绝对值相加作为分母,特征值作为分子。
  • L2归一化:平方相加作为分母,特征值作为分子。
  • max归一化:max作为分母,特征值作为分子。

示例代码:

from sklearn.preprocessing import normalize

x,y=load_iris(return_X_y=True)
x_new = normalize(x[:5], norm='max',axis=0)
print(x[:5])
print(x_new)

在这里插入图片描述

4.4.3 StandardScaler 标准化

在机器学习中,标准化是一种数据预处理技术,也称为数据归一化或特征缩放。它的目的是将不同特征的数值范围缩放到统一的标准范围,以便更好地适应一些机器学习算法,特别是那些对输入数据的尺度敏感的算法。

<1>标准化公式

最常见的标准化方法是Z-score标准化,也称为零均值标准化。它通过对每个特征的值减去其均值,再除以其标准差,将数据转换为均值为0,标准差为1的分布。这可以通过以下公式计算:
在这里插入图片描述
其中,z是转换后的数值,x是原始数据的值,μ是该特征的均值,σ是该特征的 标准差 。

<2> 标准化 API
  • sklearn.preprocessing.StandardScale
    与MinMaxScaler一样,原始数据类型可以是list、DataFrame和ndarray。fit_transform函数的返回值为ndarray, 归一化后得到的数据类型都是ndarray

不能加参数feature_range=(0, 1)

<3>标准化示例
from sklearn.preprocessing import StandardScaler
data=np.random.randint(1,10,(3,4))

transfer=StandardScaler()
print(data)
data=transfer.fit_transform(data)
print(data)
print(transfer.mean_)
print(transfer.var_) # 方差
print(transfer.scale_) # 标准差

在这里插入图片描述

<4> 注意点

在数据预处理中,特别是使用如StandardScaler这样的数据转换器时,fitfit_transformtransform这三个方法的使用是至关重要的,它们各自有不同的作用:

  1. fit:
    • 这个方法用来计算数据的统计信息,比如均值和标准差(在StandardScaler的情况下)。这些统计信息随后会被用于数据的标准化。
    • 你应当仅在训练集上使用fit方法。
  2. fit_transform:
    • 这个方法相当于先调用fit再调用transform,但是它在内部执行得更高效。
    • 它同样应当仅在训练集上使用,它会计算训练集的统计信息并立即应用到该训练集上。
  3. transform:
    • 这个方法使用已经通过fit方法计算出的统计信息来转换数据。
    • 它可以应用于任何数据集,包括训练集、验证集或测试集,但是应用时使用的统计信息必须来自于训练集。

当你在预处理数据时,首先需要在训练集X_train上使用fit_transform,这样做可以一次性完成统计信息的计算和数据的标准化。这是因为我们需要确保模型是基于训练数据的统计信息进行学习的,而不是整个数据集的统计信息。

一旦scaler对象(封装了训练数据集的均值和方差)在X_train上被fit,它就已经知道了如何将数据标准化。这时,对于测试集X_test,我们只需要使用transform方法,因为我们不希望在测试集上重新计算任何统计信息,也不希望测试集的信息影响到训练过程。如果我们对X_test也使用fit_transform,测试集的信息就可能会影响到训练过程。

总结来说:我们常常是先fit_transform(x_train)然后再transform(x_text)


总结

本文介绍了机器学习的基本概念,sklearn库的基本使用,数据集加载以及一些初步的数据预处理。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐