Python3机器学习入门(一)
前言:机器学习作为人工智能的核心,也是使计算机具有智能的根本途径,是一门多领域的交叉学科,需要较好的高等数学功底,接下来我们一步一步揭开机器学习神秘的面纱。
一. 课程环境
-
语言:Python3
-
框架:Scikit-learn
-
其他:numpy,matplotlib …
-
IDE:Jupyter Notebook
总的来说,安装ANACONDA即可
二. 机器学习部分概念
数据
-
数据整体叫
数据集(data set)
-
每一行数据称为一个
样本(sample)
或示例(instance)
-
最后一列称为
标记 label
,每一列表达样本的一个特征(feature)
或属性(attribute)
-
拥有了标记的示例,称为
样例(example)
-
可视化后可以形成一个空间,称为
特征空间(feature space)
或样本空间(sample space)
或输入空间
-
在上述空间中,我们将一个示例称为一个
特征向量
-
分类任务的本质就是在特征空间
切分
学习方法分类
- 监督学习(supervised learning)
- 给机器的训练数据拥有标记或答案
- 代表:
分类(预测的是离散值)
与回归(预测的是连续值)
- 无监督学习(unsupervised learning)
- 给机器的训练数据没有任何标记或答案
- 对没有标记的数据进行分类:
聚类分析
- 意义:对数据进行
降维处理
,特征提取、特征压缩
与异常检测
- 代表:
聚类(clustering)
- 半监督学习
- 一部分数据有标记或答案,另一部分没有
- 增强学习
- 根据周围环境采取行动,根据行动结果学习行动方式
学习方法其他分类
- 批量学习 Batch Learning (离线学习)
- 优点:简单
- 缺点:无法适应环境变化(可以考虑定时重新批量学习,但运算量大)
- 在线学习 Online Learning
- 优点:及时反映新的环境变化
- 缺点:新的数据容易带来不好的变化(需加强对数据的监控)
- 参数学习
- 非参数学习
其他概念
- 学得模型适用于新样本的能力,称为
泛化能力(generalization)
三. 环境配置(Mac系统)
-
安装anaconda(官网下载命令行版本即可)
1
$ bash ~/Downloads/Anaconda3-5.3.1-MacOSX-x86_64.sh //python3版本
-
加入环境变量以生效
1
$ source ~/.bash_profile
-
查看版本
1
$ conda --version
-
配置jupyter环境
1
2
3
4
5
6$ vim ~/.bash_profile
#加入以下字段(anaconda的bin目录路径)
PATH=$PATH:/Users/ming/anaconda3/bin
$ source ~/.bash_profile -
终端输入以下命令配置jupyter默认工作目录
1
2
3$ jupyter notebook --generate-config
$ open /Users/ming/.jupyter/jupyter_notebook_config.py -
Ctrl+F查找notebook_dir关键字,修改工作目录,并将语句前#去掉即可
四. jupyter notebook, numpy基础
jupyter notebook基础
-
运行界面如下
-
常用快捷键 更多快捷键请点击这里
- a 单元格上方插入
- b 单元格下方插入
- m 改变为markdown单元格
-
y 改变为code单元格
- x 删除当前单元格
- Shift-Enter : 运行本单元,选中下个单元
- Ctrl-Enter : 运行本单元
- Alt-Enter : 运行本单元,在其下插入新单元
jupyter notebook魔法命令
-
%run 命令:执行py文件,填写相对路径,例如:
1
%run ../py文件/hello.py
-
%timeit 命令:测试一句代码性能(多次运行,取最快三次平均值),例如:
1
2
3
4%timeit L = [i**2 for i in range(1000)]
#结果
232 µs ± 2.71 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) -
%%timeit 命令:同上,可测试一段代码性能:
1
2
3
4%%timeit
L = []
for n in range(1000):
L.append(n ** 2) -
%time 命令:给出一句代码运行一次所花费的时间
1
2
3
4
5%time L = [i**2 for i in range(10)]
#结果
CPU times: user 9 µs, sys: 0 ns, total: 9 µs
Wall time: 11.9 µs #真实物理世界时间 -
%%time 命令:同上,给出一段代码运行一次所花费的时间
-
%lsmagic :列出所有魔法命令
Numpy.array基础
-
检查运行环境
1
2import numpy as np
numpy.__version__ -
array初始化示例
1
2
3
4
5nparr = np.array([i for i in range(10)])
nparr
#结果:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) -
arange方法
1
2
3
4np.arange(0,20,2) #与python中的range方法参数一致
#结果
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]) -
linspace方法:截取范围内等步长的值
1
2
3
4
5np.linspace(0,20,10)
#结果:
array([ 0. , 2.22222222, 4.44444444, 6.66666667, 8.88888889,
11.11111111, 13.33333333, 15.55555556, 17.77777778, 20. ]) -
random方法:随机数
1
2
3
4
5np.random.randint(0,10) #生成一个0到10(不包括10)的随机数
np.random.randint(0,10,size =10) #生成包含size个随机数的数组
np.random.randint(0,10,size =(3,6)) #生成3行6列随机元素的矩阵
np.random.random(10) #生成10个随机浮点数
np.random.normal(10,100,size = 10) #指定均值为10,标准差为100的随机浮点数 数组 -
seed方法:随机种子
1
np.random.seed(666)
-
检查存储数组类型
1
数组名.dtype
-
创建全0矩阵
1
2
3
4
5
6
7np.zeros((3,5)) #三行五列为例
#np.zeros(shape=(3,5))
#结果
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]) -
创建全1矩阵
1
np.ones((3,5))
-
创建全值自定义矩阵
1
2np.full(shape(行,列),fill_value=值)
#注意传值分整形与浮点型 -
若不明白方法怎么使用?
1
2
3
4#在方法后加问号并运行即可,如:
np.random.normal?
#或者:
help(np.random.normal)
数组的基本操作
-
ndim:返回一个数组是几维的
1
2
3
4x = np.arange(10)
x.ndim
#结果
1 -
shape:返回一个数组几行几列
-
size:返回一个数组的元素个数
-
访问数组元素示例
1
2
3
4
5
6
7
8
9
10
11#x[0][0]
#x[(0,1)]
#建议用以下访问方法
x[0,0]
#访问二维数组前两行前三列
x[:2, :3]
#访问二维数组前两行,间隔为2
x[:2,::2]
#注意:numpy中修改了切片中的元素,原数组的元素也会被修改,除非使用copy函数
subX = x[:2, :3].copy() -
一维数组转换为二维数组
1
2
3
4x = np.arange(10) #一维数组
A = x.reshape(2,5) #二行五列
A = x.reshape(10,-1) #十行
A = x.reshape(-1,10) #十列
数组的合并与分割
合并
-
concatenate :数组/向量的合并,只能处理同维度数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22x = np.array([1,2,3])
y = np.array([3,2,1])
np.concatenate([x,y])
#结果
array([1, 2, 3, 3, 2, 1])
#二维数组不同维度的拼接,默认axis=0
A = np.array([[1,2,3],
[4,5,6]])
np.concatenate([A,A], axis=0)
#结果
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6]])
np.concatenate([A,A], axis=1)
#结果
array([[1, 2, 3, 1, 2, 3],
[4, 5, 6, 4, 5, 6]]) -
vstack : 垂直方向(上下)拼接两个不同维度的数组
-
hstack : 水平方向(左右)拼接两个不同维度的数组
分割
-
split 方法:数据分割
1
2
3
4
5
6
7
8
9x = np.arange(10)
#传入要切割的数组,分割点
x1,x2,x3 = np.split(x,[3,7])
#结果
x1 = array([0, 1, 2])
x2 = array([3, 4, 5, 6])
x3 = array([7, 8, 9])
#二维数组的切割同理,可传入axis参数,0为上下分割(默认),1为左右分割 -
vsplit:上下分割
-
hsplit:左右分割
矩阵运算
-
加减乘除 (对应元素,乘除非矩阵运算规则)
-
幂运算(**)
-
求绝对值
1
2
3import numpy as np
x = np.arange(1,16).reshape((3,5))
np.abs(x) -
正弦、余弦、正切
1
2
3np.sin(x)
np.cos(x)
np.tan(x) -
对x中所有元素取e的x次方
1
np.exp(x)
-
对x中所有元素取n的x次方
1
2np.power(n,x)
#等同于n**x -
以n为底求对数
1
2np.logn(x)
#例如 np.log2(x) -
矩阵乘法
1
2#A与B矩阵相乘
A.dot(B) -
矩阵转置
1
A.T
-
矩阵的逆
1
np.linalg.inv(A)
-
伪逆矩阵
1
np.linalg.pinv(A)
向量与矩阵运算
-
向量堆叠为矩阵,再与矩阵运算
1
2
3
4
5
6
7
8
9
10
11
12#传入参数分别为向量,元组(行、列需要堆叠的次数),例如:
v = np.array([1,2])
np.tile(v,(2,1))
np.tile(v,(1,2))
#结果
array([[1, 2],
[1, 2]])
array([[1, 2, 1, 2]])
聚合操作
-
数组的聚合(加法)
1
2L = np.random.random(100)
np.sum(L) -
求数组中最大值与最小值
1
2np.max(L)
np.min(L) -
矩阵行、列相加
1
2
3
4
5
6x = np.arange(16).reshape(4,-1)
np.sum(x, axis=0) #行上下相加
np.sum(x, axis=1) #列左右相加
#结果
array([24, 28, 32, 36])
array([ 6, 22, 38, 54]) -
所有元素乘积
1
np.prod(x)
-
求平均值
1
np.mean(x)
-
求中位数
1
np.median(x)
-
求百分位点
1
np.percentile(x,q=?)
-
求方差
1
np.var(x)
-
求标准差
1
np.std(x)
索引 arg运算
-
求最小值、最大值所在的索引
1
2np.argmin(x)
np.argmax(x) -
乱序处理
1
np.random.shuffle(x)
-
排序处理
1
2
3
4np.sort(x)
#对于矩阵来说:
np.sort(x, axis=0) #列上下排序
np.sort(x, axis=1) #行左右排序(默认) -
索引排序
1
2#展示排序后元素在原来数组的索引
np.argsort(x) -
排序分割
1
2np.partition(x,3) #3前面比3小,3后面比3大
np.argpartition(x,3) #索引值排序,以上类推 -
对于二维数组,以上方法均可以传入axis参数
Fancy Indexing与array比较
-
根据多个索引获得新的数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23x = np.arange(16)
ind = [3, 5, 8] #也可以传二维数组
x[ind]
#结果
array([3, 5, 8])
#已知有以下数组x
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
row = np.array([0,1,2])
col = np.array([1,2,3])
x[row,col]
#结果:
array([ 1, 6, 11]) #分别代表(0,1)(1,2)(2,3)的值
col = [True, False, True, True] #代表要取0,2,3列
x[1:3, col]
#结果:
array([[ 4, 6, 7],
[ 8, 10, 11]]) -
numpy.array的比较
1
2
3
4
5x = np.arange(8)
x<3
#结果:
array([ True, True, True, False, False, False, False, False])
#同理可以使用其他比较运算符,返回一个bool数组 -
使用sum或count_nonzero计算bool数组的真值个数
1
2
3
4
5
6np.sum(x<3)
np.sum((x>3)&(x<7)) #注意是位运算(与运算)
np.sum((x<4)|(x>7)) #或运算
np.sum(~(x==0)) #非运算
np.count_nonzero(x<3) -
使用any检测数组元素的值(一个元素满足则True)
1
2np.any(x==0)
#若x数组中含有元素0,则返回True,否则返回False,以此类推 -
使用all检测数组元素的值(所有元素满足则True)
1
np.all(x>0)
-
对于二维数组,以上方法均可以传入axis参数
-
获得满足条件的子数组
1
2
3
4#提取x中小于5的元素
x[x<5]
#提取x中最后一列元素能被3整除的行
x[x[:,3] % 3 == 0, :]
matplotlib数据可视化基础
绘制折线图
-
导入包
1
2import matplotlib as mpl
import matplotlib.pyplot as plt -
绘制横纵坐标图
1
2
3
4x = np.linspace(0,10,100)
y = np.sin(x)
plt.plot(x,y) #传入两个数组 -
绘制多条曲线,并指定颜色,结果图如下
1
2
3
4
5
6
7cosy = np.cos(x)
siny = y.copy()
plt.plot(x, siny)
plt.plot(x, cosy, color="red")
#颜色参数可传:blue(默认)/green/red/cyan/magenta/yellow/black/white,还可以传具体颜色代码
plt.show() -
线条类型
1
2plt.plot(x, cosy, color="red",linestype="--")
#linestype可传样式如下 -
改变坐标域
1
2
3
4plt.xlim(-5,15) #横坐标取-5到15
plt.ylim(-0.5,1.5) #纵坐标取-0.5到1.5
plt.axis([-1,11,-2,2]) #同时调整x,y轴 -
添加轴名字
1
2plt.xlabel("横坐标")
plt.ylabel("纵坐标") -
添加左下角图示
1
2
3plt.plot(x, siny,label="这是sinx")
plt.plot(x, cosy, color="red",linestyle="-.",label="这是cosx")
plt.legend() -
添加图标题
1
plt.title("welcome to machine learning")
绘制散点图
-
scatter方法,其他大部分参数与plot方法一致
1
plt.scatter(x, siny)
-
调整透明度
1
plt.scatter(x, siny, alpha=0.5) #透明度调整至0.5
读取数据和简单的数据探索
-
读取数据(以官方库的鸢尾花数据为例)
1
2
3
4
5
6
7import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn import datasets
iris = datasets.load_iris() #tab键可以预览datasets.load里有什么数据 -
打印数据
1
2iris.keys() #查看字典的key
print(iris.DESCR) -
绘制三种不同鸢尾花的散点图
1
2
3
4
5
6
7X = iris.data[:,:2] #获得所有行,前两列数据
y = iris.target
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")
plt.show() -
从另一个维度看看
1
2
3
4
5t = iris.data[:,2:] #取所有行,后两列数据
plt.scatter(t[y==0,0],t[y==0,1],color="red",marker="o")
plt.scatter(t[y==1,0],t[y==1,1],color="blue",marker="+")
plt.scatter(t[y==2,0],t[y==2,1],color="green",marker="x")
plt.show()