Python机器学习笔记:sklearn库的学习
ML神器:sklearn的快速使用
传统的机器学习任务从开始到建模的一般流程是:获取数据 → 数据预处理 → 训练建模 → 模型评估 → 预测,分类。
由图中,可以看到库的算法主要有四类:分类,回归,聚类,降维。其中:
流程图代表:蓝色圆圈是判断条件,绿色方框是可以选择的算法,我们可以根据自己的数据特征和任务目标去找一条自己的操作路线。
sklearn中包含众多数据预处理和特征工程相关的模块,虽然刚接触sklearn时,大家都会为其中包含的各种算法的广度深度所震惊,但其实sklearn六大板块中有两块都是关于数据预处理和特征工程的,两个板块互相交互,为建模之前的全部工程打下基础。
传统的机器学习任务从开始到建模的一般流程是:
获取数据 → 数据预处理 → 训练建模 → 模型评估 → 预测,分类。
本文我们将依据传统机器学习的流程,看看在每一步流程中都有哪些常用的函数以及它们的用法是怎么样的。
下面,我们开始一步步介绍
sklearn中包含了大量的优质的数据集,在我们学习机器学习的过程中,我们可以使用这些数据集实现出不同的模型,从而提高我们的动手实践能力,同时这个过程也可以加深对理论知识的理解和把握。除了引入数据之外,我们还可以通过**load_sample_images()**来引入图片。
首先,要使用sklearn中的数据集,必须导入datasets模块。
from sklearn import datasets
下面两个图中包含了大部分sklearn中的数据集,调用方式也图中给出,
这里我们使用iris的数据来举个例子,表示导出数据集:
iris = datasets.load_iris() # 导入数据集
X = iris.data # 获得其特征向量
y = iris.target # 获得样本label
注意,在0.18版本后,新增了一个功能:return_X_y=False
这个参数什么意思呢?就是控制输出数据的结构,若选为TRUE,则将因变量和自变量独立导出,我们看例子:
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
print(X.shape, y.shape, type(X))
data = load_iris(return_X_y=False)
print(type(data))
结果:
(150, 4) (150,) <class 'numpy.ndarray'>
<class 'sklearn.utils.Bunch'>
上面的代码可以直接运行,因为sklearn中自带这个数据集。
我们除了可以使用sklearn自带的数据集,还可以自己去创建训练样本。
from sklearn.datasets.samples_generator import make_classification
X, y = make_classification(n_samples=6, n_features=5, n_informative=2,
n_redundant=2, n_classes=2, n_clusters_per_class=2, scale=1.0,
random_state=20)
# n_samples:指定样本数
# n_features:指定特征数
# n_classes:指定几分类
# random_state:随机种子,使得随机状可重
例子:
from sklearn.datasets.samples_generator import make_classification
X, y = make_classification(n_samples=6, n_features=5, n_informative=2,
n_redundant=2, n_classes=2, n_clusters_per_class=2, scale=1.0,
random_state=20)
for x_, y_ in zip(X, y):
print(y_, end=': ')
print(x_)
结果:
0: [-0.6600737 -0.0558978 0.82286793 1.1003977 -0.93493796]
1: [ 0.4113583 0.06249216 -0.90760075 -1.41296696 2.059838 ]
1: [ 1.52452016 -0.01867812 0.20900899 1.34422289 -1.61299022]
0: [-1.25725859 0.02347952 -0.28764782 -1.32091378 -0.88549315]
0: [-3.28323172 0.03899168 -0.43251277 -2.86249859 -1.10457948]
1: [ 1.68841011 0.06754955 -1.02805579 -0.83132182 0.93286635]
scikit中的make_blobs方法常被用来生成聚类算法的测试数据,直观地说,make_blobs会根据用户指定的特征数量,中心点数量,范围等来生成几类数据,这些数据可用于测试聚类算法的效果。
sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=3,
cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True,
random_state=None)[source]
输入:
返回值:
例子(生成三类数据用于聚类(100个样本,每个样本2个特征)):
这个包自带这个数据集
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
data, label = make_blobs(n_samples=100, n_features=2, centers=5)
# 绘制样本显示
plt.scatter(data[:, 0], data[:, 1], c=label)
plt.show()
结果:
为每个类别设置不同的方差,只需要在上述代码中加入cluster_std参数即可:
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# 每个样本有几个属性或者特征
n_features = 2
data, target = make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=[1.0, 2.0, 3.0])
# 在2D图中绘制样本,每个样本颜色不同
plt.scatter(data[:, 0], data[:, 1], c=target)
plt.show()
通常用于分类算法
sklearn.datasets.make_classification(n_samples=100, n_features=20,
n_informative=2, n_redundant=2,n_repeated=0, n_classes=2,
n_clusters_per_class=2, weights=None,flip_y=0.01, class_sep=1.0,
hypercube=True,shift=0.0, scale=1.0, shuffle=True, random_state=None)
输入:
利用高斯分位点区分不同数据
sklearn.datasets.make_gaussian_quantiles(mean=None, cov=1.0, n_samples=100,
n_features=2, n_classes=3,shuffle=True, random_state=None)
利用Hastie算法,生成二分类数据
sklearn.datasets.make_hastie_10_2(n_samples=12000, random_state=None)
例子:
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.datasets import make_blobs
from sklearn.datasets import make_gaussian_quantiles
from sklearn.datasets import make_hastie_10_2
#创建图幅
plt.figure(figsize=(8, 8))
plt.subplots_adjust(bottom=0.05, top=0.9, left=0.1, right=0.95, wspace=0.15, hspace=0.5)
#图1
plt.subplot(421)
plt.title("One informative feature, one cluster per class", fontsize='small')
X1, Y1 = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_informative=1,
n_clusters_per_class=1)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1)
#图2
plt.subplot(422)
plt.title("Two informative features, one cluster per class", fontsize='small')
X1, Y1 = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_informative=2,
n_clusters_per_class=1)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1)
#图3
plt.subplot(423)
plt.title("Two informative features, two clusters per class", fontsize='small')
X2, Y2 = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_informative=2)
plt.scatter(X2[:, 0], X2[:, 1], marker='o', c=Y2)
#图4
plt.subplot(424)
plt.title("Multi-class, two informative features, one cluster",
fontsize='small')
X1, Y1 = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_informative=2,
n_clusters_per_class=1, n_classes=3)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1)
#图5
plt.subplot(425)
plt.title("Three blobs", fontsize='small')
X1, Y1 = make_blobs(n_samples=1000, n_features=2, centers=3)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1)
#图6
plt.subplot(426)
plt.title("Gaussian divided into four quantiles", fontsize='small')
X1, Y1 = make_gaussian_quantiles(n_samples=1000, n_features=2, n_classes=4)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1)
#图7
plt.subplot(427)
plt.title("hastie data ", fontsize='small')
X1, Y1 = make_hastie_10_2(n_samples=1000)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1)
plt.show()
结果:
调图位置函数:
matplotlib.pyplot.subplots_adjust
生成环线数据
sklearn.datasets.make_circles(n_samples=100, shuffle=True, noise=None, random_state=None, factor=0.8)
factor:外环和内环的尺度因子<1
sklearn.datasets.make_moons(n_samples=100, shuffle=True, noise=None, random_state=None)
生成半环图
from sklearn.datasets import make_circles
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
fig = plt.figure(1)
x1, y1 = make_circles(n_samples=1000, factor=0.5, noise=0.1)
plt.subplot(121)
plt.title('make_circles function example')
plt.scatter(x1[:, 0], x1[:, 1], marker='o', c=y1)
plt.subplot(122)
x1, y1 = make_moons(n_samples=1000, noise=0.1)
plt.title('make_moons function example')
plt.scatter(x1[:, 0], x1[:, 1], marker='o', c=y1)
plt.show()
Python数据处理中关于离散变量的处理——因子化、One-Hot、哑变量
数据预处理阶段是机器学习中不可缺少的一环,它会使得数据更加有效的被模型或者评估器识别。下面我们来看一下sklearn中有哪些平时我们常用的函数:
from sklearn import preprocessing
为了使得训练数据的标准化规则与测试数据的标准化规则同步,preprocessing中提供了很多的Scaler:
对应的有直接的函数使用:scale(),maxabs_scale(),minmax_scale(),robust_scale(),normaizer()
sklearn.preprocessing.scale(X)
标准化:在机器学习中,我们可能要处理不同种类的资料,例如,音讯和图片上的像素值,这些资料可能是高纬度的,资料标准化后会使得每个特征中的数值平均变为0(将每个特征的值都减掉原始资料中该特征的平均),标准差变为1,这个方法被广泛的使用在许多机器学习算法中(例如:支持向量机,逻辑回归和类神经网络)。
StandardScaler计算训练集的平均值和标准差,以便测试数据及使用相同的变换。
变换后各维特征有零均值,单位方差,也叫z-score规范化(零均值规范化),计算方式是将特征值减去均值,除以标准差。
fit
用于计算训练数据的均值和方差,后面就会用均值和方差来转换训练数据
fit_transform
不仅计算训练数据的均值和方差,还会基于计算出来的均值和方差来转换训练数据,从而把数据转化成标准的正态分布。
transform
很显然,它只是进行转换,只是把训练数据转换成标准的正态分布。(一般会把train和test集放在一起做标准化,或者在train集上做标准化后,用同样的标准化器去标准化test集,此时可以使用scaler)。
# 1. 基于mean和std的标准化
scaler = preprocessing.StandardScaler().fit(train_data)
scaler.transform(train_data)
scaler.transform(test_data)
一般来说先使用fit:
scaler = preocessing.StandardScaler().fit(X)
这一步可以计算得到scaler,scaler里面存的有计算出来的均值和方差。
再使用transform
scaler.transform(X)
这一步再用scaler中的均值和方差来转换X,使X标准化。
最后,在预测的时候,也要对数据做同样的标准化处理,即也要用上面的scaler中的均值和方差来对预测时候的特征进行标准化。
注意:测试数据和预测数据的标准化的方式要和训练数据标准化的方式一样,必须使用同一个scaler来进行transform。
最小最大规范化对原始数据进行线性变换,变换到[0,1]区间(也可以是其他固定最小最大值的区间)。
# 2. 将每个特征值归一化到一个固定范围
scaler = preprocessing.MinMaxScaler(feature_range=(0, 1)).fit(train_data)
scaler.transform(train_data)
scaler.transform(test_data)
#feature_range: 定义归一化范围,注用()括起来
当你想要计算两个样本的相似度时必不可少的一个操作,就是正则化。其思想是:首先求出样本的p范数,然后该样本的所有元素都要除以该范数,这样最终使得每个样本的范数都是1。规范化(Normalization)是将不同变化范围的值映射到相同的固定范围,常见的是[0,1],也成为归一化。
如下例子,将每个样本变换成unit norm。
from sklearn import preprocessing
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l2')
print(X_normalized)
结果:
[[ 0.40824829 -0.40824829 0.81649658]
[ 1. 0. 0. ]
[ 0. 0.70710678 -0.70710678]]
我们可以发现对于每一个样本都有0.42+0.42+0.812=1。这就是L2 norm,变换后每个样本的各维特征的平方和为1;
类似的,L1 norm则是变换后每个样本的各维特征的绝对值之和为1;
还有max norm,则是将每个样本的各维特征除以该样本各维特征的最大值。
在度量样本之间相似性时,如果使用的是二次型kernel,则需要做Normalization。
one-hot编码是一种对离散特征值的编码方式,在线性回归模型中常用到,用于给线性模型增加非线性能力。
from sklearn import preprocessing
data = [[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]
encoder = preprocessing.OneHotEncoder().fit(data)
print(encoder)
encoder = encoder.transform(data).toarray()
print(encoder)
结果:
OneHotEncoder()
[[1. 0. 1. 0. 0. 0. 0. 0. 1.]
[0. 1. 0. 1. 0. 1. 0. 0. 0.]
[1. 0. 0. 0. 1. 0. 1. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 1. 0.]]
给定阈值,将特征转换为0或1。
from sklearn import preprocessing
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
binarizer = preprocessing.Binarizer(threshold=1.1)
print(binarizer)
binarizer = binarizer.transform(X)
print(binarizer)
结果:
Binarizer(threshold=1.1)
[[0. 0. 1.]
[1. 0. 0.]
[0. 0. 0.]]
有时候特征时类别型的,而一些算法的输入必须是数值型,此时需要对其编码,
from sklearn import preprocessing
data = [[0, 1, 3]]
encoder = preprocessing.OneHotEncoder().fit(data)
encoder = encoder.transform(data).toarray()
print(encoder)
结果:
[[1. 1. 1.]]
from sklearn import preprocessing
data = [[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]
encoder = preprocessing.OneHotEncoder().fit(data)
encoder = encoder.transform([[0, 1, 3]]).toarray()
print(encoder)
结果:
[[1. 0. 0. 1. 0. 0. 0. 0. 1.]]
上面这个例子,第一维特征有两种值0和1,用两位去编码。第二维用三位,第三维用四位。
from sklearn import preprocessing
data = [1, 1, 2, 6]
le = preprocessing.LabelEncoder().fit(data).transform(data)
print(le)
结果:
[0 0 1 2]
from sklearn import preprocessing
# #非数值型转化为数值型
data = ["paris", "paris", "tokyo", "amsterdam"]
le = preprocessing.LabelEncoder().fit(data).transform(data)
print(le)
结果:
[1 1 2 0]
在得到训练数据集时,通常我们经常会把训练数据进一步拆分成训练集和验证集,这样有助于我们模型参数的选取。
train_test_split是模型选择model_selection中常用的函数,功能是从样本中随机的按比例选取训练集train data和测试集testdata,形式为:
X_train, X_test, y_train, y_test = model_selection.train_test_split(
train_data, train_target, test_size=0.4, random_state=0)
# 作用:将数据集划分为 训练集和测试集
# 格式:train_test_split(*arrays, **options)
from sklearn.mode_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
参数
---
arrays X,y:
样本数组,包含特征向量和标签
test_size:
float-获得多大比重的测试样本 (默认:0.25)
int - 获得多少个测试样本
train_size:
同test_size
random_state:
int - 随机种子(种子固定,实验可复现)
shuffle:
是否在分割之前对数据进行洗牌(默认True)
返回
---
分割后的列表,长度=2*len(arrays),
(train-test split)
在这一步我们首先要分析自己数据的类型,明白自己要用什么模型来做,然后我们就可以在sklearn中定义模型了,sklearn为所有模型提供了非常相似的接口,这样使得我们可以更加快速的熟悉所有模型的用法,在这之前,我们先来看看模型的常用属性和功能。
# 拟合模型
model.fit(X_train, y_train)
# 模型预测
model.predict(X_test)
# 获得这个模型的参数
model.get_params()
# 为模型进行打分
model.score(data_X, data_y)
from sklearn.linear_model import LinearRegression
# 定义线性回归模型
model = LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)
参数:
from sklearn.linear_model import LogisticRegression
# 定义逻辑回归模型
model = LogisticRegression(penalty='l2', dual=False, tol=0.0001, C=1.0,
fit_intercept=True, intercept_scaling=1,
class_weight=None, random_state=None,
solver='liblinear', max_iter=100, multi_class='ovr',
verbose=0, warm_start=False, n_jobs=1)
参数:
from sklearn import naive_bayes
model = naive_bayes.GaussianNB() #高斯贝叶斯
model = naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None) #多项式贝叶斯
model = naive_bayes.BernoulliNB(alpha=1.0, binarize=0.0, fit_prior=True, class_prior=None) #伯努利贝叶斯
文本分类问题常用MultinomialNB
参数:
from sklearn import tree
model = tree.DecisionTreeClassifier(criterion='gini', max_depth=None,
min_samples_split=2, min_samples_leaf=1,
min_weight_fraction_leaf=0.0, max_features=None,
random_state=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
class_weight=None, presort=False)
参数:
from sklearn.svm import SVC
model = SVC(C=1.0, kernel='rbf', gamma='auto')
参数:
from sklearn import neighbors
#定义kNN分类模型
model = neighbors.KNeighborsClassifier(n_neighbors=5, n_jobs=1) # 分类
model = neighbors.KNeighborsRegressor(n_neighbors=5, n_jobs=1) # 回归
参数:
from sklearn.neural_network import MLPClassifier
# 定义多层感知机分类算法
model = MLPClassifier(activation='relu', solver='adam', alpha=0.0001)
参数:
评价指标针对不同的机器学习任务有不同的指标,同一任务也有不同侧重点的评价指标。以下方法,sklearn中都在sklearn.metrics类下,务必记住哪些指标适合分类,哪些适合回归。
机器学习常用的评估指标请参考博文:Python机器学习笔记:常用评估模型指标的用法
from sklearn.model_selection import cross_val_score
cross_val_score(model, X, y=None, scoring=None, cv=None, n_jobs=1)
参数:
使用检验曲线,我们可以更加方便的改变模型参数,获取模型表现。
from sklearn.model_selection import validation_curve
train_score, test_score = validation_curve(model, X, y, param_name, param_range, cv=None, scoring=None, n_jobs=1)
参数:
返回值:
最后,我们可以将我们训练好的model保存到本地,或者放到线上供用户使用,那么如何保存训练好的model呢?主要有下面两种方式:
import pickle
# 保存模型
with open('model.pickle', 'wb') as f:
model = pickle.dump(model, f)
# 读取模型
with open('model.pickle', 'rb') as f:
model = pickle.load(model, f)
model.predict(X_test)
from sklearn.externals import joblib
# 保存模型
model = joblib.dump(model, 'model.pickle')
# 载入模型
model = joblib.load(model, 'model.pickle')
1、模型的score方法:最简单的模型评估方法就是调用模型自己的方法:
# 预测
y_predict = knnClf.predict(x_test)
print("score on the testdata:",knnClf.score(x_test,y_test))
2、sklearn的指标函数:库提供的一些计算方法,常用的有classification_report方法;
3、sklearn也支持自己开发评价方法。