简介
老师信息
老师:吴法春
学校:山大(10年毕业)
工作:
TCL c语言 单片机 2.5年 深圳
→ \to → vetch C++开发 ARM平台 3年
→ \to → 青岛 山科智汇 java平台端 Android 3年
→ \to → 东软 java方向 python人工智能
学习安排
前置基础:python基础,python数据处理和可视化基础
五天
第一阶段 (2天)
机器学习,深度学习,框架(tensorflow/pytorch)
第二阶段 (2-2.5天)
项目实训(分组 3-4人)
第三阶段 (0.5-1天)
答辩(ppt,代码演示,15分钟左右)介绍,项目演示,代码演示
成绩
平时成绩30%(考勤为主,有事请假)
项目成绩70%(项目内容为主,答辩为辅,不能来要提前说)
上课时间
上午:8-12点
下午:13-17点
上课方式
每节课都录屏发群里
课件发群里
笔记发群里
环境搭建也发群里
项目
分类任务(数据任选,模型任选)
回归任务(任选)
模式识别(数据任选)
其他项目
要求:
数据、算法、模型、训练(不能直接拿网上的结果)、效果(指标,可视化)
答辩:
PPT(团队介绍、项目介绍、项目说明、效果展示)
成果物(数据、源码、或者其他)
实训模板(没有要求,吉大的或者网上的)
提交:
以上三个,答辩完成以后,以小组为单位打包提交即可。
框架
以前:tensorflow
现在:pytorch
没讲,看发的资料
环境搭建
建议在自己电脑上搭建环境
环境:anaconda + pycharm
按照老师的给的文档安装
anaconda
带各种包:数据分析、机器学习等等的环境
pycharm
编辑器,社区版免费,破解版没必要(费劲)
机器学习
主演教四个算法演示机器学习的流程
1、概述
AI :
1956年第一次提出AI的概念。算力等等限制,受到打击
实现核心 :
机器学习
→ \to → 神经网络 ∈ \in ∈ 机器学习
→ \to → 深度学习 ∈ \in ∈ 神经网络,RNN、CNN
数据 :
清洗,筛选
整理结果:数据矩阵的样子
算法 :
参数
模型 :
输入新数据,推测结果
数据 → 输入 \xrightarrow{输入} 输入 算法 → 新数据 \xrightarrow{新数据} 新数据 模型 → 推测 \xrightarrow{推测} 推测 结果
算法重要还是数据重要?
曲线图(纵轴效果,横轴数据、算法)
分类、回归 :
回归:预测具体数值
分类:预测属于哪一类(KNN算法:判断病人的肿瘤属于良性还是恶性的)
1、KNN算法
1.1、简介
优点 :
思想极度简单
应用数学知识少(近乎为零)
效果好(缺点?)
可以解释机器学习算法使用过程中的很多细节问题
更完整的刻画机器学习应用的流程
原理案例介绍
假设现在设计一个程序判断一个新的肿瘤病人是良性肿瘤还是恶性肿瘤。
先基于原有的肿瘤病人的发现时间和肿瘤大小(特征)对应的良性/恶性(值)建立了一张散点图,横坐标是肿瘤大小,纵坐标是发现时间,红色代表良性,蓝色代表恶性,现在要预测的病人的颜色为绿色。
首先需要取一个k值(这个k值的取法后面会介绍),然后找到距离要预测的病人的点(绿点)距离最近的k个点。
然后用第一步中取到的三个点进行投票,比如本例中投票结果就是蓝:红 = 3:0 ,3>0,所以判断这个新病人幻的事恶性肿瘤。
本质 :如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
1.2、简单实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import numpy as npimport matplotlib.pyplot as plt raw_data_x = [[3.393533211 ,2.331273381 ], [2.110073483 ,1.781539638 ], [1.343808831 ,3.368360954 ], [3.582294042 ,4.679179110 ], [2.280362439 ,2.866990263 ], [7.423436942 ,4.696522875 ], [5.745051997 ,3.533989803 ], [9.172168622 ,2.511101045 ], [7.792783481 ,3.424088941 ], [7.939820817 ,0.791637231 ] ] raw_data_y = [0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ] X_train = np.array(raw_data_x) y_train = np.array(raw_data_y) x = np.array([8.093607318 ,3.365731514 ]) plt.scatter(X_train[y_train == 0 ,0 ],X_train[y_train == 0 ,1 ],color='g' ) plt.scatter(X_train[y_train == 1 ,0 ],X_train[y_train == 1 ,1 ],color='r' ) plt.scatter(x[0 ],x[1 ],color='b' ) plt.show()
欧拉距离:计算超平面两个点的距离
KNN 实现过程简单编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 import numpy as npimport matplotlib.pyplot as plt raw_data_x = [[3.393533211 ,2.331273381 ], [2.110073483 ,1.781539638 ], [1.343808831 ,3.368360954 ], [3.582294042 ,4.679179110 ], [2.280362439 ,2.866990263 ], [7.423436942 ,4.696522875 ], [5.745051997 ,3.533989803 ], [9.172168622 ,2.511101045 ], [7.792783481 ,3.424088941 ], [7.939820817 ,0.791637231 ] ] raw_data_y = [0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ] X_train = np.array(raw_data_x) y_train = np.array(raw_data_y) x = np.array([8.093607318 ,3.365731514 ])from math import sqrt distances = [] for x_train in X_train: d = sqrt(np.sum ((x_train - x)**2 )) distances.append(d)print ('distances=' )print (distances) nearset = np.argsort(distances)print ('nearset=' ) print (nearset) k = 6 topK_y = [y_train[i] for i in nearset[:k]]print ('topK_y=' )print (topK_y)from collections import Counter votes = Counter(topK_y)print ('votes=' )print (votes) mc1 = votes.most_common(1 )print ('mc1=' )print (mc1) predict = mc1[0 ][0 ]print ('predict=' )print (predict)
1.3、机器学习套路
可以说KNN是一个不需要训练过程的算法 k近邻算法是非常特殊的,可以被认为是没有模型的算法。为了和其他算法统一,可以认为训练数据集就是模型
1.4、判断机器学习算法的性能
训练数据集,测试数据集
不能用训练数据集来测试,所以要划分数据集为训练数据集,测试数据集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasets iris = datasets.load_iris() X = iris.data[:,:2 ] y = iris.target""" 目的:随机 拆分出 训练集 测试集 """ print ('=========================================================' ) shuffle_indexes = np.random.permutation(len (X))print (shuffle_indexes) test_ratio = 0.2 test_size = int (len (X) * test_ratio) test_indexes = shuffle_indexes[:test_size] train_indexes = shuffle_indexes[test_size:]print ('=========================================================' ) X_train = X[train_indexes] y_train = y[train_indexes]print (X_train)print (y_train)print ('=========================================================' ) X_test = X[test_indexes] y_test = y[test_indexes]print (X_test)print (y_test)print ('=========================================================' )print (X_train.shape)print (y_train.shape)print (X_test.shape)print (y_test.shape)
1.5、加载鸢尾花数据集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import numpy as npimport matplotlib as mplimport matplotlib.pyplot as pltfrom sklearn import datasets iris = datasets.load_iris()print (iris.DESCR) print ('===================================================================' )print (iris.data) print (iris.data.shape)print ('===================================================================' )print (iris.feature_names) print ('===================================================================' )print (iris.target) print (iris.target.shape)print (iris.target_names) X = iris.data[:,:2 ] y = iris.target X = iris.data[:,2 :] 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.6、手写字数据集
11-knn手写数字测试.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 from sklearn import datasets digits = datasets.load_digits()print (digits.keys())print (digits.DESCR)print ('==================================================' ) X = digits.dataprint (X.shape)print (X[:10 ]) y = digits.targetprint (y.shape)print (y[:100 ])print ('==================================================' ) some_digit = X[666 ] some_digit_image = some_digit.reshape(8 , 8 )import matplotlibimport matplotlib.pyplot as plt plt.imshow(some_digit_image, cmap=matplotlib.cm.binary) plt.show()from playML.module_selection import train_test_splitfrom playML.KNN import KNNClassifier X_train, y_train, X_test, y_test = train_test_split(X, y, test_radio=0.2 , seed=True ) my_knn_clf = KNNClassifier(k=3 ) my_knn_clf.fit(X_train, y_train) y_predict = my_knn_clf.predict(X_test)print (y_predict)print (sum (y_predict == y_test) / len (y_test))
1.7、超参数和模型参数
超参数 : 在算法运行前需要决定的参数
模型参数 : 算法过程中学习的参数
kNN算法没有模型参数
kNN算法中的k是典型的超参数
寻找最好的k
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from sklearn import datasets digits = datasets.load_digits() X = digits.data y = digits.targetfrom sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2 )from sklearn.neighbors import KNeighborsClassifier best_score = 0.0 best_k = -1 for k in range (1 , 11 ): knn_clf = KNeighborsClassifier(n_neighbors=k) knn_clf.fit(X_train, y_train) score = knn_clf.score(X_test, y_test) if score > best_score: best_k = k best_score = scoreprint ("best_k =" , best_k)print ("best_score =" , best_score)
一般情况下使用距离的导数作为权证
考虑距离:红色:1蓝色: 1/3+ 1/4 =7/12红色胜
考虑距离?不考虑距离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from sklearn.model_selection import train_test_splitfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn import datasets digits = datasets.load_digits() X = digits.data y = digits.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2 , random_state=666 ) best_method = "" best_score = 0.0 best_k = -1 for method in ["uniform" ,"distance" ]: for k in range (1 ,11 ): knn_clf = KNeighborsClassifier(n_neighbors=k,weights=method) knn_clf.fit(X_train,y_train) score = knn_clf.score(X_test,y_test) if score > best_score: best_k = k best_score = score best_method = methodprint ("best_k=" ,best_k)print ("best_score=" ,best_score)print ("best_method=" ,best_method)
什么是距离?
∑ i = 1 n ( X i ( a ) − X i ( b ) ) 2 \sqrt{\sum^n_{i=1}(X_i^{(a)}-X_i^{(b)})^2}
i = 1 ∑ n ( X i ( a ) − X i ( b ) ) 2
∑ i = 1 n ∣ X i ( a ) − X i ( b ) ∣ \sum_{i=1}^n|X_i^{(a)}-X_i^{(b)}|
i = 1 ∑ n ∣ X i ( a ) − X i ( b ) ∣
( ∑ i = 1 n ∣ X i ( a ) − X i ( b ) ∣ ) 1 1 (\sum_{i=1}^n|X_i^{(a)}-X_i^{(b)}|)^{\frac{1}{1}}
( i = 1 ∑ n ∣ X i ( a ) − X i ( b ) ∣ ) 1 1
( ∑ i = 1 n ∣ X i ( a ) − X i ( b ) ∣ 2 ) 1 2 (\sum_{i=1}^n|X_i^{(a)}-X_i^{(b)}|^2)^{\frac{1}{2}}
( i = 1 ∑ n ∣ X i ( a ) − X i ( b ) ∣ 2 ) 2 1
( ∑ i = 1 n ∣ X i ( a ) − X i ( b ) ∣ p ) 1 p (\sum_{i=1}^n|X_i^{(a)}-X_i^{(b)}|^p)^{\frac{1}{p}}
( i = 1 ∑ n ∣ X i ( a ) − X i ( b ) ∣ p ) p 1
明克夫斯基距离 Minkowski Distance
( ∑ i = 1 n ∣ X i ( a ) − X i ( b ) ∣ p ) 1 p (\sum_{i=1}^n|X_i^{(a)}-X_i^{(b)}|^p)^{\frac{1}{p}}
( i = 1 ∑ n ∣ X i ( a ) − X i ( b ) ∣ p ) p 1
到这里,我们获得了一个新的超参数 p
搜索明可夫斯基距离相应的p
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from sklearn.model_selection import train_test_splitfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn import datasets digits = datasets.load_digits() X = digits.data y = digits.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2 , random_state=666 ) best_p = -1 best_score = 0.0 best_k = -1 for k in range (1 ,11 ): for p in range (1 ,6 ): knn_clf = KNeighborsClassifier(n_neighbors=k,weights='distance' ,p=p) knn_clf.fit(X_train,y_train) score = knn_clf.score(X_test,y_test) if score > best_score: best_k = k best_score = score best_p = pprint ("best_p=" ,best_p)print ("best_k=" ,best_k)print ("best_score=" ,best_score)
1.8、网格搜索Grid Search
找最优参数
1.9、数据归一化处理
样本间的距离被一个字段所主导
解决方案 :将所有的数据映射到同一尺度
最值归一化 normalization :把所有数据映射到 0-1 之间
适合数值分布比较均匀,有边界的数据集
x s c a l e = x − x m i n x m a x − x m i n x_{scale}=\frac{x-x_{min}}{x_{max}-x_{min}}
x sc a l e = x ma x − x min x − x min
将这个数据映射到0~Xmax-Xmin 之间
然后对于每个x相比于整个范围所占的比例
适用于分布有明显边界的情况;
受outlier 影响较大
均值方差归一化 standardization (常用)
把所有数据归一到均值为0方差为1的分布中
适用于数据分布没有明显边界;有可能存在极端情况值
x s c a l e = x − x m e a n s x_{scale}=\frac{x-x_{mean}}{s}
x sc a l e = s x − x m e an
1.10、对测试数据集如何归一化?
测试数据是模拟真实环境
真实环境很有可能无法得到所有测试数据的均值和方差
对数据的归一化也是算法的一部分
在scikit-learn中使用Scaler
1.11、KNN的缺点
最大的缺点:效率低下
如果训练集有m个样本,n个特征,则预测每一个新的数据,需要O(m*n)
2、线性回归算法
2.1、简介
解决回归问题
思想简单,实现容易
许多强大的非线性模型的基础
结果具有很好的可解释性
蕴含机器学习中的很多重要思想
线性回归算法以一个坐标系里一个维度为结果,其他维度为特征(如二维平面坐标系中横轴为特征,纵轴为结果),无数的训练集放在坐标系中,发现他们是围绕着一条执行分布。线性回归算法的期望,就是寻找一条直线,最大程度的“拟合”样本特征和样本输出标记的关系
实现简单线性回归法
1 2 3 4 5 6 7 import numpy as npimport matplotlib.pyplot as plt x = np.array([1. , 2. , 3. , 4. , 5. ]) y = np.array([1. , 3. , 2. , 3. , 5. ]) plt.scatter(x, y) plt.axis([0 , 6 , 0 , 6 ]) plt.show()
3、梯度下降法
不是一个机器学习算法
是一种基于搜索 的最优化方法
作用:最小化一个损失函数
梯度上升法:最大化一个效用函数
以下是定义了一个损失函数以后,参数theta对应的损失函数J的值对应的示例图,我们需要找到使得损失函数值J取得最小值对应的θ \theta θ (这里是二维平面,也就是我们的参数只有一个)
在直线方程中,导数代表斜率 在曲线方程中,导数代表切线斜率 导数代表θ \theta θ 单位变化时,J相应的变化
η \eta η 称为学习率(learning rate);
η \eta η 的取值影响获得最优解的速度;
η \eta η 取值不合适,甚至得不到最优解;
η \eta η 是梯度下降法的一个超参数。
η \mathbf{\eta} η 取值的影响 :
其他注意事项 :
并不是所有函数都有唯一的极值点
解决方案:
多次运行,随机化初始点;
梯度下降法的初始点也是一个超参数。
线性回归法的损失函数∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 \sum_{i=1}^m(y^{(i)}-\hat{y}^{(i)})^2 ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 具有唯一的最优解 。
多元线性回归中的梯度下降法
套路
模型
数学推导(其他方法)损失函数或者效应函数
深度学习
1、感知机
2、神经网络