12-机器学习练习与特征工程、评价指标

一.使用PCA识别手写数字

PCA:Principal Component Analysis(主成分分析)
PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维


图1.png

图2.png

1.导包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.svm import SVC
%matplotlib inline

2.加载数据

data = pd.read_csv('./train.csv')
data.shape

3.处理数据获取训练数据和测试数据

数据共有785列,第一列为label,剩下的784列数据存储的是灰度图像(0~255)的像素值 28*28=784

#手迹像素信息
images = data.iloc[:,1:].values
#标签信息
target = data.iloc[:,:1].values.reshape(-1)


train_num = 5000
test_num = 7000
X_train,X_test = images[:train_num],images[:-test_num]
y_train,y_test = target[:train_num],target[:-test_num]

4.使用PCA进行降维

使用PCA对测试数据进行降维
pca = PCA(n_components=0.8,whiten=True)
#设置PCA参数
#n_components:
#设为大于零的整数,会自动的选取n个主成分,
#设为分数时,选择特征值占总特征值大于n的,作为主成分
#whiten:
#True表示做白化处理,白化处理主要是为了使处理后的数据方差都一致

pca = PCA(n_components= 0.8,whiten = True)
pca.fit(images)

X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)

5.创建机器学习模型

svc = SVC(kernel='rbf')
svc.fit(X_train_pca,y_train)
y_svc = svc.predict(y_test)

#预测数据
#对手迹进行识别识别
svc.score(X_test_pca,y_test)

6.预测数据绘制图形

#绘制50个数据
plt.figure(figsize = (1.8*10,2.5*5))
for i in range(50):
    plt.subplot(5,10,i+1)
    plt.imshow(X_test[i].reshape(28,28))
    plt.axis('off')
    plt.title('trainig: '+str(y_test[i])+'\n'+'predict: '+str(y_svc[i]))
plt.show()
手写识别.png

二.人脸识别

GridSearchCV:用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数:
GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。但是这个方法适合于小数据集,一旦数据的量级上去了,很难得出结果。这个时候就是需要动脑筋了。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法:拿当前对模型影响最大的参数调优,直到最优化;再拿下一个影响最大的参数调优,如此下去,直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优,但是省时间省力,巨大的优势面前,还是试一试吧,后续可以再拿bagging再优化。回到sklearn里面的GridSearchCV,GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数

SVM的两个参数 C 和 gamma:
C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差;
gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度

1.导包

import matplotlib.pyplot as plt
import logging
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV

#Labeled Faces in the Wild Home 标记的面孔数据
from sklearn.datasets import fetch_lfw_people
from sklearn.decomposition import PCA
from sklearn.svm import SVC
import numpy as np

2.设置log日志输出,显示程序执行的进度

# 控制台输出记录数据,显示程序处理数据的进度
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')

3.加载人脸数据

#############################################################################
# 获取数据,如果没有人脸的数据,那么从网络上进行下载,如果本地磁盘有,那么从本地进行加载
lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)

4.记录图像数组的维度

# 查看图像数据的数组结构(绘图)
n_samples, h, w = lfw_people.images.shape

5.从加载的数据中获取机器学习的训练数据

# 对于机器学习,我们直接使用2个数据(由于该模型忽略了相对像素位置信息)
X = lfw_people.data
# 目标人物的标签
y = lfw_people.target
#目标人物的名字
target_names = lfw_people.target_names

6.处理数据得到训练数据和测试数据

#############################################################################
#分割训练数据和预测数据
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)

7.数据的维度太高使用pca进行降维

#############################################################################
# 使用PCA对数据进行降维,去除一些不重要的数据,之前的维度是1850,我们降维到150
n_components = 150
#创建pca并训练数据
pca = PCA(n_components=n_components, svd_solver='randomized',
          whiten=True).fit(X_train)
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)

8.通过pca算法,我们可以从总体数据中抽取特征面部

#150张最具特张的脸部数据
eigenfaces = pca.components_.reshape((n_components, h, w))

9.运用GridSearchCV获取最佳的机器学习方法

#############################################################################
# 创建机器学习模型
c = np.arange(1,10,2)
param_grid = {'C': c,
              'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
clf = clf.fit(X_train_pca, y_train)

#通过GridSearchCV我们找到了最佳的支持向量机方法
print('最佳的支持向量机参数',clf.best_estimator_)

10.定义方法人脸对应人名,预测姓名,真实姓名

# 预测名字和真实名字
def title(y_pred, y_test, target_names, i):
    pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]
    true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]
    return 'predicted: %s\ntrue:      %s' % (pred_name, true_name)

11.定义绘制图形方法

#y_test是图片数据
#row代表多少行,columns代表多少列
def draw_picture(X_test,row,columns,titles):
    plt.figure(figsize=(columns*2,row*2.8))
    for i in range(row*columns):
        plt.subplot(row,columns,(i+1))
        plt.imshow(X_test[i].reshape((250,250)),cmap = 'gray')
        plt.title(titles[i])
        plt.axis('off')

