本文中的公式使用公式编辑器编辑
matplotlib官网
sklearn的各种数据集api
了解基础
机器学习中的数据通常用二维的表格来表示,横轴表示特征分类feature,每一行就是一个样本数据sample,代表一个特征向量
X
(
i
)
X^{(i)}
X(i) ,通常最后一列表示数据的lable,将整体的数据称为data set
第i个样本表示为
X
(
i
)
X^{(i)}
X(i),第i个样本的第j个特征表示为
X
j
(
i
)
X^{(i)} _{j}
Xj(i) ,第i个样本的标记为
y
(
i
)
y^{(i)}
y(i) ,在数学公式中通常用大写字母表示矩阵,小写字母表示向量.
行向量通常指1Xn的向量,列向量为nX1的向量,即行列。在数学上通常将向量表示为列向量,因此整个数据的矩阵可以写成
(
(
X
(
1
)
)
T
(
X
(
2
)
)
T
(
X
(
3
)
)
T
.
.
.
)
\begin{pmatrix} \\(X^{(1)})^{T} \\(X^{(2)})^{T} \\(X^{(3)})^{T} \\... \end{pmatrix}
⎝
⎛(X(1))T(X(2))T(X(3))T...⎠
⎞
以上都是约定俗成的。
在坐标轴中,2个特征可以确定一个点,3个特征就是三维空间,以此类推,该控件称为feature space。分类任务的本质就是在特征空间的划分。切分可能是用曲线切分的
特征也可以是很抽象的,如在图像识别领域,每一个像素点,都是一个特征对于28X28像素的图像,就有784个特征,通过每个像素的灰度值来表示图像。在机器学习中,特征可能是没有语义,特别抽象的,可能是和最终要完成的任务毫无关系的,例如第100个像素点,和最终的结果是否有必然的联系。这就要借助电脑强大的运算能力,找到点和最终结果之间的联系。在数据清理阶段,甚至需要特征工程学科,来筛选特征。
机器学习主要关注的是分类任务和回归任务
标出了具体的分类就是监督学习,对没有标记的数据进行聚类分析,就是非监督学习,之外还有半监督学习和增强学习
numpy等库的使用
jupyter notebook
安装好后,可以通过jupyter notebook
来启动。
- help-keyboard shortcuts ,查看快捷键
- %run myscript.py 魔法命令,运行自定义的py文件,下面的格子也可以调用py文件中的变量、函数
- 可以
from . import mymodule
来导入自定义的模块 %timeit
可以计算一行代码的运行时间%%timeit
,统计单元格内整体的代码运行时间%time
只统计一次,结果要更详细一些,%%time
同理%lsmagic
查看其它魔法命令- 查看命令对应的文档,在后面加?(推荐),如
%run?
、np.random.normal?
这是在下面出现弹出框的。如果想在out中输出,就用help(np.random.normal)
numpy矩阵操作
numpy.array
多维数组,python中的list是不限制其中元素的类型(优点灵活、缺点效率低),python中有限制类型的数组,import array
(但没提供矩阵的相关运算),np限制,可以通过dtype属性查看np中元素的类型np.zeros((3,5),dtype=int)
,创建3行5列数组,或传入参数用shape=(3,5)
np.ones()
np.full(shape=(3,5),fill_value=666)
np.arange(0, 1, 0.2)
步长可以传入浮点数,range不可以np.linspace(0, 1, 5)
在0,1范围内切出5个数包括1,5np.random.randint(0, 10, size=(3,5))
前闭后开区间,定义随机种子np.random.seed(666)
np.random.normal(0, 1, (3, 5))
生成均值为0标准差为1的随机浮点数X = np.arange(15).reshape((3, 5))
,numpy.array
的基本属性有ndim、shape、shape,reshape可通过X?
查看- 取得多维数组中的元素,不建议用
X[0][0]
,建议使用X[0, 0]
或X[(0, 0)]
,这是np特殊的方式,X[:2, :3]
(取前2行,前3列)与X[:2][:3]
结果是不同的,因为后者是取X[:2]
的前3个元素。所以只要是多维度的,就要用逗号符 - 支持切片访问,第3个参数为步长,这里引出了快速颠倒数组的方法,只需设置步长为-1,
x[::-1]
- 对于list切片赋值是创建了全新的list,对于np则是直接在原矩阵中修改,因为np优先考虑效率,要是想修改不影响原矩阵,就要调用
.copy()
- 需要注意的是与切片不同,reshape不会改变原矩阵或列表的ndim,要想存储,就需要赋值
A = x.reshape(1, 10)
,array转为1行10列的2维矩阵 x.reshape(10, -1)
,生成10行,列数自动的矩阵
- 取得多维数组中的元素,不建议用
np.concatenate([A, A], axis=1)
,矩阵沿着第2个维度,即列的方向拼接。只能处理相同维度数的拼接np.vstack([A, z])
, 维度不同,也可以在竖直方向拼接,但如果在拼接方向上的量不同,也是不可以的x1, x2, x3 = np.split(x, [3, 7])
分割;对于矩阵,可以指定维度分割A1, A2 = np.split(A, [2], axis=1)
;同理也有在垂直方向上分割upper, lower = np.vsplit(A, [2])
- 分割常用于切分特征值与标签,切分的标签常用y来表示,会是
array([[ 3], [ 7], [11], [15]])
这时就可以用y[:, 0]
将其转换为1维的列表
- 分割常用于切分特征值与标签,切分的标签常用y来表示,会是
numpy矩阵的运算
前置知识:
1X2的矩阵与2X2的矩阵相乘,结果是1X2的矩阵
原矩阵与逆矩阵相乘是单位矩阵,对角线都为1,其它值为0,逆矩阵乘原矩阵也是单位矩阵,只有方阵才能求逆矩阵
np也支持列表推导式np.array(2*e for e in L)
- py原生的list2是把list拼接,np中是对应项2,且速度比np应用列表推导式还要快,这就是np把数组当作矩阵或者说是向量来运算,称为NumPy’s UFuncs (Universal Functions),几乎支持所有的数学运算。
np.exp(x)
,求每一项的 e x e^{x} ex ,np.power(3,x)
为 3 x 3^{x} 3x等同于3**x,np.log(x)
求自然对数,np.log2(x)
求2为底的对数 A*B
,矩阵之间的对应项相乘,在np中,所有的运算符运算都是都是对相应位置元素运算。A.dot(B)
,矩阵乘法,A矩阵的每一行和B矩阵的每一列相乘再相加,如果是向量与矩阵相乘,np可以自动判断用行向量还是列向量A.T
np.vstack([v] * A.shape[0])
把列表落成和矩阵相同的行数,便于做运算np.tile(v, (2, 1))
v是向量,表示在行上堆叠2行,列上堆叠一次np.linalg.inv(A)
Linear algebra inverse矩阵的逆。与原矩阵相乘后,除了对角线为1,其它部分可能是无限接近0的,是由浮点误差造成的np.linalg.pinv(X)
伪矩阵的逆 p 为Pseudo
numpy的聚合运算
axis参数意为沿着轴运算,0代表第一个维度,行的维度。另一种理解方式是,参数是什么代表把对应的维度压缩,传0代表把0压缩
- 对应的索引值位置可以用
np.argmin(x)
np.sum(L)
比原生的sum(L)
效率要高很多,np也提供了面向对象的方式如L.sum()
,相对的说np方法更能显示的说明用np中的方法,且运算方式更全- np.sum默认求所有和,如果想求某一维度的,需要指明axis参数
np.prod(L)
所有元素的乘积np.mean(L)
平均值np.median(L)
中位数np.percentile(big_array, q=50)
百分位数,q为50等同于中位数,100就是最大值np.max(big_array)
for percent in [0, 25, 50, 75, 100]:
print(np.percentile(big_array, q=percent))
np.var(big_array)
方差 variancenp.std(big_array)
标准差 standard deviationnp.random.shuffle(x)
对数组乱序处理,改变原数组np.random.permutation(len(X))
返回数组X的乱序后的索引np.sort(x)
没有改变向量x本身x.sort()
,改变x为排好序的数组- 如果是对矩阵排序
np.sort(X, axis=0)
沿着行的方向排序 np.argsort(x)
返回从大到小排序元素的索引
np.argpartition(x, 3)
3前面的比3小,3后面的比3大,但前后都不是有序的,便于只想找到比某些值小或大的元素np.argpartition(x, 3)
np.argpartition(X, 2, axis=1)
np的Fancy Indexing
x[[3, 5, 7]]
找到数组x对应的索引值- 得到对应位置值的矩阵,支持切片,布尔值
- 例如对于数组x,
x<3
,返回的就是布尔数组 np.sum(x <= 3)
False转换为了0,可用于统计个数np.count_nonzero( x <= 3)
统计传进的数组有多少个不为0的np.any(x == 0)
数组中是否有0元素,有任何为True,结果就为Truenp.all(x >= 0)
所有都为True才返回Truenp.sum(X % 2 == 0, axis=0)
支持矩阵统计np.sum((x > 3) & (x < 10))
此处用位运算符,而不是条件运算符,因为条件运算符连接的是2个条件,分别是2个布尔值,但此时,左右分别是2个数组,希望2个数组按照索引,分别做与或运算,得到的结果依然是数组,所以用位运算符,而不能用条件运算符&&
np.sum((x % 2 == 0) | (x > 10))
np.sum(~(x == 0))
非运算
- 例如对于数组x,
ind = np.array([[0, 2], [1, 3]])
x[ind]
row = np.array([0, 1, 2])
col = np.array([1, 2, 3])
X[row, col]
col = [True, False, True, True]
X[1:3, col]
x[x < 5]
查找小于5的数据X[X[:,3] % 3 == 0, :]
矩阵X的索引是3的列能被3整除的所有行的值
数据可视化
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.plot(x, y)
plt.show()
mpl是高级功能,通常plt就足够用了
想绘制2个图形在一张图上,就可以
plt.plot(x, siny, label="sin(x)")
plt.plot(x, cosy, color = 'red', linestyle="--", label="cos(x)")
plt.xlim(-5, 15)
plt.ylim(0, 1)
# 也可以同时调整,前2个是x轴范围,后面是y轴范围
plt.axis([-1, 11, -2, 2])
plt.xlabel("x axis")
plt.ylabel("y value")
plt.legend() # 根据label添加图示
plt.title("标题")
再show就可以了,line2d的样式可以查看官网
plt.scatter
绘制散点图用
对于折线图,通常横轴是特征,纵轴是取值
散点图的横纵轴都是特征,通常表现二维数据,颜色是label
x = np.random.normal(0, 1, 10000)
y = np.random.normal(0, 1, 10000)
plt.scatter(x, y, alpha=0.1)
加载sklearn数据集
sklearn的数据集是一种类字典对象,通过.keys()
查看数据集中包含的内容,见网址
# Fancy Indexing形式加载并绘制散点图
plt.scatter(X[y==0,0], X[y==0,1], color="red", marker="o")
plt.scatter(X[y==1,0], X[y==1,1], color="blue", marker="+")
plt.scatter(X[y==2,0], X[y==2,1], color="green", marker="x")