《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记三
基础篇
本章书中着重介绍了监督学习经典模型和无监督学习经典模型的使用方法、性能评价以及优缺点。对于每一类经典模型,都将从模型简介、数据描述、编程实践、性能评测、特点分析五个角度进行阐述。
监督学习经典模型
监督学习任务的基本构架和流程:
- 准备训练数据(包括文本、音频、图像等),抽取所需要的特征,形成特征向量(Feature Vectors)。
- 把这些特征向量连同对应的标记/目标(Labels)一并送入学习算法(Machine Learning Algorithm),训练出一个预测模型(Predictive Model)。
- 采用同样的特征抽取方法作用于新测试数据,得到用于测试的特征向量。
- 使用预测模型对这些待测试的特征向量进行训练并得到结果。
分类学习
分类学习是最常见的监督学习问题,并且其中的经典模型也是最被广泛应用。包括二分类(Binary Classification)、多类分类(Multiclass Classification)、多标签分类(Multi-label Classification)。
线性分类器
是一种假设特征与分类结果存在线性关系的模型。这个模型通过累加计算每个维度的特征与各自权重的乘积来帮助类别决策。
定义代表维特征向量,定义n维列向量来代表对应的权重,增加一个截距(intercept),由此该线性关系可以表达为:
这类,取值范围分布于整个实数域。
我们所要处理的最简单的二分类问题希望,因此我们需要把原函数映射到,于是我们想到了Logistic函数:
将上式替换为,整合两个方程式,便获得了Logistic回归模型(Logistic Regression):
该模型处理一个待分类的特征向量:如果,那么;若,那么,则被判别为一类,反之被判别为另一类。
当使用一组m个用于训练的特征向量和其所对应的分类目标,我们希望Logistic回归模型可以在这组训练集上取得最大似然估计(Maximum Likelihood)的概率。
我们得知原始数据共有699条样本,每个样本有11列不同的数值:1列用于检索的id,9列与肿瘤相关的医学特征,1列表示肿瘤的类型。9列医学特征特质的数值均被量化为1~10之间的数字,肿瘤类型2代表良性肿瘤,肿瘤类型4代表恶性肿瘤。数据中有16个缺失值,用?表示。
import pandas as pd
import numpy as np
#创建特征列表
column_names = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion',
'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']
# 使用pandas.read_csv函数从互联网读取指定数据。
data = pd.read_csv('C:\\Users\\cao\\Jupyter\\Datasets\\Breast-Cancer\\breast-cancer-wisconsin.data',
names = column_names )
# 将?替换为标准缺失值表示。
data = data.replace(to_replace='?', value=np.nan)
# 丢弃带有缺失值的数据(只要有一个维度有缺失)。
data = data.dropna(how='any')
# 输出data的数据量和维度。
data.shape
(683, 11)
data.head
<bound method NDFrame.head of Sample code number Clump Thickness Uniformity of Cell Size \
0 1000025 5 1
1 1002945 5 4
2 1015425 3 1
3 1016277 6 8
4 1017023 4 1
.. ... ... ...
694 776715 3 1
695 841769 2 1
696 888820 5 10
697 897471 4 8
698 897471 4 8
Uniformity of Cell Shape Marginal Adhesion Single Epithelial Cell Size \
0 1 1 2
1 4 5 7
2 1 1 2
3 8 1 3
4 1 3 2
.. ... ... ...
694 1 1 3
695 1 1 2
696 10 3 7
697 6 4 3
698 8 5 4
Bare Nuclei Bland Chromatin Normal Nucleoli Mitoses Class
0 1 3 1 1 2
1 10 3 2 1 2
2 2 3 1 1 2
3 4 3 7 1 2
4 1 3 1 1 2
.. ... ... ... ... ...
694 2 1 1 1 2
695 1 1 1 1 2
696 3 8 10 2 4
697 4 10 6 1 4
698 5 10 4 1 4
[683 rows x 11 columns]>
# 使用sklearn.cross_valiation里的train_test_split模块用于分割数据。
# sklearn中已经废弃cross_validation,将其中的内容整合到model_selection中
from sklearn.model_selection import train_test_split
# 随机采样25%的数据用于测试,剩下的75%用于构建训练集合。
X_train, X_test, y_train, y_test = train_test_split(data[column_names[1:10]], data[column_names[10]], test_size=0.25, random_state=33)
#查验训练样本数量和类别分布
y_train.value_counts()
2 344
4 168
Name: Class, dtype: int64
# 查验测试样本的数量和类别分布。
y_test.value_counts()
2 100
4 71
Name: Class, dtype: int64
使用线性回归模型预测良性\恶行肿瘤
# 从sklearn.preprocessing里导入StandardScaler。
from sklearn.preprocessing import StandardScaler
# 从sklearn.linear_model里导入LogisticRegression与SGDClassifier。
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
# 标准化数据,保证每个维度的特征数据方差为1,均值为0。使得预测结果不会被某些维度过大的特征值而主导。
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)
使用Logistic回归和随机梯度下降参数估计两种方法对上述处理好的训练数据进行学习,并根据测试样本进行预测。
# 初始化LogisticRegression与SGDClassifier。
lr = LogisticRegression()
sgdc = SGDClassifier()
# 调用LogisticRegression中的fit函数/模块用来训练模型参数。
lr.fit(X_train, y_train)
# 使用训练好的模型lr对X_test进行预测,结果储存在变量lr_y_predict中。
lr_y_predict = lr.predict(X_test)
# 调用SGDClassifier中的fit函数/模块用来训练模型参数。
sgdc.fit(X_train, y_train)
# 使用训练好的模型sgdc对X_test进行预测,结果储存在变量sgdc_y_predict中。
sgdc_y_predict = sgdc.predict(X_test)
性能评测:
在代码的最后,我们分别利用LogisticRegression和SGDClassfier针对测试样本进行预测。我们接下来有多种评价指标。
准确性(Accuracy):y_test记录了测试样本的正确数据,计算预测正确的百分比。
召回率(Recall):#True positive/(#True positive + #False positive)
精确率(Precision):#True negative/(#True negative + #False negative)
F1指标(F1 measure):以上两个指标的调和平均数
# 从sklearn.metrics里导入classification_report模块。
from sklearn.metrics import classification_report
# 使用逻辑斯蒂回归模型自带的评分函数score获得模型在测试集上的准确性结果。
print('Accuracy of LR Classifier:', lr.score(X_test, y_test))
# 利用classification_report模块获得LogisticRegression其他三个指标的结果。
print(classification_report(y_test, lr_y_predict, target_names=['Benign', 'Malignant']))
Accuracy of LR Classifier: 0.9883040935672515
precision recall f1-score support
Benign 0.99 0.99 0.99 100
Malignant 0.99 0.99 0.99 71
accuracy 0.99 171
macro avg 0.99 0.99 0.99 171
weighted avg 0.99 0.99 0.99 171
# 使用随机梯度下降模型自带的评分函数score获得模型在测试集上的准确性结果。
print('Accuarcy of SGD Classifier:', sgdc.score(X_test, y_test))
# 利用classification_report模块获得SGDClassifier其他三个指标的结果。
print(classification_report(y_test, sgdc_y_predict, target_names=['Benign', 'Malignant']))
Accuarcy of SGD Classifier: 0.9941520467836257
precision recall f1-score support
Benign 1.00 0.99 0.99 100
Malignant 0.99 1.00 0.99 71
accuracy 0.99 171
macro avg 0.99 0.99 0.99 171
weighted avg 0.99 0.99 0.99 171
特点分析
线性分类器是最常用和最基本的机器学习模型,尽管其受限于数据特征和分类目标之间的线性假设。这里使用了LogisticRegression和SGDClassifier。相比之下,前者对参数的计算采用了精确解析的方式,计算时间长但模型性能略高;后者采用随机梯度上升算法估计模型参数,计算时间短但模型性能略低。一般而言,对于10W量级以上的数据,考虑到时间消耗,更加推荐使用随机梯度算法。