参考资料
<PYTHON_MACHINE_LEARNING> chapter3
A Tour of Machine Learning
Classifers Using Scikit-learn
引言
在本章节中,我们将接触一些常用的机器学习算法,了解这些监督学习式分类算法的优缺点,并且用 python 的 Scikit-learn 库来进行搭建
在面对具体问题的时候,我们并不能保证某一类算法是永远是最好的,没有一种单一的算法能够完美匹配所有的情况,这与样本中特征值,数据集,以及分类是否线性分离都有关系,一般的,我们大概要遵循以下五个流程:
- 1 Selection of features.
- 2 Choosing a performance metric(标准).
- 3 Choosing a classifer and optimization algorithm.
- 4 Evaluating the performance of the model.
- 5 Tuning the algorithm.
写在前面,关于新的函数
- numpy.unique() 只接受数组(一维情况可以等价于列表),不接受列表
import numpy as np
A = [1, 2, 2, 3, 4, 3]
a = np.unique(A)
print(a) # 输出为 [1 2 3 4]
a, b, c = np.unique(A, return_index=True, return_inverse=True)
print(a, b, c) # 输出为 [1 2 3 4], [0 1 3 4], [0 1 1 2 3 2]
- sklearn.model_selection.train_test_split 随机划分训练集和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
'''
一般形式:
train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data
和testdata,形式为:
X_train,X_test, y_train, y_test =
cross_validation.train_test_split(train_data,train_target,test_size=0.4, random_state=0)
参数解释:
train_data:所要划分的样本特征集
train_target:所要划分的样本结果
test_size:样本占比,如果是整数的话就是样本的数量
random_state:是随机数的种子。
随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。
比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。
'''
- StandardScaler 标准化特征值
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)#计算均值跟标准差
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
- Perceptron 类依靠 One-vs.-Rest 方法进行多分类
from sklearn.linear_model import Perceptron
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0)
# n_iter 迭代数 eta0 学习速率(需要不断测试) random_state用于每次迭代开始的时候打乱数据集
ppn.fit(X_train_std, y_train)
- Perceptron类中的 predict 方法 : 实现预测
y_pred = ppn.predict(X_test_std)
num = 0
for i in range(len(y_pred)):
if y_pred[i] != y_test[i]:
num += 1
print('Misclassified samples: %d' % num)
使用sclearn库中现有的 iris 数据集再现感知机模型
- 导入数据集
from sklearn import datasets
iris = datasets.load_iris()
x = iris.data[:,[2,3]] #提取每一行中的第2,3列
y = iris.target#获得相应的y
- 使用刚刚讲到的几个函数,我们可以重现chapter2 中的感知机
__author__ = 'Administrator'
#! /usr/bin/python <br> # -*- coding: utf8 -*-
from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score
from PDC import plot_decision_regions
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
iris = datasets.load_iris()
x = iris.data[:,[2,3]]
y = iris.target
X_train,X_test,y_train,y_test = train_test_split(
x , y, test_size=0.3, random_state = 0
)
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
ppn = Perceptron(n_iter=80,eta0=0.01,random_state=0)
ppn.fit(X_train_std,y_train)
y_pred = ppn.predict(X_test_std)
num = 0
for i in range(len(y_pred)):
if y_pred[i] != y_test[i]:
num += 1
print('Misclassified samples: %d' % num)
print('Accuracy:%.2f'% accuracy_score(y_test,y_pred))
X_combined_std = np.vstack((X_train_std,X_test_std))
y_combined = np.hstack((y_train,y_test))
plot_decision_regions(X=X_combined_std,y=y_combined,
classifier=ppn,
test_idx=range(105,150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.savefig('Iris.png')
plt.show()
- 在可视化的时候,我们引用了之前写好的PDC.py 中的 plot_decision_regions 函数
这里,我们需要在函数中加一个功能,使其能够高亮显示测试集数据
#! usr/bin/python <br> # -*- coding:utf8 -*-
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import numpy as np
def plot_decision_regions(X, y, classifier,test_idx = None, resolution=0.02):
#setup marker generator and colormap
markers = ('s','x','o','^','v')
colors = ('red','blue','lightgreen','gray','cyan')
cmap = ListedColormap(colors[: len(np.unique(y))])
# plot the decision surface
x1_min, x1_max = X[:,0].min() -1, X[:,0].max()+1
x2_min, x2_max = X[:,1].min() -1, X[:,1].max()+1
# X[:,k] 冒号左边表示行范围,读取所有行,冒号右边表示列范围,读取第K列
xx1, xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),
np.arange(x2_min,x2_max,resolution))
#arange(start,end,step) 返回一个一维数组
#meshgrid(x,y)产生一个以x为行,y为列的矩阵
#xx1是一个(305*235)大小的矩阵 xx1.ravel()是将所有的行放在一个行里面的长度71675的一维数组
#xx2同理
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
#np.array([xx1.ravel(), xx2.ravel()]) 生成了一个 (2*71675)的矩阵
# xx1.ravel() = (1,71675)
#xx1.shape = (305,205) 将Z重新调整为(305,205)的格式
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
# plot class samples
print(np.unique(y))
# idx = 0,1 cl = -1 1
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y==cl, 0], y=X[y==cl, 1],
alpha=0.8, c=cmap(idx),
marker = markers[idx],label = cl)
#highlight test samples
#增加的模块
if test_idx:
X_test, y_test = X[test_idx,:],y[test_idx]
plt.scatter(X_test[:,0],X_test[:,1],c='',edgecolors='0',
alpha=1.0, linewidths=1,marker='o',
s=55, label='test set')
贴一下结果吧