sklearn基本使用

通用学习模式

import numpy as np
from sklearn import datasets #用sklearn自带的数据库学习
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier #从sklearn中导入kNN分类器

iris = datasets.load_iris()#导入这种花的数据信息
iris_x = iris.data #将属性全都存在iris_x里面
iris_y = iris.target #将所有的分类存放在iris_y里面

print(iris_x[:5,:])
print(iris_y)  #查看iris数据里面的属性和分类信息
x_train,x_test,y_train,y_test = train_test_split(iris_x,iris_y,test_size = 0.3)
#将总的数据分开成训练集和测试集,测试比例占0.3
#x_test,y_test占了0.3的数据

print(y_train)#可以看出这个时候的y_train已经是打乱的,占总数据的0.7


knn = KNeighborsClassifier() #定义用sklearn中哪一个模型
knn.fit(x_train,y_train) #自动把训练数据进行训练
result = knn.predict(x_test) #用训练好的模型去预测测试集的数据分类结果

#打印预测结果和真实结果最对比
print(result)
print(y_test) 

sklearn的datasets数据库

sklearn自带的数据库:
https://scikit-learn.org/stable/modules/classes.html#module-sklearn.datasets
打开数据会有该数据的特征数,大小等信息

from sklearn import datasets
from sklearn.linear_model import LinearRegression #从sklearn导入LinearRegression模型

loaded_data = datasets.load_boston()
data_X = loaded_data.data #数据
data_y = loaded_data.target #结果

model = LinearRegression() #建立模型
model.fit(data_X,data_y) #训练模型

print(model.predict(data_X[:4,:])) #用data_X的前四条数据放进训练好的模型中算一下结果
print(data_y[:4]) #打印出前四条数据的真实结果,与上述预测结果进行对比

[30.00384338 25.02556238 30.56759672 28.60703649]
[24. 21.6 34.7 33.4]
这里我们可以看出预测结果与真实结果存在差距,所以在精确度上需要做很多别的工作
你得挑选合适的model,不同的参数,改变data的处理方式等

如何创造一些数据进行学习呢

from sklearn import datasets
import matplotlib.pyplot as plt


#创造100个sample,有一个属性和一个target,noise的大小决定数据点的离散程度
X1,y1 = datasets.make_regression(n_samples = 100,n_features = 1,n_targets = 1,noise = 1)
plt.subplot(121)
plt.title('noise = 1')
plt.scatter(X1,y1) #用point的形式输出结果


X2,y2 = datasets.make_regression(n_samples = 100,n_features = 1,n_targets = 1,noise = 10)
plt.subplot(122)
plt.title('noise = 10')
plt.scatter(X2,y2) #用point的形式输出结果
plt.show()

在这里插入图片描述

model的常用属性和功能

from sklearn import datasets
from sklearn.linear_model import LinearRegression #从sklearn导入LinearRegression模型

loaded_data = datasets.load_boston()
data_X = loaded_data.data
data_y = loaded_data.target

model = LinearRegression() #建立模型
model.fit(data_X,data_y) #训练数据

print(model.predict(data_X[:4,:]))
#model的属性输出
print(model.coef_) #y = wx + b .coef_输出的是w
print(model.intercept_)#.intercept输出的是b
print(model.get_params) #返回定义的参数
print(model.score(data_X,data_y)) #对data_X做预测,同data_y进行对比,进行打分

[-1.08011358e-01 4.64204584e-02 2.05586264e-02 2.68673382e+00
-1.77666112e+01 3.80986521e+00 6.92224640e-04 -1.47556685e+00
3.06049479e-01 -1.23345939e-02 -9.52747232e-01 9.31168327e-03
-5.24758378e-01] 这是w向量
36.45948838509001 这是b
<bound method BaseEstimator.get_params of LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
normalize=False)> 参数
0.7406426641094094 打分

标准化数据normalization

from sklearn import preprocessing
import numpy as np

a = np.array([[10,2.7,3.6],
              [-100,5,-2],
              [120,20,40]])

print(a)
print(preprocessing.scale(a))

[[ 10. 2.7 3.6]
[-100. 5. -2. ]
[ 120. 20. 40. ]]
preprocessing.scale之后,将每列进行处理
scaled之后的数据零均值,单位方差
[[ 0. -0.85170713 -0.55138018]
[-1.22474487 -0.55187146 -0.852133 ]
[ 1.22474487 1.40357859 1.40351318]]

b = preprocessing.scale(a)
print(b.mean(axis = 0))
print(b.std(axis = 0))

[0.00000000e+00 1.48029737e-16 0.00000000e+00] 均值为0
[1. 1. 1.] 方差为1

from sklearn import preprocessing
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets.samples_generator import make_classification
from sklearn.svm import SVC
import matplotlib.pyplot as plt

X,y = make_classification(n_samples = 300,n_features = 2,n_redundant = 0,
                          n_informative = 2,random_state = 22,n_clusters_per_class = 1,
                          scale = 100)
#生成一个大小为300的数据,有两个属性,有两个是相关的属性,每一次运行时产生的data是一样的