12.调用方法,显示人脸识别的预测结果

#调用方法获取人脸预测的名字,以及人脸的真实名字
prediction_titles = [title(y_pred, y_test, target_names, i)
                     for i in range(y_pred.shape[0])]
#调用方法,进行人脸绘制
plot_gallery(X_test, prediction_titles, h, w)
#显示
plt.show()
人脸预测1.png

人脸预测2.png

三.特征工程

特征工程.png

四.机器学习评价指标

机器学习常见评价指标:

  • AUC
    AUC是一个模型评价指标,用于二分类模型的评价。AUC是“Area under Curve(曲线下的面积)”的英文缩写,而这条“Curve(曲线)”就是ROC曲线。
    ROC:受试者工作特征曲线


    ROC.png

    然后,我们计算两个指标的值:
      True Positive Rate=TP/(TP+FN),代表将真实正样本划分为正样本的概率 真阳率
      False Positive Rate=FP/(FP+TN),代表将真实负样本划分为正样本的概率 伪阳率

      接着,我们以“True Positive Rate”作为纵轴,以“False Positive Rate”作为横轴,画出ROC曲线。类似下图:
    类似图---ROC.png

    为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?答案是这样的:机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。使用AUC可以解决这个问题,接下来详细介绍AUC的计算。

例如,数据集一共有5个样本,真实类别为(1,0,0,1,0);二分类机器学习模型,得到的预测结果为(0.5,0.6,0.4,0.7,0.3)。将预测结果转化为类别——预测结果降序排列,以每个预测值(概率值)作为阈值,即可得到类别。计算每个阈值下的“True Positive Rate”、“False Positive Rate”。以“True Positive Rate”作为纵轴,以“False Positive Rate”作为横轴,画出ROC曲线,ROC曲线下的面积,即为AUC的值。
那么什么是“True Positive Rate”、“False Positive Rate”?

首先,我们看如下的图示:
ROC1.png

然后,我们计算两个指标的值:
  TruePositiveRate=TP/(TP+FN),代表将真实正样本划分为正样本的概率

  FalsePositiveRate=FP/(FP+TN),代表将真实负样本划分为正样本的概率

  接着,我们以“True Positive Rate”作为纵轴,以“False Positive Rate”作为横轴,画出ROC曲线,ROC曲线下的面积,即为AUC的值。类似下图:
类似图---ROC1.png
  • Precision、Recall、F-measure、Accuracy
    Precision------"正确被检索的item(TP)"占所有"实际被检索到的(TP+FP)"的比例
    Recall------“正确被检索的item(TP)"占所有"应该检索到的item(TP+FN)"的比例
    F-measure= 正确率 * 召回率 * 2 / (正确率 + 召回率) (F 值即为正确率和召回率的调和平均值)


    1.png

    2.png

五.ROC-AUC图形绘制

1.导包

import numpy as np
#线性插值
from scipy import interp
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn import svm, datasets
# 评价指标
from sklearn.metrics import roc_curve, auc
# 数据拆分,分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同
from sklearn.model_selection import StratifiedKFold

2.加载数据iris并添加噪声

iris = datasets.load_iris()
X = iris.data
y = iris.target
X, y = X[y != 2], y[y != 2]
n_samples, n_features = X.shape

# Add noisy features
random_state = np.random.RandomState(0)
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]

3.声明算法

cv = StratifiedKFold(n_splits=6)
classifier = svm.SVC(kernel='linear', probability=True,random_state=random_state)

tprs = []
aucs = []
mean_fpr = np.linspace(0, 1, 100)

4.批量训练计算ROC

i = 0
for train, test in cv.split(X, y):
    probas_ = classifier.fit(X[train], y[train]).predict_proba(X[test])
    y_ = classifier.predict(X[test])
    # Compute ROC curve and area the curve
    fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1])
    
    tprs.append(interp(mean_fpr, fpr, tpr))
    tprs[-1][0] = 0.0
    roc_auc = auc(fpr, tpr)
    aucs.append(roc_auc)
    plt.plot(fpr, tpr, lw=1, alpha=0.3,
             label='ROC fold %d (AUC = %0.2f)' % (i, roc_auc))
    i += 1

5.计算平均ROC

mean_tpr = np.mean(tprs, axis=0)
mean_tpr[-1] = 1.0
mean_auc = auc(mean_fpr, mean_tpr)
std_auc = np.std(aucs)
plt.plot(mean_fpr, mean_tpr, color='b',
         label=r'Mean ROC (AUC = %0.2f $\pm$ %0.2f)' % (mean_auc, std_auc),
         lw=2, alpha=.8)

6.设置绘图

plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
ROC-AUC.png

推荐阅读更多精彩内容