写作前言:
1.本文章的写作顺序和Chris Albon[美]《Python机器学习手册-从数据预处理到深度学习》(Machine Learning with Python Cookbook)相似。但是我会添加自己的想法和总结,并简化内容。如有侵权,请及时联系我删除文章。至此,由衷感谢该书提供指导。
2.文章篇幅比较大,文章分为以下章节:
-- 1. 向量、矩阵和数组
-- 2. 加载数据
-- 3. 数据整理
-- 4. 处理数值型数据
-- 5. 处理分类数据
-- 6. 处理文本
-- 7. 处理日期和时间
-- 8. 图像处理
-- 9. 使用特征提取进行特征降维
-- 10. 使用特征选择进行降维
-- 11. 模型评估
-- 12. 模型选择
-- 13. 线性回归
-- 14. 树和森林
-- 15. KNN
-- 16. 逻辑回归
-- 17. 支持向量机
-- 18. 朴素贝叶斯
-- 19. 聚类
-- 20. 神经网络
3.文章归纳了在机器学习中所常遇见的方法,只上应用实例。如果想要查询方法的参数以及更多的使用方法,请读者前往官方查询。
4.基于笔者能力有限以及写作文章篇幅过大,写作未免有疏漏错误,还请读者大胆提出来,笔者愿意接受读者的批评指正。
5.所有代码的运行环境基于所需模块的版本详细:
- python 3.8.8
- numpy 1.22.4
- scikit-learn 1.2.2
- pandas 1.3.5
- matplotlib 3.3.4
目录
在机器学习中,矩阵和向量可谓是我们最为经常接触的数据结构了。
Numpy是Python的第三方模块,支持对矩阵的操作和运算并提供了许多数学运算模块。
在机器学习中,Numpy并不是占据主导地位,但是我们仍需要掌握Numpy的基础,以便后续对矩阵的操作。
1.创建向量和矩阵
01 | 自由创建向量/矩阵 | np.array()方法 |
02 | 指定范围创建向量/矩阵 | np.arange()方法 |
03 | 创建全零向量/矩阵 | np.zeros()方法 |
04 | 创建全一向量/矩阵 | np.ones()方法 |
import numpy as np
""" 创建行向量 """
rowVector = np.array([1,2,3])
""" 创建列向量 """
columnVector = np.array([[1],
[2],
[3]])
""" 创建3*3矩阵,方法一 """
matrix1 = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
""" 创建3*3矩阵,方法二 """
matrix2 = np.arange(1,10,1).reshape(3,3)
print(matrix2)
# >>>
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
# 拓展:
import numpy as np
""" 创建全一矩阵 """
matrix3 = np.ones([3,3])
print(matrix3)
# >>>
"""
[[1 1 1]
[1 1 1]
[1 1 1]]
"""
""" 创建全零矩阵 """
matrix4 = np.zeros([3,3])
print(matrix4)
# >>>
"""
[[0 0 0]
[0 0 0]
[0 0 0]]
"""
2.矩阵数据的增删改查
01 | 矩阵增加操作 | np.concatenate()方法 | ||||||
02 | 矩阵删除操作 | 切片赋值法 | ||||||
03 | 矩阵修改操作 | 指定索引法 | ||||||
04 | 矩阵查询操作 |
|
2.1 增加操作
import numpy as np
""" 向矩阵右边添加一组行向量 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
# 设置想要链接的列向量
newColumn = np.array([[10],[11],[12]])
# 指定连接矩阵和轴
newMatrix = np.concatenate((matrix,newColumn),axis = 1)
print(newMatrix)
# >>>
"""
[[ 1 2 3 10]
[ 4 5 6 11]
[ 7 8 9 12]]
"""
2.2 删除操作
import numpy as np
""" 删除最右边的列向量 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
# 采取切片赋值的方法实现删除数据
newMatrix = matrix[:,:-1]
print(newMatrix)
# >>>
"""
[[1 2]
[4 5]
[7 8]]
"""
2.3 修改操作
import numpy as np
""" 修改第1行第1列的值 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
# 采取指定索引的方法实现修改数据
matrix[0,0] = 6
print(matrix)
# >>>
"""
[[6 2 3]
[4 5 6]
[7 8 9]]
"""
2.4 查询操作
import numpy as np
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
""" 查询最大值 """
print(np.max(matrix))
# >>>
"""
9
"""
""" 查询最小值 """
print(np.min(matrix))
# >>>
"""
1
"""
""" 找到每一列最大的元素 """
print(np.max(matrix,axis=0))
# >>>
"""
[7 8 9]
"""
""" 找到每一行最大的元素 """
print(np.max(matrix,axis=1))
# >>>
"""
[3 6 9]
"""
""" 查看第一行第一列的值 """
print(matrix[0,0])
# >>>
"""
1
"""
3.展示矩阵的属性
01 | 查询矩阵形状 | shape属性 |
02 | 查询矩阵元素数量 | size属性 |
03 | 查询矩阵维数 | ndim属性 |
04 | 查询矩阵的秩 | np.linalg.matrix_rank()方法 |
05 | 查询矩阵的秩 | trace()方法 |
3.1 矩阵的形状
import numpy as np
""" 查看矩阵的形状 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
print(matrix.shape)
# >>>
"""
(3,3)
"""
3.2 矩阵的元素数量
import numpy as np
""" 查看矩阵的元素数量 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
print(matrix.size)
# >>>
"""
9
"""
3.3 矩阵的维数
import numpy as np
""" 查看矩阵的维数 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
print(matrix.ndim)
# >>>
"""
2
"""
3.4 矩阵的秩
import numpy as np
""" 查看矩阵的秩 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
print(np.linalg.matrix_rank(matrix))
# >>>
"""
2
"""
3.5 矩阵的迹
import numpy as np
""" 查看矩阵的迹 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
print(matrix.trace())
# >>>
"""
15
"""
4.矩阵数学运算
01 | 计算矩阵平均值 | np.mean()方法 |
02 | 计算矩阵中位数 | np.median()方法 |
03 | 计算矩阵标准差 | np.std()方法 |
4.1 计算平均值
import numpy as np
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
""" 计算矩阵的平均值 """
print(np.mean(matrix))
# >>>
"""
5.0
"""
""" 计算矩阵每一列的平均值 """
print(np.mean(matrix,axis=0))
# >>>
"""
[4. 5. 6.]
"""
4.2 计算中位数
import numpy as np
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
""" 计算矩阵的中位数 """
print(np.median(matrix))
# >>>
"""
5.0
"""
""" 计算矩阵每一行的中位数 """
print(np.median(matrix,axis=1))
"""
[2. 5. 8.]
"""
4.3 计算标准差
import numpy as np
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
""" 计算矩阵的标准差 """
print(np.std(matrix))
# >>>
"""
2.581988897471611
"""
""" 计算矩阵每一行的标准差 """
print(np.std(matrix,axis=1))
# >>>
"""
[0.81649658 0.81649658 0.81649658]
"""
5.矩阵线性代数运算
01 | 转置矩阵 | T属性 |
02 | 计算行列式 | np.linalg.det()方法 |
03 | 矩阵相加 | '+'运算 / np.add()方法 |
04 | 矩阵相减 | '-'运算 / np.subtract()方法 |
05 | 矩阵的乘法运算 | '@'运算 np.dot()方法 |
06 | 向量的内积 | '@'运算 np.dot()方法 |
07 | 向量的点积 | '@'运算 np.dot()方法 |
08 | 向量的外积 | np.outer()方法 |
09 | 计算矩阵的逆 | np.linalg.inv()方法 |
10 | 计算特征值和特征向量 | np.linalg.eig()方法 |
5.1 转置矩阵
import numpy as np
""" 转置矩阵 """
# 创建数值从1到9的3*3矩阵
matrix = np.arange(1,10,1).reshape(3,3)
print(matrix.T)
# >>>
"""
[[1 4 7]
[2 5 8]
[3 6 9]]
"""
注意的是:在线性代数范围内严格的说:一个向量是不能被转置的,因为它只是值的集合。当我们需要将行向量转换为列向量的时候,需要添加两对中括号,来表示它是一个二维数组。
import numpy as np
""" 将行向量转置为列向量 """
# 创建数值从1到5的二维矩阵(一行五列)
matrix = np.arange(1,6).reshape(1,-1)
print(matrix.T)
# >>>
"""
[[1]
[2]
[3]
[4]
[5]]
"""
5.2 计算行列式
import numpy as np
""" 计算行列式 """
# 自由创建一个矩阵
matrix = np.array([[1,4,8],
[5,6,7],
[1,6,5]])
print(np.linalg.det(matrix))
# >>>
"""
108.00000000000003
"""
5.3 矩阵相加
import numpy as np
""" 矩阵相加 """
# 自由创建一个矩阵
matrix1 = np.array([[1,4,8],
[5,6,7],
[1,6,5]])
matrix2 = np.array([[1,2,4],
[2,3,4],
[5,6,1]])
# 方法一
matrix = matrix1 + matrix2
print(matrix)
# >>>
"""
[[ 2 6 12]
[ 7 9 11]
[ 6 12 6]]
"""
# 方法二
matrix = np.add(matrix1,matrix2)
print(matrix)
# >>>
"""
[[ 2 6 12]
[ 7 9 11]
[ 6 12 6]]
"""
5.4 矩阵相减
import numpy as np
""" 矩阵相减 """
# 自由创建一个矩阵
matrix1 = np.array([[1,4,8],
[5,6,7],
[1,6,5]])
matrix2 = np.array([[1,2,4],
[2,3,4],
[5,6,1]])
# 方法一
matrix = matrix1 - matrix2
print(matrix)
# >>>
"""
[[ 0 2 4]
[ 3 3 3]
[-4 0 4]]
"""
# 方法二
matrix = np.subtract(matrix1,matrix2)
print(matrix)
# >>>
"""
[[ 0 2 4]
[ 3 3 3]
[-4 0 4]]
"""
5.5 矩阵的乘法运算
import numpy as np
""" 矩阵的乘法运算 """
# 自由创建一个矩阵
matrix1 = np.array([[1,1],
[1,2]])
matrix2 = np.array([[1,3],
[1,2]])
# 方法一(Python.__version__ > 3.5)
matrix = matrix1 @ matrix2
print(matrix)
# >>>
"""
[[2 5]
[3 7]]
"""
# 方法二
matrix = np.dot(matrix1,matrix2)
print(matrix)
# >>>
"""
[[2 5]
[3 7]]
"""
注意的是:“matrix1 * matrix2”是矩阵对应元素相乘,请注意区分。
5.6 向量的内积
向量的内积的运算过程和矩阵的乘法运算过程是一样的。
向量的内积可以近似理解为特殊矩阵的乘法运算。
因此计算向量的内积方法和上述计算矩阵的乘法是一样的
import numpy as np
""" 向量的内积 """
# 自由创建一个行向量
matrix1 = np.array([1,2,3])
# 自由创建一个列向量
matrix2 = np.array([[1,2,3]]).T
# 方法一(Python.__version__ > 3.5)
matrix = matrix1 @ matrix2
print(matrix)
# >>>
"""
[14]
"""
# 方法二
matrix = np.dot(matrix1,matrix2)
print(matrix)
# >>>
"""
[14]
"""
5.7 向量的点积
点积和上述的内积在概念上是相似的,都用于衡量向量之间的相似度或关系。
点积常用于向量的几何性质和相似度计算,
而内积更常用于线性代数中的向量空间和矩阵运算。
因此计算向量的点积方法和上述计算向量的内积仍然是一样的。
import numpy as np
""" 向量的点积 """
# 自由创建一个向量
matrix1 = np.array([1,2,3])
matrix2 = np.array([1,2,3])
# 方法一(Python.__version__ > 3.5)
matrix = matrix1 @ matrix2
print(matrix)
# >>>
"""
14
"""
# 方法二
matrix = np.dot(matrix1,matrix2)
print(matrix)
# >>>
"""
14
"""
5.8 向量的外积
import numpy as np
""" 向量的外积 """
# 自由创建一个向量
matrix1 = np.array([[1,2,3]]).T
matrix2 = np.array([1,2,3])
# 计算向量的外积
matrix = np.outer(matrix1,matrix2)
print(matrix)
# >>>
"""
[[1 2 3]
[2 4 6]
[3 6 9]]
"""
5.9 计算矩阵的逆
import numpy as np
""" 计算矩阵的逆 """
# 自由创建一个矩阵
matrix = np.array([[1,4],
[2,5]])
print(np.linalg.inv(matrix))
# >>>
"""
[[-1.66666667 1.33333333]
[ 0.66666667 -0.33333333]]
"""
5.10 计算特征值和特征向量
import numpy as np
""" 计算矩阵的特征值和特征向量 """
# 自由创建一个矩阵
matrix = np.array([[1,-1,3],
[1,1,6],
[3,8,9]])
# 计算特征值和特征向量 => 用两个变量分别接受特征值和特征向量
eigenValues,eigenVectors = np.linalg.eig(matrix)
# 查看特征值
print(eigenValues)
# >>>
"""
[13.55075847 0.74003145 -3.29078992]
"""
# 查看特征向量
print(eigenVectors)
# >>>
"""
[[-0.17622017 -0.96677403 -0.53373322]
[-0.435951 0.2053623 -0.64324848]
[-0.88254925 0.15223105 0.54896288]]
"""
6.拓展资料
在开始学习Numpy的时候,轴是非常重要的,因为很多的数组的操作都需要用到轴。然而我刚开始学的时候,就一脸懵圈。因为轴这个东西也很抽象,我们需要画图去加深理解。
6.1 二维数组的轴
在二维数组中,每一个数组有行有列。可以将列方向看为axis=0,而行方向看为axis=1。比如第m行的数据可以看作为:在列方向的索引为m的数据。如下图的obj[2]=[3,4,5,6,7,8]。以前我常遇到将axis=0看作是行的,因为平时说”第几行第几列“习惯了,前期就误以为axis=0是行方向,axis=1是列方向。我们注意的是,轴是一个有方向有大小的矢量,而我们平时说的”第几行第几列“是一个标量,只有大小,没有方向。因此就陷入了这种思维误区。
假设某一条数据的位置是[m,n]。即可看作为:在列方向的索引为m;在行方向的索引为n。例如在下图中,obj[2,3]=6。
在使用reshape(m,n)方法中,可以理解为:将列方向的大小调整为m;在行方向的大小调整为n。
在使用std(obj,axis=1)方法中,可以理解为:标准化每一行数据。