文章目录
- url
- 1.机器学习常用算法
- 2.以线性回归为例进行机器学习入门
-
- 2.1 numpy实现
-
- 总结:
- 2.2 sklearn实现
- 3.图像分类
-
- 3.1 支持向量机分类
- 4.分类算法的评判标准
- 5.交叉验证+参数调优(网格搜索)
- 6.总结
url
https://download.csdn.net/download/qq_34405401/12208225
1.机器学习常用算法
- 监督
- 线性回归
- 逻辑回归 (正则化)
- SVM(支撑向量机support Vector Machine)
- DT(决策树)
- 集成算法
- 随机森林
- XGBoost
- k-NN
- Bayes分类
- 无监督
- PCA
- 规则关联(推荐)
- k-Means
2.以线性回归为例进行机器学习入门
2.1 numpy实现
- 线性回归的场景
- 数据呈现正比关系。
- 线性回归举例(身高与年龄的关系):
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt# 读取数据
age = np.loadtxt('ex2x.dat')
tall = np.loadtxt('ex2y.dat')
# 用数据画一个散点图
figure = plt.figure(1, figsize=(5, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], title='年龄与身高')
#下面设置x轴,x轴是年龄,left=1.0代表最小一岁,right=10.0代表最大十岁
ax.set_xlim(left=1.0, right=10)
#设置y轴,y轴是身高,最低0.5,最高1.5
ax.set_ylim(bottom=0.5, top=1.5)
ax.scatter(x=age, y=tall, color='blue')
plt.show()
# 简单分析数据
- 结论:
- 年龄与身高成正比关系。
- 学习目标:
- 找出一条直线,使得点尽可能在直线周围。
- 建模
- yi=w1?xi+w2?1y_i = w_1 \ast x_i + w_2 \ast 1yi?=w1??xi?+w2??1
- 最优的w1与w2
- 简化模式:线性回归的数学模型:(即令w最后多一列1,把w2放入x最后一列)
- $ y = W \cdot x$
- 理论模型与现实测量数据存在误差
- ?=y?y′\epsilon = y - y ^ \prime?=y?y′
- 测量的样本与理想模型计算的数据存在误差,而且是误差平方和最小。(不靠谱)
- ?=∑i=1,?,N(yi?yi′)2\epsilon = \sum \limits _{i=1,\cdots, N} (y_i - y_i ^\prime)^2?=i=1,?,N∑?(yi??yi′?)2
- 理论基础
- 测量误差:误差服从高斯分布:中心点是正确值,越接近中心点(正确值)概率越大。
- L=∏ip(?∣xi)L = \prod \limits _i p(\epsilon | x_i)L=i∏?p(?∣xi?)
- 损失函数(误差函数)的最优计算
- 求极小值点(数学求解问题)
- 代码中已有求解损失函数的算法。这些算法封装成模块,叫:优化器
- 最小化损失函数的一些常用算法:
- 最小二乘法。
- 梯度下降法。
- 坐标下降法。
- 牛顿迭代法。
- 拟牛顿法
- …
上面身高-年龄线性模型求解(继续上面的代码,使用最小二乘法求W):
import numpy.linalg as ln
#需要的训练数据age、tall已获取,打印查看它们的类型
print(age.shape,tall.shape)
(50,) (50,)
#上面输出的(50,)意味着一维数组,数组中有50个元素;若是(50,1)那就是二维数组,即50行1列
#我们需要把数据转成矩阵,意味着二维数组
X = np.zeros(shape=(age.shape[0], 2), dtype=np.float)#此处X是两列是因为对应上面的 6.简化模型,即最后一列都是1
Y = tall.reshape(tall.shape[0], 1)#即转成矩阵(二维数组)的50行1列形式#X=np.zeros()中的元素都是0,因此需要克隆数据
X[:, 0] = age
X[:, 1] = 1 #最后一列都是1
W计算公式:W=(XTX)?1XTYW = (X^T X)^{-1}X^TYW=(XTX)?1XTY
W = np.matmul(np.matmul(ln.inv(np.matmul(X.T, X)), X.T), Y)
print(W)
[[0.06388117][0.75016254]]
预测的Y(tall)的计算公式: $Y = X W $
#我们要把学习得到的线性模型画出来,再把原来的真实数据散点图也画出来,看看点是否在习得模型的周围#画线性模型可以用真实数据的x(age)和预测y(tall)来画,也可以再生成50个x,带入线性模型中求y,并画出模型#在0到10岁之间生成50个点
X_AX = np.linspace(0, 10, 50, dtype=np.float)#格式处理
X_X = np.zeros(shape=(X_AX.shape[0], 2), dtype=np.float) # 构造连续50个样本-年龄
X_X[:, 0] = X_AX
X_X[:, 1] = 1
#求出预测值Y_X
Y_X = np.matmul(X_X, W)#画出线性模型
fig = plt.figure(1, figsize=(5, 4))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], title="训练模型")
ax.set_xlim(0,10)
ax.set_ylim(0, 1.7)
ax.plot(X_AX, Y_X, color='blue')
#画出真实值的散点图
ax.scatter(x=age, y=tall, color='red')
plt.show()
- 11.结果比较
- 回归模型比较真实值与理想值之间的拟合关系:相关系数
- r(Y′,Y)=cov(Y′,Y)Var(Y′)Var(Y)r(Y ^ \prime, Y) = \dfrac{cov(Y^\prime,Y)}{\sqrt{Var(Y ^ \prime)Var(Y)}}r(Y′,Y)=Var(Y′)Var(Y)?cov(Y′,Y)?
Y_ = np.matmul(X, W)#Y_是真实数据X的预测值
r = np.corrcoef(Y.T, Y_.T)#比较预测的Y和真实的Y_
print(r)
[[1. 0.92631702][0.92631702 1. ]]
总结:
先确定模型,然后根据误差概率模型确定损失函数,再选择优化器最小化损失函数,最后模型编程。
2.2 sklearn实现
from sklearn.linear_model import LinearRegression# 1. 对象构建
regressor = LinearRegression()# 2. fit是训练
regressor.fit(X, Y) # sklearn提供数据格式的自动处理,但是要求我们形成数据格式的规范。# 3. 预测
Y_PRE = regressor.predict(X)#coef是系数,此时对应W;intercept是截距
print(regressor.coef_, regressor.intercept_)
[[0.06388117 0. ]] [0.75016254]
#评估预测的拟合情况
score = regressor.score(X, Y)
print(score)
0.858063223720823
3.图像分类
分类算法有:SVM、Logistic、PCA等
3.1 支持向量机分类
import numpy as np
#机器视觉方面使用opencv
import cv2
# 读取图像
img_test = cv2.imread("./att_faces/s1/1.pgm")
print(img_test.shape)
(112, 92, 3)
#每张图片的形状为112行(高),92列(长),3为深度即带三个颜色通道
#接下来展示这张图片
%matplotlib inline
import matplotlib.pyplot as plt
#cmap=plt.cm.gray是按灰度展示
plt.imshow(img_test, cmap=plt.cm.gray)
plt.show()
# 接下来读取图像到矩阵,一共有四百张图
# 定义常量#每个人有十张自己的图像
ONE_PERSON_FACE_NUM = 10
#一共有40个人
PERSON_NUM = 40
#图像数量自然是40*10
SAMPLE_NUM = ONE_PERSON_FACE_NUM * PERSON_NUM
#每张图像高112,宽92
IMG_W = 92
IMG_H = 112#定义存放图像信心的矩阵
#因为有400张图,因此行是SAMPLE_NUM,列是每张图的信息,最后效果是一行代表一张图
data_faces = np.zeros(shape=(SAMPLE_NUM, IMG_W * IMG_H), dtype=np.int32)
#一行代表一个图片的类别,因此只需要一列
label_faces = np.zeros(shape=(SAMPLE_NUM, 1), dtype=np.int32)#把图片信息复制到矩阵中
idx = 0 # 数据集的位置,即在哪个文件夹
for i in range(1, PERSON_NUM + 1): # 40个人的目录,此处是使角标从1到PERSON_NUM,因为range不包含PERSON_NUM,所以得+1for j in range(1, ONE_PERSON_FACE_NUM + 1):path_ = "./att_faces/s{i}/{j}.pgm".format(i=i,j=j)img_ = cv2.imread(path_)#因为读取的是三通道图像,为了大大减少计算量,转化为灰度图像(因为做图像识别,颜色没有太大价值,所以可转灰度)gray_ = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY)data_faces[idx, :] = gray_.reshape(IMG_W * IMG_H)label_faces[idx, :] = iidx += 1print(data_faces.shape,label_faces.shape)
(400, 10304) (400, 1)
#此时图像转矩阵完毕,查看矩阵是否信息正确
#查看矩阵里的最后一张图像
plt.imshow(data_faces[-1:].reshape((IMG_H, IMG_W)), cmap='gray')
plt.show()
#查看文件夹存放的最后一张
img_test = cv2.imread("./att_faces/s40/10.pgm")
plt.imshow(img_test, cmap=plt.cm.gray)
plt.show()
#确定矩阵信息正确,接下来对图像进行预处理,即PCA降维,其中会自动归一化
#降维的原因是原先数据维度太高,特征太多;且经实验降到20维效果最好from sklearn.decomposition import PCA
#降到20维
n_dims = 20
# 训练,whiten为白化,svd_solver为奇异值分解
pca = PCA(n_components=n_dims, whiten=True, svd_solver='randomized')
# 用data_faces来训练得到降维后的特征
pca.fit(data_faces)
#将降维后得到的第一个人脸特征显示出来,并打出来
eg_faces = pca.components_.reshape((n_dims, IMG_H, IMG_W))
plt.imshow(eg_faces[0], cmap='gray')
plt.show()
print(eg_faces[0])
[[-0.00212508 -0.00211277 -0.0021425 ... -0.00192885 -0.00195297-0.00202584][-0.00215919 -0.00206477 -0.00235067 ... -0.00176855 -0.00173679-0.00189663][-0.0019191 -0.00201744 -0.00217899 ... -0.0018383 -0.00174359-0.00175921]...[-0.01346525 -0.01375571 -0.01361521 ... -0.00615034 -0.00604953-0.00588547][-0.01411743 -0.01450171 -0.01444153 ... -0.00682447 -0.00679768-0.00701538][-0.01481082 -0.01578775 -0.01547279 ... -0.00704006 -0.00639096-0.00734479]]
#查看降维后所有的人脸特征
rows = 5
cols = 4
plt.figure(figsize=(1.8 * cols, 2.4 * rows))
for i in range(n_dims):ax = plt.subplot(rows, cols, i+1)plt.imshow(eg_faces[i], cmap="gray")plt.xticks(())plt.yticks(())
plt.show()
#通过上述对降维的训练,已经得出了20个特征脸,接下来将数据降维成20维
#此处用data_faces训练,用data_faces降维,这样做不好;其实应该用一部分数据训练,然后对所有数据降维
pca_data = pca.transform(data_faces)
print(pca_data.shape)
(400, 20)
#调用逻辑回归进行分类,SVC是支持向量机分类运算
from sklearn.svm import SVC
classifier = SVC(kernel='rbf', C=1000, gamma=0.1)
#训练
classifier.fit(pca_data, label_faces[:,0])
#预测,用训练的数据进行预测,不太好
pre_labels = classifier.predict(pca_data)
#打印预测的类
print(pre_labels)
[ 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 33 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 55 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 88 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 1010 10 10 10 11 11 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12 12 12 1213 13 13 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 14 14 15 15 15 1515 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 17 1717 17 18 18 18 18 18 18 18 18 18 18 19 19 19 19 19 19 19 19 19 19 20 2020 20 20 20 20 20 20 20 21 21 21 21 21 21 21 21 21 21 22 22 22 22 22 2222 22 22 22 23 23 23 23 23 23 23 23 23 23 24 24 24 24 24 24 24 24 24 2425 25 25 25 25 25 25 25 25 25 26 26 26 26 26 26 26 26 26 26 27 27 27 2727 27 27 27 27 27 28 28 28 28 28 28 28 28 28 28 29 29 29 29 29 29 29 2929 29 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 31 32 3232 32 32 32 32 32 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 3434 34 34 34 35 35 35 35 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 3637 37 37 37 37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 38 39 39 39 3939 39 39 39 39 39 40 40 40 40 40 40 40 40 40 40]
#查看预测的准确率,此处是100%正确
corr_num = (pre_labels == label_faces[:,0]).sum()
corr_num/=400.0
print(corr_num)
1.0
4.分类算法的评判标准
- 识别准确率:
- 误识率:(FAR)是指在标准指纹数据库上测试指纹识别算法时,不同指纹的匹配分数大于给定阈值,从而被认为是相同指纹的比例,简单地说就是“把不应该匹配的指纹当成匹配的指纹”的比例。
- 拒识率:(FRR)是指在标准指纹数据库上测试指纹识别算法时,相同指纹的匹配分数低于给定阈值,从而被认为是不同指纹的比例,简单地说就是 “把应该相互匹配成功的指纹当成不能匹配的指纹”的比例。
- 度量模式:
- 混淆矩阵
- 分类报告
- 精确度得分
采用上面图像分类程序作为例子
# 混淆矩阵from sklearn.metrics import confusion_matrixmatrix = confusion_matrix(pre_labels, label_faces[:,0])
print(matrix)
[[10 0 0 ... 0 0 0][ 0 10 0 ... 0 0 0][ 0 0 10 ... 0 0 0]...[ 0 0 0 ... 10 0 0][ 0 0 0 ... 0 10 0][ 0 0 0 ... 0 0 10]]
# 分类报告from sklearn.metrics import classification_reportreport = classification_report(pre_labels, label_faces[:,0])
print(report)
precision recall f1-score support1 1.00 1.00 1.00 102 1.00 1.00 1.00 103 1.00 1.00 1.00 104 1.00 1.00 1.00 105 1.00 1.00 1.00 106 1.00 1.00 1.00 107 1.00 1.00 1.00 108 1.00 1.00 1.00 109 1.00 1.00 1.00 1010 1.00 1.00 1.00 1011 1.00 1.00 1.00 1012 1.00 1.00 1.00 1013 1.00 1.00 1.00 1014 1.00 1.00 1.00 1015 1.00 1.00 1.00 1016 1.00 1.00 1.00 1017 1.00 1.00 1.00 1018 1.00 1.00 1.00 1019 1.00 1.00 1.00 1020 1.00 1.00 1.00 1021 1.00 1.00 1.00 1022 1.00 1.00 1.00 1023 1.00 1.00 1.00 1024 1.00 1.00 1.00 1025 1.00 1.00 1.00 1026 1.00 1.00 1.00 1027 1.00 1.00 1.00 1028 1.00 1.00 1.00 1029 1.00 1.00 1.00 1030 1.00 1.00 1.00 1031 1.00 1.00 1.00 1032 1.00 1.00 1.00 1033 1.00 1.00 1.00 1034 1.00 1.00 1.00 1035 1.00 1.00 1.00 1036 1.00 1.00 1.00 1037 1.00 1.00 1.00 1038 1.00 1.00 1.00 1039 1.00 1.00 1.00 1040 1.00 1.00 1.00 10accuracy 1.00 400macro avg 1.00 1.00 1.00 400
weighted avg 1.00 1.00 1.00 400
# 精确度得分from sklearn.metrics import accuracy_scoreacc = accuracy_score(pre_labels, label_faces[:,0])
print(acc)
1.0
5.交叉验证+参数调优(网格搜索)
- 样本数据集划分为:训练集、测试集
- 划分方案:
- 直接分
- n-折
- 划分方案:
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.svm import SVC
#加载数据集
data,target=datasets.load_iris(return_X_y=True)
print(data.shape)#交叉验证:训练集+测试集
#test_size=0.2,测试集是原数据规模的0.2
data_train,data_test,target_train,target_test=train_test_split(data,target,test_size=0.2)
print(data_train.shape)#调用机器学习算法完成训练(常规训练+网格搜索训练)
#classifier=SVC(kernel='rbf',C=1000,gamma=0.1) #这个算法参数是固定的
#参数字典
dic_p={
'C':[1,10,100,10000],'gamma':[0.01,0.1,1],
}
#网格搜索:这个是从参数字典里自动找到最佳参数,即网格搜索
classifier=GridSearchCV(SVC(kernel='rbf'),dic_p)
classifier.fit(data_train,target_train)#结果
pre=classifier.predict(data_test)
#测试集一共三十个,打印正确预测的个数
print((pre==target_test).sum())
(150, 4)
(120, 4)
30
6.总结
- 模式识别 ,机器学习(机器视觉),神经网络,深度学习关系
- sklearn:机器学习:分类,回归,聚类,模型,降维, 数据预处理:数据分析 -> 数据挖掘
- tensorflow/pytorch: 深度学习
- 机器视觉(图像opencv) + 自然语言(NLTK)