python学习笔记39:sklearn

from sklearn import datasets
from sklearn.model_selection import train_test_split  # 训练集和测试集
from sklearn.neighbors import KNeighborsClassifier # k-means分类

iris = datasets.load_iris() # 加载数据集
# iris 查看iris数据信息
iris_X = iris.data  # iris出来是一个字典,可以用.的方式获取对应的values
# iris_X
iris_y = iris.target # 目标变量
# iris_y
# 将数据集拆分为训练集和测试集,测试集占30%
X_train,X_test,y_train,y_test = train_test_split(iris_X,iris_y,test_size=0.3)
print(y_test)
[1 0 0 0 2 0 1 1 0 0 1 1 2 1 2 2 0 1 2 1 2 2 0 0 1 1 2 1 2 1 0 0 2 0 1 1 0
 0 1 2 2 0 1 2 2]
knn = KNeighborsClassifier() # 引入实例
knn.fit(X_train,y_train)     # 训练模型
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=None, n_neighbors=5, p=2,
           weights='uniform')
# 测试模型
y_pred = knn.predict(X_test)
y_pred
array([1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 2, 1, 1, 2, 0, 1, 2, 1, 2, 2,
       0, 0, 1, 1, 2, 1, 2, 1, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 2, 0, 1, 2,
       2])
# 把测试结果写会csv
# 生成id
ind = []
for i in range(len(y_pred)):
    ind.append(i+1)
    
import pandas as pd
dic = {'id':ind,'pred':y_pred}
test_pred = pd.DataFrame(dic)
test_pred.to_csv('knn_test_pred.csv',index=False)
%matplotlib inline

sklean 进行数据展示

from sklearn import datasets
X,y = datasets.make_regression(n_samples=100,n_features=1,n_targets=1,noise=1)

import matplotlib.pyplot as plt
plt.figure()
plt.scatter(X,y,marker='.')
plt.show()

sklearn model中的属性

from sklearn import datasets
from sklearn.linear_model import LinearRegression

load_data = datasets.load_boston()
data_X = load_data.data
data_y = load_data.target
print(data_X.shape)
(506, 13)
lr_model = LinearRegression()
lr_model.fit(data_X,data_y)
lr_model.predict(data_X[:4,:])
array([30.00384338, 25.02556238, 30.56759672, 28.60703649])
print(lr_model.coef_) # 拟合直线的系数
print(lr_model.intercept_) # 截距
print(lr_model.get_params) # 参数

[-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]
36.459488385089855
<bound method BaseEstimator.get_params of LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
         normalize=False)>

数据标准化

许多学习算法中目标函数的基础都是假设所有的特征都是零均值并且具有同一阶数上的方差(比如径向基函数,支持向量机以及L1L2正则化项等)。如果某个特征的方差比其他特征大几个数量级,那么他就会在学习算法中占据主导位置,导致学习器对其他特征有所忽略。
标准化先对数据进行中心化,再除以特征的标准差进行缩放。
在sklearn中,我们可以通过Scale将数据缩放,达到标准化的目的。

from sklearn import preprocessing
import numpy as np

data = np.array([[12,92,3],[2,3,4],[3,4,5]],dtype=np.float64)
print('标准化前:',data)
print('标准化后:',preprocessing.scale(data))
标准化前: [[12. 92.  3.]
 [ 2.  3.  4.]
 [ 3.  4.  5.]]
标准化后: [[ 1.4083737   1.41414586 -1.22474487]
 [-0.81537425 -0.71905721  0.        ]
 [-0.59299945 -0.69508864  1.22474487]]
from sklearn import datasets
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

# 生成数据并进行可视化
plt.figure()
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)
plt.scatter(X[:,0],X[:,1],c=y) # X的第0列和第1列画散点图,用y做颜色区分
plt.show()

# 未标准化
X_pre = X
y_pre = y
X_train_pre,X_test_pre,y_train_pre,y_test_pre = train_test_split(X_pre,y_pre,test_size=0.3)
clf = SVC()
clf.fit(X_train_pre,y_train_pre)
clf.score(X_test_pre,y_test_pre)
/Users/zxx/anaconda3/lib/python3.7/site-packages/sklearn/svm/base.py:196: FutureWarning: The default value of gamma will change from 'auto' to 'scale' in version 0.22 to account better for unscaled features. Set gamma explicitly to 'auto' or 'scale' to avoid this warning.
  "avoid this warning.", FutureWarning)





