day06-----机器学习介绍

url

https://download.csdn.net/download/qq_34405401/12208225

1.机器学习常用算法

  • 监督
    1. 线性回归
    2. 逻辑回归 (正则化)
    3. SVM(支撑向量机support Vector Machine)
    4. DT(决策树)
    5. 集成算法
      • 随机森林
      • XGBoost
    6. k-NN
    7. Bayes分类
  • 无监督
    1. PCA
    2. 规则关联(推荐)
    3. k-Means

2.以线性回归为例进行机器学习入门

2.1 numpy实现

  1. 线性回归的场景
    • 数据呈现正比关系。
  2. 线性回归举例(身高与年龄的关系):
%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()
# 简单分析数据

在这里插入图片描述

  1. 结论:
    • 年龄与身高成正比关系。
  2. 学习目标:
    • 找出一条直线,使得点尽可能在直线周围。
  3. 建模
    • y i = w 1 ∗ x i + w 2 ∗ 1 y_i = w_1 \ast x_i + w_2 \ast 1 yi=w1xi+w21
    • 最优的w1与w2
  4. 简化模式:线性回归的数学模型:(即令w最后多一列1,把w2放入x最后一列)
    • $ y = W \cdot x$
  5. 理论模型与现实测量数据存在误差
    • ϵ = y − y ′ \epsilon = y - y ^ \prime ϵ=yy
    • 测量的样本与理想模型计算的数据存在误差,而且是误差平方和最小。(不靠谱)
      • ϵ = ∑ i = 1 , ⋯   , N ( y i − y i ′ ) 2 \epsilon = \sum \limits _{i=1,\cdots, N} (y_i - y_i ^\prime)^2 ϵ=i=1,,N(yiyi)2
  6. 理论基础
    • 测量误差:误差服从高斯分布:中心点是正确值,越接近中心点(正确值)概率越大。
    • L = ∏ i p ( ϵ ∣ x i ) L = \prod \limits _i p(\epsilon | x_i) L=ip(ϵxi)
  7. 损失函数(误差函数)的最优计算
    • 求极小值点(数学求解问题)
    • 代码中已有求解损失函数的算法。这些算法封装成模块,叫:优化器
  8. 最小化损失函数的一些常用算法:
    • 最小二乘法。
    • 梯度下降法。
    • 坐标下降法。
    • 牛顿迭代法。
    • 拟牛顿法

上面身高-年龄线性模型求解(继续上面的代码,使用最小二乘法求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 = ( X T X ) − 1 X T Y W = (X^T X)^{-1}X^TY W=(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 ) = c o v ( Y ′ , Y ) V a r ( Y ′ ) V a r ( 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,所以得+1
    for 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, :] = i
        idx += 1

print(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  3
  3  3  3  3  3  3  4  4  4  4  4  4  4  4  4  4  5  5  5  5  5  5  5  5
  5  5  6  6  6  6  6  6  6  6  6  6  7  7  7  7  7  7  7  7  7  7  8  8
  8  8  8  8  8  8  8  8  9  9  9  9  9  9  9  9  9  9 10 10 10 10 10 10
 10 10 10 10 11 11 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12 12 12 12
 13 13 13 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 14 14 15 15 15 15
 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 17 17
 17 17 18 18 18 18 18 18 18 18 18 18 19 19 19 19 19 19 19 19 19 19 20 20
 20 20 20 20 20 20 20 20 21 21 21 21 21 21 21 21 21 21 22 22 22 22 22 22
 22 22 22 22 23 23 23 23 23 23 23 23 23 23 24 24 24 24 24 24 24 24 24 24
 25 25 25 25 25 25 25 25 25 25 26 26 26 26 26 26 26 26 26 26 27 27 27 27
 27 27 27 27 27 27 28 28 28 28 28 28 28 28 28 28 29 29 29 29 29 29 29 29
 29 29 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 31 32 32
 32 32 32 32 32 32 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34
 34 34 34 34 35 35 35 35 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36
 37 37 37 37 37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 38 39 39 39 39
 39 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_matrix

matrix = 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_report

report = classification_report(pre_labels, label_faces[:,0])
print(report)
              precision    recall  f1-score   support

           1       1.00      1.00      1.00        10
           2       1.00      1.00      1.00        10
           3       1.00      1.00      1.00        10
           4       1.00      1.00      1.00        10
           5       1.00      1.00      1.00        10
           6       1.00      1.00      1.00        10
           7       1.00      1.00      1.00        10
           8       1.00      1.00      1.00        10
           9       1.00      1.00      1.00        10
          10       1.00      1.00      1.00        10
          11       1.00      1.00      1.00        10
          12       1.00      1.00      1.00        10
          13       1.00      1.00      1.00        10
          14       1.00      1.00      1.00        10
          15       1.00      1.00      1.00        10
          16       1.00      1.00      1.00        10
          17       1.00      1.00      1.00        10
          18       1.00      1.00      1.00        10
          19       1.00      1.00      1.00        10
          20       1.00      1.00      1.00        10
          21       1.00      1.00      1.00        10
          22       1.00      1.00      1.00        10
          23       1.00      1.00      1.00        10
          24       1.00      1.00      1.00        10
          25       1.00      1.00      1.00        10
          26       1.00      1.00      1.00        10
          27       1.00      1.00      1.00        10
          28       1.00      1.00      1.00        10
          29       1.00      1.00      1.00        10
          30       1.00      1.00      1.00        10
          31       1.00      1.00      1.00        10
          32       1.00      1.00      1.00        10
          33       1.00      1.00      1.00        10
          34       1.00      1.00      1.00        10
          35       1.00      1.00      1.00        10
          36       1.00      1.00      1.00        10
          37       1.00      1.00      1.00        10
          38       1.00      1.00      1.00        10
          39       1.00      1.00      1.00        10
          40       1.00      1.00      1.00        10

    accuracy                           1.00       400
   macro avg       1.00      1.00      1.00       400
weighted avg       1.00      1.00      1.00       400
# 精确度得分

from  sklearn.metrics import accuracy_score

acc = 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.总结

  1. 模式识别 ,机器学习(机器视觉),神经网络,深度学习关系
  2. sklearn:机器学习:分类,回归,聚类,模型,降维, 数据预处理:数据分析 -> 数据挖掘
  3. tensorflow/pytorch: 深度学习
  4. 机器视觉(图像opencv) + 自然语言(NLTK)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值