首页 > 编程 > Python > 正文

python之机器学习库scikit-learn

2019-11-09 14:34:04
字体:
来源:转载
供稿:网友

一、 加载sklearn中的数据集datasets

from sklearn import datasetsiris = datasets.load_iris() # 鸢尾花卉数据digits = datasets.load_digits() # 手写数字8x8像素信息数据查看数据的信息PRint iris.data[:4] # 查看数据的特征信息print iris.data.shape # 查看数据的特征信息维度print iris.target_names # 查看标签对应的文本print iris.target[:4] # 查看数据的标签 setosa:0 ...[[ 5.1 3.5 1.4 0.2] [ 4.9 3. 1.4 0.2] [ 4.7 3.2 1.3 0.2] [ 4.6 3.1 1.5 0.2]](150L, 4L)['setosa' 'versicolor' 'virginica'][0 0 0 0]print digits.data[0]print digits.data.shapeprint digits.target[0]print digits.data[0].reshape((8,8)) # 重塑成8x8的像素数组[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0. 0. 3. 15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0. 0. 5. 8. 0. 0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0. 0. 2. 14. 5. 10. 12. 0. 0. 0. 0. 6. 13. 10. 0. 0. 0.](1797L, 64L)0[[ 0. 0. 5. 13. 9. 1. 0. 0.] [ 0. 0. 13. 15. 10. 15. 5. 0.] [ 0. 3. 15. 2. 0. 11. 8. 0.] [ 0. 4. 12. 0. 0. 8. 8. 0.] [ 0. 5. 8. 0. 0. 9. 8. 0.] [ 0. 4. 11. 0. 1. 12. 7. 0.] [ 0. 2. 14. 5. 10. 12. 0. 0.] [ 0. 0. 6. 13. 10. 0. 0. 0.]]

二、训练集和分割集的分割

from sklearn.model_selection import train_test_splitX = digits.data # 特征矩阵y = digits.target # 标签向量# 随机分割训练集和测试集:# test_size:设置测试集的比例。random_state:可理解为种子,保证随机唯一X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3., random_state=8) print X_train.shapeprint X_test.shape(1198L, 64L)(599L, 64L)

三、特征数值的归一化

当特征的数值范围差距较大时,需要对特征的数值进行归一化,防止某些属性的权重过大。(有时不需特征归一化)

from sklearn import preprocessingimport numpy as npx1 = np.random.randint(0,10,1000).reshape((1000,1))x2 = np.random.randint(0,100,1000).reshape((1000,1))x3 = np.random.randint(0,10000,1000).reshape((1000,1))X = np.concatenate([x1,x2,x3],axis=1)print X[:4][[ 0 78 3423] [ 7 35 963] [ 7 63 9945] [ 3 60 6516]]# 特征数值归一化print preprocessing.scale(X)[:4][[-1.59232736 0.96948157 -0.56718281] [ 0.83236081 -0.55950092 -1.40672255] [ 0.83236081 0.43611559 1.65862133] [-0.55317529 0.32944239 0.48838484]验证归一化的重要性# 生成分类数据进行验证from sklearn import datasetsimport matplotlib.pyplot as plt%matplotlib inline# 生成分类数据:# n_sample:样本个数、n_features:类别标签种类数X, y = datasets.make_classification(n_samples=300, n_features=2, n_redundant=0, n_informative=2, random_state=25, n_clusters_per_class=1, scale=100)plt.scatter(X[:,0], X[:,1], c=y)plt.show()

这里写图片描述

使用svm模型(未特征归一化时)# 使用svm模型(未特征归一化时)from sklearn import svm# X = preprocessing.scale(X)# 分割训练集合测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3., random_state=7) svm_classifier = svm.SVC()# 训练模型svm_classifier.fit(X_train, y_train)# 在测试集上对模型打分svm_classifier.score(X_test, y_test)0.52000000000000002使用svm模型(特征归一化时)# 使用svm模型(特征归一化时)from sklearn import svmX = preprocessing.scale(X)# 分割训练集合测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3., random_state=7) svm_classifier = svm.SVC()svm_classifier.fit(X_train, y_train)svm_classifier.score(X_test, y_test)0.97999999999999998

四、模型的训练、预测与保存

以线性回归模型为例iris = datasets.load_iris() # 鸢尾花卉数据X = iris.datay = iris.targetprint X[:3]print y[:3][[ 5.1 3.5 1.4 0.2] [ 4.9 3. 1.4 0.2] [ 4.7 3.2 1.3 0.2]][0 0 0]# 选择线性回归模型from sklearn.linear_model import LinearRegression# 新建一个模型(参数默认)iris_model = LinearRegression()# 分割训练集、测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3., random_state=7) # 训练该模型iris_model.fit(X_train,y_train)# 返回模型参数列表iris_model.get_params(){'copy_X': True, 'fit_intercept': True, 'n_jobs': 1, 'normalize': False}# 模型在训练集上的评分iris_model.score(X_train, y_train)0.94505820275667418# 模型在测试集上的评分iris_model.score(X_test, y_test)0.89618390663189063# 使用模型进行预测y_pred = iris_model.predict(X_test)print '预测标签:', y_pred[:3]print '真实标签:', y_test[:3]预测标签: [ 1.66080893 1.39414184 -0.02450645]真实标签: [2 1 0]# 使用pickle保存模型import cPickle as picklewith open('LR_model.pkl', 'w') as f: pickle.dump(iris_model, f)# 重新加载模型进行预测with open('LR_model.pkl', 'r') as f: model = pickle.load(f)# 使用模型进行预测model.predict(X_test)[:3]array([ 1.66080893, 1.39414184, -0.02450645])

五、交叉验证