0.4444444444444444
# 标准化
X_pre = preprocessing.minmax_scale(X)
y_pre = y
X_train,X_test,y_train,y_test = train_test_split(X_pre,y_pre,test_size=0.3)
clf = SVC()
clf.fit(X_train,y_train)
clf.score(X_test,y_test)
/Users/zxx/anaconda3/lib/python3.7/site-packages/sklearn/svm/base.py:196: FutureWarning: The default value of gamma will change from 'auto' to 'scale' in version 0.22 to account better for unscaled features. Set gamma explicitly to 'auto' or 'scale' to avoid this warning.
  "avoid this warning.", FutureWarning)





0.9333333333333333

可以看到数据规范化之前模型分数为0.52222,数据规范化之后模型分数为0.91111

交叉验证

交叉验证的思想就是重复的使用数据,把得到的样本数据进行切分,组合成为不同的训练集和验证集,用训练集来训练模型,用验证集评估模型预测的好坏。

(1)简单的交叉验证:

随机的将样本数据分为两部分(如70%训练,30%测试),然后用训练集来训练模型,在验证集上验证模型及参数;接着再把样本打乱,重新选择训练集和验证集,重新训练验证,最后选择损失函数评估最优的模型和参数。

(2)k折交叉验证:

随机将样本数均分为K份,每次随机选择其中的k-1份作为训练集,剩下的1份做验证集。当这一轮完成后,重新随机选择k-1份来训练数据,若干轮后选择损失函数评估最优的模型和参数。

(3)留一交叉验证:

留一交叉验证是k折交叉验证的一种特例,此时k=n(样本的个数),每次选择n-1个样本进行训练,留一个样本进行验证模型的好坏。
这种方法适合样本量非常少的情况。

(4)Boostrapping自助采样法:

这种方法也是随机森林训练样本采用的方法。
在n个样本中随机有放回抽样m个样本作为一颗树的一个训练集,这种采用会大约有1/3的样本不被采到,这些不被采到的样本就会被作为这棵树的验证集。

如果只是对数据做一个初步的模型建立,不需要做深入分析的话,简单的交叉验证就可以了,否则使用k折交叉验证,在样本量很小时,可以选择使用留一法。
总之,所有的东西不是一成不变的,大家在遇到具体问题的时候,可以所有方式都尝试一下,看看效果,根据具体问题选择合适的方法

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier 
from sklearn.model_selection import cross_val_score # 交叉验证

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

# 拆分数据集
# X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3) 使用交叉验证不需要拆分

knn = KNeighborsClassifier(n_neighbors=5)
scores = cross_val_score(knn,X,y,cv=5,scoring='accuracy')
print(scores)
print(scores.mean())

[0.96666667 1.         0.93333333 0.96666667 1.        ]
0.9733333333333334
from sklearn import datasets
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt

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

# 调整模型参数
k_range = range(1,31)
k_score = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn,X,y,cv=5,scoring='accuracy')  # 5折交叉验证
    k_score.append(scores.mean())

plt.figure()
plt.plot(k_range,k_score)
plt.xlabel('value of k for knn')
plt.ylabel('cross accuracy')
plt.show()

另外我们可以选择2-fold cross validation,leave-one-out cross validation等方法来分割数据,比较不同的方法和参数得到最优结果。

8.过拟合问题

过拟合的问题是因为模型过于复杂,对于训练数据能很好的拟合,却不能正确的处理测试数据,从一个角度说就是,学到了一些样本数据一些非通用信息。使得模型的泛化效果非常不好。

#先距离如何辨别overfitting问题
#Sklearn.learning_curve中的learning curve可以直观的看出模型学习的进度,对比发现有没有过拟合。
from sklearn.model_selection import learning_curve # 学习曲线
from sklearn.datasets import load_digits
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

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

# 设置记录点
train_size,train_loss,test_loss = learning_curve(SVC(gamma=0.1),X,y,cv=10,scoring='neg_mean_squared_error',train_sizes = np.arange(0.05,1.05,0.05))
train_loss_mean = -np.mean(train_loss,axis=1)
test_loss_mean = -np.mean(test_loss,axis=1)

# 画图
plt.figure()
plt.plot(train_size,train_loss_mean,'go--',label='Training')
plt.plot(train_size,test_loss_mean,'ro--',label='Cross-validataion')
plt.legend(loc = 'best')
plt.show()



posted @ 2019-09-03 16:17  zheng1076  阅读(1295)  评论(1编辑  收藏  举报