前言:机器学习作为人工智能的核心,也是使计算机具有智能的根本途径,是一门多领域的交叉学科,需要较好的高等数学功底,接下来我们一步一步揭开机器学习神秘的面纱。

一.课程环境

  • 语言: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
    2
    import numpy as np
    numpy.__version__
  • array初始化示例

    1
    2
    3
    4
    5
    nparr = np.array([i for i in range(10)])
    nparr

    #结果:
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  • arange方法

    1
    2
    3
    4
    np.arange(0,20,2) #与python中的range方法参数一致

    #结果
    array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
  • linspace方法:截取范围内等步长的值

    1
    2
    3
    4
    5
    np.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
    5
    np.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
    7
    np.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
    2
    np.full(shape(行,列),fill_value=值)
    #注意传值分整形与浮点型
  • 若不明白方法怎么使用?

    1
    2
    3
    4
    #在方法后加问号并运行即可,如:
    np.random.normal?
    #或者:
    help(np.random.normal)

数组的基本操作

  • ndim:返回一个数组是几维的

    1
    2
    3
    4
    x = 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
    4
    x = 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
    22
    x = 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
    9
    x = 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
    3
    import numpy as np
    x = np.arange(1,16).reshape((3,5))
    np.abs(x)
  • 正弦、余弦、正切

    1
    2
    3
    np.sin(x)
    np.cos(x)
    np.tan(x)
  • 对x中所有元素取e的x次方

    1
    np.exp(x)
  • 对x中所有元素取n的x次方

    1
    2
    np.power(n,x)
    #等同于n**x
  • 以n为底求对数

    1
    2
    np.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
    2
    L = np.random.random(100)
    np.sum(L)
  • 求数组中最大值与最小值

    1
    2
    np.max(L)
    np.min(L)
  • 矩阵行、列相加

    1
    2
    3
    4
    5
    6
    x = 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
    2
    np.argmin(x)
    np.argmax(x)
  • 乱序处理

    1
    np.random.shuffle(x)
  • 排序处理

    1
    2
    3
    4
    np.sort(x)
    #对于矩阵来说:
    np.sort(x, axis=0) #列上下排序
    np.sort(x, axis=1) #行左右排序(默认)
  • 索引排序

    1
    2
    #展示排序后元素在原来数组的索引
    np.argsort(x)
  • 排序分割

    1
    2
    np.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
    23
    x = 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
    5
    x = np.arange(8)
    x<3
    #结果:
    array([ True, True, True, False, False, False, False, False])
    #同理可以使用其他比较运算符,返回一个bool数组
  • 使用sum或count_nonzero计算bool数组的真值个数

    1
    2
    3
    4
    5
    6
    np.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
    2
    np.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
    2
    import matplotlib as mpl
    import matplotlib.pyplot as plt
  • 绘制横纵坐标图

    1
    2
    3
    4
    x = np.linspace(0,10,100)
    y = np.sin(x)

    plt.plot(x,y) #传入两个数组
  • 绘制多条曲线,并指定颜色,结果图如下

    1
    2
    3
    4
    5
    6
    7
    cosy = 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
    2
    plt.plot(x, cosy, color="red",linestype="--")
    #linestype可传样式如下
  • 改变坐标域

    1
    2
    3
    4
    plt.xlim(-5,15) 		#横坐标取-5到15
    plt.ylim(-0.5,1.5) #纵坐标取-0.5到1.5

    plt.axis([-1,11,-2,2]) #同时调整x,y轴
  • 添加轴名字

    1
    2
    plt.xlabel("横坐标")	
    plt.ylabel("纵坐标")
  • 添加左下角图示

    1
    2
    3
    plt.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
    7
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt

    from sklearn import datasets

    iris = datasets.load_iris() #tab键可以预览datasets.load里有什么数据
  • 打印数据

    1
    2
    iris.keys()	#查看字典的key
    print(iris.DESCR)
  • 绘制三种不同鸢尾花的散点图

    1
    2
    3
    4
    5
    6
    7
    X = 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
    5
    t = 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()