在分割训练集和测试集后,测试集一般用于对最后选择的模型进行评分。而在选择模型的超参数的过程中,为验证/评价模型的好坏,需要在训练集中取出一定比例的样本作为验证集来评价某个模型的好坏,训练集中的其他样本用来训练模型。

为消除所选出来的验证集中的样本的特殊性,则需要将训练集中的每一份样本作为验证集,其他样本作为训练集来训练模型。若将训练集中的样本分为N分,最后会得到N个对该模型的评分,对这些评分取均值,即得到了交叉验证的评分。

交叉验证一般用来调整模型的超参数。

sklearn中的交叉验证

cross_val_score函数用于交叉验证,返回各个验证集的评价得分。

from sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom sklearn.model_selection import cross_val_scoreimport matplotlib.pyplot as plt%matplotlib inlineiris = datasets.load_iris()X = iris.datay = iris.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3., random_state=5)以KNN模型为例# 使用KNN模型进行预测(K为超参数)from sklearn.neighbors import KNeighborsClassifier# 超参数K的范围k_range = range(1,31)# 交叉验证的评分集合cv_scores = []for k in k_range: knn = KNeighborsClassifier(k) # 构造模型 # 将训练集均分为10份 #cv: 交叉验证迭代器 scores = cross_val_score(knn, X_train, y_train, cv=10, scoring='accuracy') # 分类问题使用 #scores = cross_val_score(knn, X_train, y_train, cv=10, scoring='neg_mean_squared_error') # 回归问题使用 cv_scores.append(scores.mean()) # # print cv_scores# 可视化各个k值模型的交叉验证的平均分plt.plot(k_range,cv_scores)plt.xlabel('k')plt.ylabel('Accuracy')plt.show()

这里写图片描述

# 选择最优的超参数Kbest_knn = KNeighborsClassifier(15)best_knn.fit(X_train, y_train)print best_knn.score(X_test, y_test)print best_knn.predict(X_test)1.0[1 2 2 0 2 1 0 1 0 1 1 2 2 2 0 0 2 2 0 0 1 2 0 1 1 2 1 1 1 2 0 1 1 0 1 0 0 2 0 2 2 1 0 0 1 2 1 2 2 0]

六、过拟合与欠拟合

过拟合:模型对于训练集数据拟合程度过当,以致太适合训练集数据而无法适应一般情况。即训练出来的模型在训练集上表现很好,在验证集/测试集上表现并不好。

欠拟合:模型在训练集/测试集上都表现得不是很好。

# 加载数据from sklearn.model_selection import learning_curvefrom sklearn.svm import SVCimport numpy as npdigits = datasets.load_digits()X = digits.datay = digits.target欠拟合情况# 绘制学习曲线(学习曲线:在不同训练数据量下对训练出来的模型进行评分)# gamma = 0.001train_sizes, train_scores, val_scores = learning_curve( SVC(gamma=0.001), X, y, cv=10, scoring='accuracy', train_sizes=[0.1, 0.25, 0.5, 0.75, 1])# train_sizes: 每次模型训练的数量# train_scores: 每次模型在训练集上的评分# val_scores:每次模型在验证集上的交叉验证评分# 求不同训练数据量下的评分的均值train_scores_mean = np.mean(train_scores, axis=1) # 行均值val_scores_mean = np.mean(val_scores, axis=1)# 绘制学习曲线plt.plot(train_sizes, train_scores_mean, 'o-', color='r', label='training')plt.plot(train_sizes, val_scores_mean, '*-', color='g', label='cross validation')plt.xlabel('training sample size')plt.ylabel('accuracy')plt.legend(loc='best')plt.show()

这里写图片描述

如图所示:当训练数据量较少时,模型在交叉验证中的得分较低,可看作一种欠拟合现象;随着训练数据量的增多,交叉验证的平均分也随之增加过拟合train_sizes, train_scores, val_scores = learning_curve( SVC(gamma=0.1), X, y, cv=10, scoring='accuracy', train_sizes=[0.1, 0.25, 0.5, 0.75, 1] )# 求不同训练数据量下的评分的均值train_scores_mean = np.mean(train_scores, axis=1) # 行均值val_scores_mean = np.mean(val_scores, axis=1)# 绘制学习曲线plt.plot(train_sizes, train_scores_mean, 'o-', color='r', label='training')plt.plot(train_sizes, val_scores_mean, '*-', color='g', label='cross validation')plt.xlabel('training sample size')plt.ylabel('accuracy')plt.legend(loc='best')plt.show()

这里写图片描述

如图所示:当训练数据量较少时,模型在交叉验证中的得分较低;然而,随着训练数据量的增多,交叉验证的平均分并没增多。因此出现过拟合现象。通过验证曲线来观察过拟合# 绘制验证曲线(验证曲线:在不同超参数下对模型的评分)from sklearn.model_selection import validation_curve# 设置SVC模型的超参数gamma的取值范围gamma_range = np.arange(1, 10) / 3000.train_scores, val_scores = validation_curve( SVC(), X, y, param_name='gamma', param_range=gamma_range, cv=5, scoring='accuracy')# train_scores: 每次模型在训练集上的评分# val_scores:每次模型在验证集上的交叉验证评分# 求每次的平均值train_scores_mean = np.mean(train_scores, axis=1)val_scores_mean = np.mean(val_scores, axis=1)# 绘制验证曲线plt.plot(gamma_range, train_scores_mean, 'o-', color='r', label='training')plt.plot(gamma_range, val_scores_mean, '*-', color='g', label='cross validation')plt.xlabel('gamma')plt.ylabel('accuracy')plt.legend(loc='best')plt.show()

这里写图片描述

如图所示:当gamma>0.0015时,出现过拟合现象,对应模型在训练集上的评分不断增大,而在验证集上的评分反而在减小
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表