plt.scatter(X[:,0],X[:,1],c = y)
plt.show() #查看数据结构

在这里插入图片描述

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3)

clf = SVC() #建立SVC模型
clf.fit(X_train,y_train) #训练模型
print(clf.score(X_test,y_test))#将用X_test预测出来的target预y_test作比较得到的分数

如果用原数据,不做scale处理,那么算出来的分数是:0.5666666666666667

#对数据进行预处理
X2 = preprocessing.scale(X)#将X数据压缩到负的一点几到正的一点几
X_train,X_test,y_train,y_test = train_test_split(X2,y,test_size = 0.3)

clf = SVC() #建立SVC模型
clf.fit(X_train,y_train) #训练模型
print(clf.score(X_test,y_test))#将用X_test预测出来的target预y_test作比较得到的分数

对数据进行scale处理后,用于模型训练得到的分数:0.9444444444444444,显然分数提高了很多

此外,除了scale,我们也可以用minmax_scale():

X1 = preprocessing.minmax_scale(X,feature_range = (-1,1))#将X范围压缩到(-1,1)的范围

是训练数据限定在指定范围内

所以如果属性之间的取值范围非常悬殊的话,对模型训练的准确性是会有影响的,normalization变得尤为重要

交叉验证cross validation

我们先来按照普通的分发一部分训练集,一部分测试机这样分,然后算出这样分之后用knn模型算出的分数:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
X = iris.data
y = iris.target

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2)
knn = KNeighborsClassifier(n_neighbors = 5) #k近邻中取最近的5个点
knn.fit(X_train,y_train)
y_pred = knn.predict(X_test)
print(y_pred)
print(knn.score(X_test,y_test))

分数是:0.9666666666666667

然后我们试图按照下面的测试集分发,分五次,然后对每次的结果求取平均值,这样是否会提高一些精度呢?
在这里插入图片描述

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
X = iris.data
y = iris.target

from sklearn.model_selection import cross_val_score
knn = KNeighborsClassifier(n_neighbors = 5) #k近邻中取最近的5个点
scores = cross_val_score(knn,X,y,cv = 5,scoring = 'accuracy')
#用knn,测试数据X,y被自动分成五组,每一组的训练数据和测试数据是不一样的,每组得分也不一样
print(scores)

[0.96666667 1. 0.93333333 0.96666667 1. ]
五组的测试分数得到了,有两组居然是1,这显然不能作为得分来衡量所以需要平均一下:

print(scores.mean())

0.9733333333333334,那么这个分数的可靠度就比较高了

那么问题来了,参数n_neighbors的改变会不会对精确度造成影响呢

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
X = iris.data
y = iris.target

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
k_range = range(1,31)#从1到30取值
k_scores = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors = k) #k近邻中取最近的5个点
    scores = cross_val_score(knn,X,y,cv = 10,scoring = 'accuracy')
    #用knn,测试数据X,y被自动分成十组,每一组的训练数据和测试数据是不一样的,每组得分也不一样
    k_scores.append(scores.mean())


plt.plot(k_range,k_scores)
plt.xlabel('Value of K for KNN')
plt.ylabel('Cross-Validated Accuracy')
plt.show()

可以算出不同n_neighbors参数对模型得分的影响
在这里插入图片描述
从图中可以看出n_neighbors太大了也会出现过拟合,准确度下降,overfitting
注意这里做classification的问题用scores来衡量得分标准,如果是做回归问题,regression的衡量要用loss函数:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
X = iris.data
y = iris.target

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
k_range = range(1,31)#从1到30取值
k_scores = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors = k) #k近邻中取最近的5个点
    loss = -cross_val_score(knn,X,y,cv = 10,scoring = 'neg_mean_squared_error')
    #用knn,测试数据X,y被自动分成十组,每一组的训练数据和测试数据是不一样的,每组得分也不一样
    k_scores.append(loss.mean())


plt.plot(k_range,k_scores)
plt.xlabel('Value of K for KNN')
plt.ylabel('Cross-Validated Accuracy')
plt.show()

在这里插入图片描述
loss对应的值越小,则说明模型越精确

 scores = cross_val_score(knn,X,y,cv = 10,scoring = 'accuracy')
 loss = -cross_val_score(knn,X,y,cv = 10,scoring = 'neg_mean_squared_error')

overfitting问题

from sklearn.model_selection import learning_curve #用来可视化整个学习的过程
from sklearn.datasets import load_digits #数字data
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

digits = load_digits()
X = digits.data
y = digits.target

train_sizes,train_loss,test_loss = learning_curve(SVC(gamma = 0.001),X,y,cv = 10,
                                                  scoring = 'neg_mean_squared_error',
                                                  train_sizes = [0.1,0.25,0.5,0.75,1])

#learning_curve输出的是training data数据大小,loss随时间变化的数值,还有test data的loss
#更改model的参数为0.001
#将整个data分成了十组进行测试,计算这十次的分数
#图像上会标记上五个点,当training data数据量分别为[0.1,0.25,0.5,0.75,1]时,test_loss的变化
train_loss_mean = -np.mean(train_loss,axis = 1)
test_loss_mean = -np.mean(test_loss,axis = 1)


