sklearn库入门介绍
sklearn有六大模块+数据导入:
Classification(分类)、Regression(回归)、Clustering(聚类)、Dimensionality Reduction(降维)、Model Selection(模型选择)、Preprocessing(预处理)
以及datasets(数据导入)
一、datasets
datasets.load_(导入小数据集)
datasets.fetch_(导入大数据集)
datasets.make_(创建数据集)
##datasets from sklearn import datasets digits = datasets.load_digits() digits.keys() housing = datasets.fetch_california_housing() housing.keys() gquant = datasets.make_gaussian_quantiles() type(gquant),len(gquant)
二、估计器(estimater)
线性回归和k均值聚类
注意:唯一需要注意的就是输入 X 要求是两维(二维数组)
from sklearn.linear_model import LinearRegression model = LinearRegression(normalize = True) model x = np.arange(10) y = x *2 + 1 plt.plot(x,y,'o') X = x[:,np.newaxis] ##将x转化成二维数组 lr = model.fit(X,y) lr.coef_ lr.intercept_
画图
from matplotlib.colors import ListedColormap cmap_light = ListedColormap(['#FFAAAA','#AAFFAA','#AAAAFF']) cmap_bold1 = ListedColormap(['red','green','blue']) cmap_bold2 = ListedColormap(['red','blue','green']) centroid = mod1.cluster_centers_ ##聚类中心 label = iris.target ##原始标签 true_centroid =np.vstack((x[label == 0,:].mean(axis = 0), x[label == 1,:].mean(axis = 0), x[label == 2,:].mean(axis = 0))) ##原始数据的中心 plt.figure(figsize = (12,6)) plt.subplot(1,2,1) plt.scatter(x[:,0],x[:,1],c= mod1.labels_,cmap = cmap_bold1) plt.scatter(centroid[:,0],centroid[:,1],marker = 'o',s = 200, edgecolors = 'k',c = [0,1,2],cmap = cmap_light) plt.xlabel('sepal length(cm)') plt.ylabel('sepal width(cm)') plt.title('Cluster Class') plt.subplot(1,2,2) plt.scatter(x[:,0],x[:,1],c= iris.target,cmap = cmap_bold2) plt.scatter(true_centroid[:,0],true_centroid[:,1],marker = 'o',s = 200, edgecolors = 'k',c = [0,2,1],cmap = cmap_light) plt.xlabel('sepal length(cm)') plt.ylabel('sepal width(cm)') plt.title('True Class') plt.show()
三、预测器(predict函数)
logistic回归
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression iris = load_iris() x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target,test_size=0.2) x_train.shape mod2 = LogisticRegression(solver = 'lbfgs',multi_class = 'multinomial') ##multi_class多分类 lor = mod2.fit(x_train,y_train) y_pred = lor.predict(x_test) ##类别 p_pred = lor.predict_proba(x_test) ##概率 print(y_test,'\n') print(y_pred,'\n') print(p_pred[:5,:]) ''' s = ['Class 1 Prob', 'Class 2 Prob', 'Class 3 Prob'] prob_DF = pd.DataFrame( p_pred, columns=s ) prob_DF['Predicted Class'] = y_pred prob_DF.head() ''' lor.score(x_test, y_test) ##分类准确率 print(np.sum(y_pred == y_test)/len(y_test)) ##分类准确率 decision_score = lor.decision_function(x_test) print(decision_score) ''' #是否按照分数最高的分类 s = ['Class 1 Score', 'Class 2 Score', 'Class 3 Score'] decision_df = pd.DataFrame(decision_score,columns = s) decision_df['score class'] = y_pred decision_df.tail() '''
##k均值聚类 from sklearn.cluster import KMeans mod1 = KMeans(n_clusters = 3) km = mod1.fit(x_train[:,0:2]) idx_pred = km.predict(x_test[:,0:2]) print(idx_pred) print(y_test) km.score(x_test[:,0:2]) ##画图 from matplotlib.colors import ListedColormap cmap_light = ListedColormap(['#FFAAAA','#AAFFAA','#AAAAFF']) cmap_bold1 = ListedColormap(['red','green','blue']) cmap_bold2 = ListedColormap(['red','blue','green']) centroid = mod1.cluster_centers_ ##聚类中心 true_centroid =np.vstack((x_test[y_test == 0,:].mean(axis = 0), x_test[y_test == 1,:].mean(axis = 0), x_test[y_test == 2,:].mean(axis = 0))) ##原始数据的中心 plt.figure(figsize = (12,6)) plt.subplot(1,2,1) plt.scatter(x_test[:,0],x_test[:,1],c= idx_pred,cmap = cmap_bold1) plt.scatter(centroid[:,0],centroid[:,1],marker = 'o',s = 200, edgecolors = 'k',c = [0,1,2],cmap = cmap_light) plt.xlabel('sepal length(cm)') plt.ylabel('sepal width(cm)') plt.title('Cluster Class') plt.subplot(1,2,2) plt.scatter(x_test[:,0],x_test[:,1],c = y_test,cmap = cmap_bold2) plt.scatter(true_centroid[:,0],true_centroid[:,1],marker = 'o',s = 200, edgecolors = 'k',c = [0,2,1],cmap = cmap_light) plt.xlabel('sepal length(cm)') plt.ylabel('sepal width(cm)') plt.title('True Class') plt.show()
小结:估计器都有 fit() 方法,预测器都有 predict() 和 score() 方法,言外之意不是每个预测器都有 predict_proba() 和 decision_function() 方法,这个在用的时候查查官方文档就清楚了 (比如 RandomForestClassifier 就没有 decision_function() 方法)。
四、转换器
两大类转换器
-
将分类型变量 (categorical) 编码成数值型变量 (numerical)
-
规范化 (normalize) 或标准化 (standardize) 数值型变量
1.1 LabelEncoder & OrdinalEncoder
LabelEncoder
和 OrdinalEncoder 都可以将字符转成数字,但是
-
LabelEncoder
的输入是一维,比如 1d ndarray -
OrdinalEncoder 的输入是二维,比如 DataFrame
#变量编码 from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import OrdinalEncoder enc = ['win','draw','lose','win'] dec = ['draw','draw','win'] LE = LabelEncoder() print(LE.fit(enc)) print(LE.classes_) print(LE.transform(dec)) OE = OrdinalEncoder() enc_df = pd.DataFrame(enc) dec_df = pd.DataFrame(dec) print(OE.fit(enc_df)) print(OE.categories_) print(OE.transform(dec_df))
上面这种编码的问题是,机器学习算法会认为两个临近的值比两个疏远的值要更相似。显然这样不对 (比如,0 和 1 比 0 和 2 距离更近,难道 draw 和 win 比 draw 和 lose更相似?)。
1.2 OneHotEncoder,
转换器 OneHotEncoder 可以接受两种类型的输入:
-
用 LabelEncoder 编码好的一维数组
-
DataFrame
##one-hot编码 ##使用labelencoder的结果作为输入 from sklearn.preprocessing import OneHotEncoder OHE = OneHotEncoder() num = LE.fit_transform(enc) print(num) OHE_y = OHE.fit_transform(num.reshape(-1,1)) OHE_y ##稀疏矩阵 OHE_y.toarray() ##转换成矩阵 ##使用dataframe作为输入 OHE.fit_transform(enc_df).toarray()
2.1 标准化 (standardization)
每个维度的特征减去该特征均值,除以该维度的标准差。唯一需要注意的就是输入 X 要求是两维。
##标准化 from sklearn.preprocessing import MinMaxScaler X = np.array( [0, 0.5, 1, 1.5, 2, 100] ) #X.reshape(-1,1) ##将X转换成二维数组 #X[:,np.newaxis] ##将X转换成二维数组 X_scale = MinMaxScaler().fit_transform(X.reshape(-1,1)) ##reshape 将一维数组转化成二维数组 X_scale
2.2 规范化 (normalization)
每个维度的特征减去该特征最小值,除以该特征的最大值与最小值之差。
##规范化 from sklearn.preprocessing import StandardScaler X_stand = StandardScaler().fit_transform(X.reshape(-1,1)) X_stand
五、高级API
Sklearn 里核心 API 接口是估计器,那高级 API 接口就是元估计器 (meta-estimator),即由很多基估计器 (base estimator) 组合成的估计器。
本节讨论五大元估计器,分别带集成功能的 ensemble,多分类和多标签的 multiclass,多输出的 multioutput,选择模型的 model_selection,和流水线的 pipeline。
5.1 Ensemble 估计器
分类器统计每个子分类器的预测类别数,再用「多数投票」原则得到最终预测。回归器计算每个子回归器的预测平均值。最常用的 Ensemble 估计器排列如下:
-
AdaBoostClassifier
: 逐步提升分类器 -
AdaBoostRegressor
: 逐步提升回归器 -
BaggingClassifier
: 装袋分类器 -
BaggingRegressor
: 装袋回归器 -
GradientBoostingClassifier
: 梯度提升分类器 -
GradientBoostingRegressor
: 梯度提升回归器 -
RandomForestClassifier
: 随机森林分类器 -
RandomForestRegressor
: 随机森林回归器 -
VotingClassifier
: 投票分类器 -
VotingRegressor
: 投票回归器
5.1.1随机森林分类器
##ensemble ##随机森林(同质估计器:估计器是相同的) from sklearn.ensemble import RandomForestClassifier RF = RandomForestClassifier(n_estimators = 4,max_depth = 5) #由4个决策树组成,树的最大深度是5 rf = RF.fit(x_train,y_train) print(rf.n_estimators) ##估计器的个数 rf.estimators_ #输出各个估计器本身 rf.predict(x_test) print('RF_accuracy(train):%.4g'% metrics.accuracy_score(y_train,RF.predict(x_train))) print('RF_accuracy(test):%.4g'% metrics.accuracy_score(y_test,RF.predict(x_test)))
5.1.2 VotingClassifier
和随机森林由同质分类器「决策树」不同,投票分类器由若干个异质分类器组成。下例用 VotingClassifier 建立个含有对率回归 (LR)、随机森林 (RF) 和高斯朴素贝叶斯 (GNB) 三个分类器的集成模型。
RandomForestClassifier 的基分类器只能是决策树,因此只用通过控制 n_estimators 超参数来决定树的个数,而 VotingClassifier 的基分类器要实实在在的输入其本身。
##VotingClassifier from sklearn.linear_model import LogisticRegression from sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifier,VotingClassifier LR = LogisticRegression(solver = 'lbfgs',multi_class = 'multinomial') ##lbfgs:表示优化算法选择拟牛顿法,multi——class = multiclass表示多对多,默认为ovr(one vs rest) RF = RandomForestClassifier(n_estimators = 5) GNB = GaussianNB() Ensemble = VotingClassifier(estimators = [('lr',LR),('rf',RF),('gnb',GNB)], voting = 'hard') Ensemble.fit(x_train,y_train) Ensemble.predict(x_test) print('RF_accuracy(train):%.4g'% metrics.accuracy_score(y_train,Ensemble.predict(x_train))) print('RF_accuracy(test):%.4g'% metrics.accuracy_score(y_test,Ensemble.predict(x_test)))
5.2 Multiclass 估计器
sklearn.multiclass 可以处理多类别 (multi-class) 的多标签 (multi-label) 的分类问题。
将二分类推广至多分类
多对多 转成一对一 (One vs One, OvO):假设有n个类,从n个类中随机抽取两个进行二分类,需要训练n(n-1)/2个分类器。
##多分类 估计器 multiclass ##onevsoneclassifier from sklearn.datasets import load_digits from sklearn.model_selection import train_test_split from sklearn import metrics from sklearn.multiclass import OneVsOneClassifier from sklearn.linear_model import LogisticRegression import matplotlib.pyplot as plt digits = load_digits() digits.keys() x_train,x_test,y_train,y_test = train_test_split(digits.data, digits.target,test_size = 0.2) print('the size of x_train is:',x_train.shape) print('the size of y_train is:',y_train.shape) print('the size of x_test is:',x_test.shape) print('the size of y_test is:',y_test.shape) fig,axes = plt.subplots(10,10,figsize =(8,8)) fig.subplots_adjust(hspace = 0.1,wspace = 0.1) for i,ax in enumerate(axes.flat): ax.imshow(x_train[i,:].reshape(8,8),cmap = 'binary',interpolation = 'nearest') ax.text(0.05,0.05,str(y_train[i]), transform = ax.transAxes,color = 'blue') ax.set_xticks([]) ax.set_yticks([]) ovo_lr = OneVsOneClassifier(LogisticRegression(solver = 'lbfgs',max_iter = 200)) ovo_lr.fit(x_train,y_train) print(len(ovo_lr.estimators_)) ##有10*9/2=45个分类器 print('the accuracy of ovo_lr is:%.4f'% metrics.accuracy_score(y_test, ovo_lr.predict(x_test)))
一对其他 (One vs rest, OvA):训练 10 个二分类器(逻辑回归、svm、gnb),每一个对应一个数字,第一个分类 1 和「非1」,第二个分类 2 和「非2」,以此类推。N 个类需要 N 个分类器。
##onevsrestclassifier from sklearn.multiclass import OneVsRestClassifier ovr_lr = OneVsRestClassifier(LogisticRegression(solver = 'lbfgs',max_iter = 800)) ovr_lr.fit(x_train,y_train) print(len(ovr_lr.estimators_)) ##有十个分类器 print('the accuracy of ovr_lr is:%0.4f'% metrics.accuracy_score(y_test,ovr_lr.predict(x_test)))
5.3 多分类标签
MultiOutputRegression 估计器
-
MultiOutputRegressor
: 多输出回归 -
MultiOutputClassifier
: 多输出分类
##Multioutput 估计器 #MultiOutputRegressor: 多输出回归 #MultiOutputClassifier: 多输出分类 ##多分类标签数据集介绍 from sklearn.multiclass import OneVsRestClassifier import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import load_digits digits = load_digits() digits.keys() x_train,x_test,y_train,y_test = train_test_split(digits.data, digits.target,test_size = 0.2) ##构建多标签 y_train_multilabel = np.c_[y_train%2==0, y_train<=4] ##c_表示将两个数组整合到一起 print(y_train_multilabel) ova_ml = OneVsRestClassifier(LogisticRegression(solver = 'lbfgs',max_iter = 800)) ova_ml.fit(x_train,y_train_multilabel) print(len(ova_ml.estimators_)) ova_ml.estimators_ ##将测试集展示出来 fig,axes = plt.subplots(10,10,figsize = (8,8)) fig.subplots_adjust(hspace = 0.1,wspace = 0.1) for i,ax in enumerate(axes.flat): ax.imshow(x_test[i,:].reshape(8,8),cmap = 'binary',interpolation = 'nearest') ax.text(0.05,0.05,str(y_test[i]), transform = ax.transAxes,color = 'blue') ax.set_xticks([]) ax.set_yticks([]) print(y_test[:1]) print(ova_ml.predict(x_test[:1,:])) #预测 #在手写数字的例子上,我们也为特意每个数字设计了多标签而且每个标签的类别都大于二。 #标签 1 - 小于等于 4,4 和 7 之间,大于等于 7 (三类) #标签 2 - 数字本身 (十类) from sklearn.multioutput import MultiOutputClassifier from sklearn.ensemble import RandomForestClassifier y_train_1st = y_train.copy() y_train_1st[y_train <= 4] = 0 y_train_1st[np.logical_and(y_train>4,y_train <7)] = 1 y_train_1st[y_train >= 7] = 2 y_train_multioutput = np.c_[y_train_1st,y_train] y_train_multioutput MO = MultiOutputClassifier((RandomForestClassifier()(n_estimators =100))) MO.fit(x_train,y_train_multioutput) MO.predict(x_test[:5,:1])
5.4 Model Selection 估计器 ---模型评价
-
cross_validate
: 评估交叉验证的表现。 -
learning_curve
: 建立学习曲线。 -
GridSearchCV
: 用交叉验证从网格中一组超参数搜索出最佳超参数。 -
RandomizedSearchCV
: 用交叉验证从一组随机超参数搜索出最佳超参数。