plt.plot(train_sizes,train_loss_mean,'o-',color = 'r',label = 'Training')
plt.plot(train_sizes,test_loss_mean,'o-',color = 'g',label = 'Cross-validation')

plt.xlabel('Training examples')
plt.ylabel('Loss')
plt.legend(loc = 'best')
plt.show()

在这里插入图片描述
试图改变gamma的值为0.01:

from sklearn.model_selection import learning_curve #用来可视化整个学习的过程
from sklearn.datasets import load_digits #数字data
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

digits = load_digits()
X = digits.data
y = digits.target

train_sizes,train_loss,test_loss = learning_curve(SVC(gamma = 0.1),X,y,cv = 10,
                                                  scoring = 'neg_mean_squared_error',
                                                  train_sizes = [0.1,0.25,0.5,0.75,1])

#learning_curve输出的是training data数据大小,loss随时间变化的数值,还有test data的loss
#更改model的参数为0.1
#将整个data分成了十组进行测试,计算这十次的分数
#图像上会标记上五个点,当training data数据量分别为[0.1,0.25,0.5,0.75,1]时,test_loss的变化
train_loss_mean = -np.mean(train_loss,axis = 1)
test_loss_mean = -np.mean(test_loss,axis = 1)


plt.plot(train_sizes,train_loss_mean,'o-',color = 'r',label = 'Training')
plt.plot(train_sizes,test_loss_mean,'o-',color = 'g',label = 'Cross-validation')

plt.xlabel('Training examples')
plt.ylabel('Loss')
plt.legend(loc = 'best')
plt.show()

我们发现test_loss的值到后来就下不来了,这就是overfitting
在这里插入图片描述
如何选model中的参数,如svc中的gamma选什么时候比较好

from sklearn.model_selection import validation_curve
from sklearn.datasets import load_digits #数字data
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

digits = load_digits()
X = digits.data
y = digits.target
param_range = np.logspace(-6,-2.3,5)#参数取log的-6到-2.3进行变化,取中间五个点进行拟合

train_loss,test_loss = validation_curve(SVC(),X,y,param_name = 'gamma',
                                                  param_range = param_range,cv = 10,
                                                  scoring = 'neg_mean_squared_error')
#改变一个参数,参数名是gamma,参数变化范围是param_range
#learning_curve输出的是training data数据大小,loss随时间变化的数值,还有test data的loss
#更改model的参数为0.1
#将整个data分成了十组进行测试,计算这十次的分数
#validation_curve没有train_sizes这个参数
train_loss_mean = -np.mean(train_loss,axis = 1)
test_loss_mean = -np.mean(test_loss,axis = 1)


plt.plot(param_range,train_loss_mean,'o-',color = 'r',label = 'Training')
plt.plot(param_range,test_loss_mean,'o-',color = 'g',label = 'Cross-validation')

plt.xlabel('gamma')
plt.ylabel('Loss')
plt.legend(loc = 'best')
plt.show()

这里画出随着gamma变化时,train_loss和test_loss的变化:
在这里插入图片描述
可以发现gamma取0.0005到0.001之间是最好的,之后gamma增大,test_loss会变大,这是典型的overfitting

存储模型

训练好的模型可以进行存储,下次有测试数据就可以直接使用了

pickle方法

from sklearn import svm
from sklearn import datasets

clf = svm.SVC()
iris = datasets.load_iris()
X,y = iris.data,iris.target
clf.fit(X,y)

#保存
#method 1:pickle
import pickle
with open('D:/python/workspace/clf.pickle','wb')as f: #python路径要用反斜杠
    pickle.dump(clf,f) #将模型dump进f里面

这个时候在路径下面就会有一个.pickle的文件,存储的就是训练好的clf模型

提取模型的时候:

import pickle
from sklearn import datasets

iris = datasets.load_iris()
X,y = iris.data,iris.target

with open('D:/python/workspace/clf.pickle','rb') as f:
    clf2 = pickle.load(f)#从f文件中提取出模型赋给clf2
    print(clf2.predict(X))

输出预测值,说明原来的模型已经被提取出来了
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]

joblib方法

from sklearn import svm
from sklearn import datasets

clf = svm.SVC()
iris = datasets.load_iris()
X,y = iris.data,iris.target
clf.fit(X,y)

#保存
#method 2:joblib
from sklearn.externals import joblib #joblib是sklearn的一个外部模块
joblib.dump(clf,'D:/python/workspace/clf.pkl') #将clf存入.pkl的文件中

在这里插入图片描述
提取模型的时候:

from sklearn.externals import joblib
from sklearn import datasets


iris = datasets.load_iris()
X,y = iris.data,iris.target


clf3 = joblib.load('D:/python/workspace/clf.pkl')
print(clf3.predict(X))

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]模型已提取并已经可以用于预测分类

在处理大量数据的时候joblib的窗户里速度会比pickle更加快一点

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值