scikit-learn简称sklearn,支持包括分类,回归,降维和聚类四大机器学习算法。还包括了特征提取,数据处理和模型评估者三大模块。
一,sklearn官方文档的内容和结构
1.1 sklearn官方文档的内容
库的算法主要有四类:
- 监督学习的:分类,回归,
- 无监督学习的:聚类,降维。
- 常用的回归:线性、决策树、SVM、KNN
集成回归:随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees- 常用的分类:线性、决策树、SVM、KNN,朴素贝叶斯;集成分类:随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees
- 常用聚类:k均值(K-means)、层次聚类(Hierarchical clustering)、DBSCAN
- 常用降维:LinearDiscriminantAnalysis、PCA
二,sklearn的快速使用
传统的机器学习任务从开始到建模的一般流程就是:获取数据——》数据预处理——》训练模型——》模型评估——》预测,分类。
sklearn共有六大板块,其实sklearn六大板块中有两块都是关于数据预处理和特征工程的,两个板块互相交互,为建模之前的全部工程打下基础。
- 模块preprocessing:几乎包含数据预处理的所有内容
- 模块Impute:填补缺失值专用
- 模块feature_selection:包含特征选择的各种方法的实践
- 模块decomposition:包含降维算法
三,具体介绍sklearn
1,获取数据
补充:什么是X[y==0, 0] ?
X[2,3]就是返回第二行第3列数据
X[:, (2, 3)]冒号代表全部,这句话就是返回所有行的第2列和第3列
X[y==0,3]就是返回满足y为0的那些行中的第三列数据
1.1 导入sklearn数据集
sklearn中包含了大量的优质的数据集
1.1.1 导入鸢尾花数据集
from sklearn import datasets #要使用sklearn中的数据集,必须导入datasets模块
iris = datasets.load_iris() # 导入数据集
X = iris.data # 获得其特征向量
y = iris.target # 获得样本label
方法二:
from sklearn.datasets import load_iris #导入鸢尾花数据集
X, y = load_iris(return_X_y=True)
例题:
from sklearn.datasets import load_iris #导入鸢尾花数据集
iris=load_iris()
print("特征描述名称为:")
print(iris.feature_names)
print("目标描述名为:")
print(iris.target_names)
print("-------------------------------------------------")
iris = load_iris() # 导入数据集
X = iris.data # 获得其特征向量
y = iris.target # 获得样本label
#等价于 X, y = load_iris(return_X_y=True)
print(iris.data[0]) #[ 5.1 3.5 1.4 0.2]相当于X[0]
print(iris.target)#相当于print(y)
print(iris.keys()) #dict_keys(['target', 'DESCR', 'data', 'target_names', 'feature_names'])
print("-------------------------------------------------")
n_samples,n_features=iris.data.shape
print(iris.data.shape) #(150, 4)
print("样本数量:",n_samples) # 150
print("特征数量:",n_features) # 4
print(iris.target.shape) #(150,)
from sklearn.datasets import load_iris #导入鸢尾花数据集
X, y = load_iris(return_X_y=True)
print(X[:10])#输出前十个
print(y[:10])#输出前十个
print(X[y==0,3])
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris=load_iris()#切记iris.data就是X, iris.target就是y
x_index=3
print(iris.target_names) #['setosa' 'versicolor' 'virginica']
color=['blue','red','green']
print(dict(zip( range(len(iris.target_names)) , color )))#{0: 'blue', 1: 'red', 2: 'green'}
print(iris.feature_names)#['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
#当直方图的横坐标选取的研究属性为'petal width (cm)'时,绘制坐标轴时x应当选取X[y=label,3],里面的3就是iris.feature_names[3]
#画直方图plt.hist(x,bins=None,color=None,label=None)
for label,color in zip(range(len(iris.target_names)),color):
plt.hist(iris.data[iris.target==label,x_index],#也就是X[y=label,3]
label=iris.target_names[label],
color=color)
plt.xlabel(iris.feature_names[x_index])
plt.legend(loc="Upper right")
plt.show()
#画散点图,第一维的数据作为x轴和第二维的数据作为y轴
x_index=0
y_index=1
colors=['blue','red','green']
for label,color in zip(range(len(iris.target_names)),colors):
plt.scatter(iris.data[iris.target==label,x_index], #也就是X[y=label,0]
iris.data[iris.target==label,y_index],#也就是X[y=label,1]
label=iris.target_names[label],
c=color)
plt.xlabel(iris.feature_names[x_index])
plt.ylabel(iris.feature_names[y_index])
plt.legend(loc='upper right')
plt.show()
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
data = load_iris()
X = data.data # 150x4的数据[ [6.4 3.1 5.5 1.8] [6. 3. 4.8 1.8] ...]
y = data.target # y=[0 0 0 ...1 1 1..2 2 2]
features = data.feature_names # 4个特征的名称
targets = data.target_names # 3类鸢尾花的名称,跟y中的3个数字对应
plt.figure(figsize=(10, 4))
plt.plot(X[:, 2][y==0], X[:, 3][y==0], 'bs', label=targets[0])
plt.plot(X[:, 2][y==1], X[:, 3][y==1], 'kx', label=targets[1])
plt.plot(X[:, 2][y==2], X[:, 3][y==2], 'ro', label=targets[2])
plt.xlabel(features[2])
plt.ylabel(features[3])
plt.title('Iris Data Set')
plt.legend()
plt.show()
1.1.2 导入手写数字数据集
手写数字数据集包含1797个0-9的手写数字数据,每个数据由8 * 8 大小的矩阵构成,矩阵中值的范围是0-16,代表颜色的深度。
from sklearn.datasets import load_digits
X, y = load_digits(return_X_y=True)
from sklearn.datasets import load_digits
digits=load_digits()
print(digits.data.shape)#(1797, 64)
n_samples,n_features=digits.data.shape
#n_samples=1797,n_features=64,即1797个样本,64个特征量
print(digits.images.shape)#(1797, 8, 8)即1797个图片,每张图片由8 * 8 大小的矩阵构成
输出结果:
(1797, 64)
(1797, 8, 8)
展示如下:
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
digits = load_digits()
plt.matshow(digits.images[25])#展示一下第25幅图片,可以看到就是一个数字5
plt.show()
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
digits=load_digits()
plt.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.05,wspace=0.05)#这个可以不用管,没有也不影响
for i in range(64):
plt.subplot(8,8,i+1,xticks=[],yticks=[])#xticks=[],yticks=[]不显示子图的坐标轴刻度
plt.imshow(digits.images[i],cmap=plt.cm.binary,interpolation='nearest')
#cmap表示绘图时的样式,这里选择的是plt.cm.binary主题。interpolation代表的是插值运算,'nearest'只是选取了其中的一种插值方式。
plt.text(0,7,str(digits.target[i]))#用y值标记图像
plt.show()
1.1.3 导入波士顿房价数据集
from sklearn.datasets import load_boston
boston =load_boston()
print(boston.data.shape) #(506, 13)
n_samples,n_features=boston.data.shape
print("样本数量:",n_samples) # 506
print("特征数量:",n_features) # 13
print(boston.target.shape) #(506,)
2,数据预处理
①数据预处理阶段是机器学习中不可缺少的一环,我们获得的数据中往往存在很多的无用信息,甚至存在错误信息。下面我们来看一下sklearn的数据预处理:
from sklearn import preprocessing
②为了使得训练数据的标准化规则与测试数据的标准化规则同步,preprocessing中提供了很多的Scaler:
- StandardScaler
- MaxAbsScaler
- MinMaxScaler
- RobustScaler
- Normalizer
- 等其他预处理操作
用法是:
from sklearn import preprocessing
xxx=preprocessing.StandardScaler()
xxx=preprocessing.MaxAbsScaler()
③
fit() 用于计算训练数据的均值和方差,后面就会用均值和方差来转换训练数据
transform() 很显然,它只是进行转换,只是把训练数据转换成标准的正态分布。(一般会把train和test集放在一起做标准化,或者在train集上做标准化后,用同样的标准化器去标准化test集,此时可以使用scaler)。
fit_transform() 不仅计算训练数据的均值和方差,还会基于计算出来的均值和方差来转换训练数据,从而把数据转化成标准的正态分布。
用法是:
scaler = preprocessing.StandardScaler().fit(train_data)
scaler.transform(train_data)
等价于:
scaler = preprocessing.StandardScaler().fit_transform(train_data)
- 一般来说先使用fit:
scaler = preocessing.StandardScaler().fit(X)
这一步可以计算得到scaler,scaler里面存的有计算出来的均值和方差。 - 再使用transform:
scaler.transform(X)
这一步再用scaler中的均值和方差来转换X,使X标准化。 - 最后,在预测的时候,也要对数据做同样的标准化处理,即也要用上面的scaler中的均值和方差来对预测时候的特征进行标准化。
2.1 数据标准化
Standardization标准化:将特征数据的分布调整成标准正太分布,也叫高斯分布,也就是使得数据的均值维0,方差为1。标准化的过程为两步:去均值的中心化(均值变为0);方差的规模化(方差变为1)。
①在sklearn.preprocessing中提供了一个scale的方法,可以实现以上功能。
from sklearn import preprocessing
import numpy as np
# 创建一组特征数据,每一行表示一个样本,每一列表示一个特征
x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
# 将每一列特征标准化为标准正太分布,注意,标准化是针对每一列而言的
x_scale = preprocessing.scale(x)
结果:
②preprocessing这个模块还提供了一个实用类StandarScaler,它可以在训练数据集上做了标准转换操作之后,把相同的转换应用到测试训练集中。
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.StandardScaler().fit(train_x)
scaler.transform(train_x)
'''
如果令x=scaler.transform(train_x)
可以得到此时被标准化后的数据是:
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
'''
# 好了,比如现在又来了一组新的样本,也想得到相同的转换
new_x = [[-1., 1., 0.]]
scaler.transform(new_x)
#transform后的new_x为array([[-2.44948974, 1.22474487, -0.26726124]])
③总结StandarScaler的用法:
from sklearn import preprocessing
train_data = [[0, 0], [0, 0], [1, 1], [1, 1]]
scaler = preprocessing.StandardScaler().fit(train_data)
scaler.transform(train_data)
scaler.transform(test_data)
规范到一定区间内,feature_range为数据规范化的范围
from sklearn import preprocessing
train_data = [[0, 0], [0, 0], [1, 1], [1, 1]]
scaler = preprocessing.StandardScaler(feature_range=(0,1)).fit(train_data)
scaler.transform(train_data)
scaler.transform(test_data)
2.2 最小-最大规范化
①MinMaxScaler规模化特征到[0,1]内
为了对付那些标准差相当小的特征并且保留下稀疏数据中的0值,需要将特征规模化到一定的[0,1]范围内。我们用MinMaxScaler
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.MinMaxScaler().fit(train_x)
scaler.transform(train_x)
'''
如果令x=scaler.transform(train_x),然后print(x)
可以得到此时被标准化后的数据是:
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
'''
# 好了,比如现在又来了一组新的样本,也想得到相同的转换
x_test = np.array([[-3., -1., 4.]])
scaler.transform(x_test)
#transform后的new_x为array([[-1.5 , 0. , 1.66666667]])
②MaxAbsScaler规模化特征到[0,1]内
原理与上面的很像,只是数据会被规模化到[-1,1]之间。也就是特征中,所有数据都会除以最大值。这个方法对那些已经中心化均值维0或者稀疏的数据有意义。
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.MaxAbsScaler().fit(train_x)
scaler.transform(train_x)
'''
如果令x=scaler.transform(train_x),然后print(x)
可以得到此时被标准化后的数据是:
array([[ 0.5, -1. , 1. ],
[ 1. , 0. , 0. ],
[ 0. , 1. , -0.5]])
'''
# 好了,比如现在又来了一组新的样本,也想得到相同的转换
x_test = np.array([[-3., -1., 4.]])
scaler.transform(x_test)
#transform后的new_x为array([[-1.5, -1. , 2. ]])
规模化稀疏数据
如果对稀疏数据进行去均值的中心化就会破坏稀疏的数据结构。虽然如此,我们也可以找到方法去对稀疏的输入数据进行转换,特别是那些特征之间的数据规模不一样的数据。
MaxAbsScaler 和 maxabs_scale这两个方法是专门为稀疏数据的规模化所设计的。规模化有异常值的数据
如果你的数据有许多异常值,那么使用数据的均值与方差去做标准化就不行了。
在这里,你可以使用robust_scale 和 RobustScaler这两个方法。它会根据中位数或者四分位数去中心化数据。
2.3 正则化(normalize)
当你想要计算两个样本的相似度时必不可少的一个操作,就是正则化。其思想是:首先求出样本的p范数,然后该样本的所有元素都要除以该范数,这样最终使得每个样本的范数都是1。规范化(Normalization)是将不同变化范围的值映射到相同的固定范围,常见的是[0,1],也成为归一化。
如下例子,将每个样本变换成unit norm。
函数normalize 提供了一个快速有简单的方式在一个单向量上来实现这正则化的功能。正则化有l1,l2等,这些都可以用上:
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.normalize(train_x, norm='l2')
print(scaler)
'''
array[[ 0.40824829 -0.40824829 0.81649658]
[ 1. 0. 0. ]
[ 0. 0.70710678 -0.70710678]]
'''
====================================================================
我们可以发现[ 0.40824829 -0.40824829 0.81649658]中有`0.4^2+0.4^2+0.81^2=1`。
这就是L2 norm
L2 norm,变换后每个样本的各维特征的平方和为1.类似的,
L1 norm则是变换后每个样本的各维特征的绝对值之和为1.
还有max norm,则是将每个样本的各维特征除以该样本各维特征的最大值,
====================================================================
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.normalize(train_x, norm='l1')
print(scaler)
'''
[[ 0.25 -0.25 0.5 ]
[ 1. 0. 0. ]
[ 0. 0.5 -0.5 ]]
'''
====================================================================
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.normalize(train_x, norm='max')
print(scaler)
'''
[[ 0.5 -0.5 1. ]
[ 1. 0. 0. ]
[ 0. 1. -1. ]]
'''
方法二:
preprocessing这个模块还提供了一个实用类Normalizer,实用transform方法同样也可以对新的数据进行同样的转换
from sklearn import preprocessing
import numpy as np
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
scaler = preprocessing.Normalizer().fit(train_x)
scaler.transform(train_x)
'''
如果令x=scaler.transform(train_x),然后print(x)
可以得到此时被标准化后的数据是:
array([[ 0.40824829, -0.40824829, 0.81649658],
[ 1. , 0. , 0. ],
[ 0. , 0.70710678, -0.70710678]])
'''
# 好了,比如现在又来了一组新的样本,也想得到相同的转换
x_test = np.array([[-1., 1., 0.]])
scaler.transform(x_test)
'''
[[-0.70710678 0.70710678 0. ]]
'''
在度量样本之间相似性时,如果使用的是二次型kernel,则需要做Normalization。
2.4 特征二值化(Binarization)
特征的二值化是指将数值型的特征数据转换成布尔类型的值。可以使用实用类Binarizer。
from sklearn import preprocessing
import numpy as np
# 创建一组特征数据,每一行表示一个样本,每一列表示一个特征
train_x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
binarizer = preprocessing.Binarizer().fit(train_x)
binarizer.transform(train_x)
'''
如果令binarizer.transform(train_x),然后print(x)
可以得到此时被标准化后的数据是:
array([[ 1., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.]])
'''
#默认是根据0来二值化,大于0的都标记为1,小于等于0的都标记为0。
#当然也可以自己设置这个阀值,只需给出参数threshold即可。
binarizer = preprocessing.Binarizer(threshold=1.5)
binarizer.transform(train_x)
'''
如果令binarizer.transform(train_x),然后print(x)
array([[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 0., 0.]])
'''
2.5 类别特征编码
== ①one-hot编码==
'''
网上关于One-hot编码的例子都来自于同一个例子,而且结果来的太抖了。查了半天,终于给搞清楚这个独热编码是怎么回事了,其实挺简单的,这里再做个总结。 首先,引出例子:
已知三个feature,三个feature分别取值如下: feature1=[“male”, “female”] feature2=[“from Europe”, “from US”, “from Asia”] feature3=[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]
如果做普通数据处理,那么我们就按0,1,2,3进行编号就行了。例如feature1=[0,1],feature2=[0,1,2],feature3=[0,1,2,3]。 那么,如果某个样本为[“male”,“from Asia”, “uses Chrome”],它就可以表示为[0,2,1]。 以上为普通编码方式。 独热编码(One-hot)换了一种方式编码,先看看百科定义的:
独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。 例如对六个状态进行编码: 自然顺序码为 000,001,010,011,100,101 独热编码则是 000001,000010,000100,001000,010000,100000
通过以上可以看到,独热编码每一个码的总的位数取决于状态的种类数,每一个码里的“1”的位置,就代表了哪个状态生效。 还是回到我们最开始的例子,那么我们将它换成独热编码后,应该是: feature1=[01,10] feature2=[001,010,100] feature3=[0001,0010,0100,1000]
注意,独热编码还有个特性是,当某个特征里的某一状态生效后,此特征的其他状态因为是互斥的关系,必须全部为0,切必须全部添加到特征里,不能省略不写。 所以,对于前边样本[“male”,“from Asia”, “uses Chrome”],经过独热编码后,它应该为: [01,00, 000,000,100, 0000,0010,0000,0000] 。
以上的独热编码可以写成简写形式: [1,0, 0,0,1, 0,1,0,0]
'''
In [2]: import numpy as np
...: from sklearn import preprocessing
...: y = np.array([[1,2,3],[2,5,6]])
...: one_hot_encoder = preprocessing.OneHotEncoder()
...: one_hot_encoder.fit_transform(y).toarray()
...:
Out[2]:
array([[ 1., 0., 1., 0., 1., 0.],
[ 0., 1., 0., 1., 0., 1.]])
y有三个特征:第一个特征的取值为1、2,第二特征的取值为2、5,第三个特征的取值为3、6;可知三个特征的最大特征值分别为2、5、6,每个特征的取值都必须在range(n_values[i])范围内,因此n_values=[3,6,7]
n_values_属性:就是取每个特征的最大特征值+1
In [3]: one_hot_encoder.n_values_
Out[3]: array([3, 6, 7])
feature_indices_属性:就是n_values_的累计
(n_values=[3, 6, 7]中,0=0,0+3=3,0+3+6=9,0+3+6+7=16;其中0、3、6、7都是n_values;得到的[0,3,9,16]就是feature_indices_)
In [4]: one_hot_encoder.feature_indices_
Out[4]: array([ 0, 3, 9, 16], dtype=int32)
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
>>> enc.n_values_
array([2, 3, 4])
>>> enc.feature_indices_
array([0, 2, 5, 9])
>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1., 0., 0., 1., 0., 0., 1., 0., 0.]])
'''
由[[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]得到的矩阵就是:
0 0 3
1 1 0
0 2 1
1 0 2
'''
② 标签编码(Label encoding)
le = sklearn.preprocessing.LabelEncoder()
le.fit([1, 2, 2, 6])
le.transform([1, 1, 2, 6]) #array([0, 0, 1, 2])
#非数值型转化为数值型
le.fit(["paris", "paris", "tokyo", "amsterdam"])
le.transform(["tokyo", "tokyo", "paris"]) #array([2, 2, 1])
2.5.1 标签编码Label encoding 和 独热编码OneHotEncoder例题
例题—会员卡预测
包含27个相关的特征(姓名、地址、教育情况);还有一个会员卡的类型(金卡、银卡、铜卡、普通卡)特征的选择:特征列太多,我们先选择三个数字型特征的列(年收入,小孩数,家庭汽车拥有量)。年收入是一个范围,我们要替换一下才能用;
import pandas as pd
frame=pd.read_csv('F:/python数据/customer.csv')
print(frame['yearly_income'].head(2))
frame['yearly_income']=frame['yearly_income'].str.replace('[^0-9]','') #frame['yearly_income'].str获得列那一列元素的字符串表示,然后用空字符替换不属于0-9的阿拉伯数字
print(frame['yearly_income'].head(2))
'''用3050表示30-50'''
方法二:
import pandas as pd
frame=pd.read_csv('F:/python数据/customer.csv')
print(frame['yearly_income'].head(2))
frame['yearly_income']=frame['yearly_income'].str.split(' ').str[0].str.replace('[^0-9]','') #我们只取下限作为年收入
print(frame['yearly_income'].head(2))
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
import numpy as np
frame=pd.read_csv('F:/python数据/customer.csv')
frame['yearly_income']=frame['yearly_income'].str.split(' ').str[0].str.replace('[^0-9]','') #我们只取下限作为年收入
y=frame['member_card'] #把会员卡列作为预测列
X=frame[["yearly_income",'total_children','num_cars_owned']] #将三个数值列作为特征列
如果能够引入更多的分类特征,决策树的效果会更好一些,比如受教育程度和职业与会员等级也有很大的联系
import pandas as pd
from sklearn.preprocessing import LabelEncoder
frame=pd.read_csv('F:/python数据/customer.csv')
encoding=LabelEncoder() #使用这种方法将字符串映射为数字
encoding.fit(frame['education'])
education_new=encoding.transform(frame['education'])
print(frame['education'].values)
print(education_new)
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
import numpy as np
frame=pd.read_csv('F:/python数据/customer.csv')
frame['yearly_income']=frame['yearly_income'].str.split(' ').str[0].str.replace('[^0-9]','') #我们只取下限作为年收入
encoding=LabelEncoder() #使用这种方法将字符串映射为数字
encoding.fit(frame['education'])
frame['education_new']=encoding.transform(frame['education'])
y=frame['member_card'] #把会员卡列作为预测列
X=frame[["yearly_income",'total_children','num_cars_owned']] #将三个数值列作为特征列
clf=DecisionTreeClassifier() #用了决策树
scores=cross_val_score(clf,X,y,scoring='accuracy')
print(np.mean(scores))
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
import numpy as np
frame=pd.read_csv('F:/python数据/customer.csv')
encoding=OneHotEncoder()
print(frame['education'].values)
newData=encoding.fit_transform(np.vstack(frame['education'].values)).todense()#vstack把序列竖了起来,只有这样才能存储独热编码的那些列
print(newData)
import pandas as pd
import numpy as np
frame=pd.read_csv('F:/python数据/customer.csv')
print(frame['education'].values)
print(np.vstack(frame['education'].values)) #vstack把序列竖了起来,只有这样才能存储独热编码的那些列
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
import numpy as np
frame=pd.read_csv('F:/python数据/customer.csv')
encoding=OneHotEncoder()
newData=encoding.fit_transform(np.vstack(frame['education'].values)).todense()
frame_new=pd.DataFrame(newData)
frame_full=pd.merge(frame[['yearly_income','total_children','num_cars_owned']],frame_new,left_index=True,
right_index=True)
print(frame_full)
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import OneHotEncoder
import numpy as np
frame=pd.read_csv('F:/python数据/customer.csv')
y=frame['member_card'] #把会员卡列作为预测列
frame['yearly_income']=frame['yearly_income'].str.split(' ').str[0].str.replace('[^0-9]','')
encoding=OneHotEncoder()
newData=encoding.fit_transform(np.vstack(frame['education'].values)).todense()
frame_new=pd.DataFrame(newData)
frame_full=pd.merge(frame[['yearly_income','total_children','num_cars_owned']],frame_new,left_index=True,
right_index=True)
X=frame_full
clf=DecisionTreeClassifier()
scores=cross_val_score(clf,X,y,scoring='accuracy')
print(np.mean(scores))
2.6弥补缺失值
①slearn的缺失值处理器: Imputer
(Imputer 只接受DataFrame类型,而且Dataframe 中必须全部为数值属性)
from sklearn.preprocessing import Imputer
#Imputer函数,通过设定strategy参数为mean,使用平均值补全缺失数据,axis=0为按列处理
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
- “mean”使用平均值代替
- “median”使用中值代替
- “most_frequent”使用众数代替,也就是出现次数最多的数
import pandas as pd
import numpy as np
df=pd.DataFrame([["XXL", 8, "black", "class 1", 22],
["L", np.nan, "gray", "class 2", 20],
["XL", 10, "blue", "class 2", 19],
["M", np.nan, "orange", "class 1", 17],
["M", 11, "green", "class 3", np.nan],
["M", 7, "red", "class 1", 22]])
df.columns=["size", "price", "color", "class", "boh"]
print(df)
'''
size price color class boh
0 XXL 8.0 black class 1 22.0
1 L NaN gray class 2 20.0
2 XL 10.0 blue class 2 19.0
3 M NaN orange class 1 17.0
4 M 11.0 green class 3 NaN
5 M 7.0 red class 1 22.0
'''
from sklearn.preprocessing import Imputer
imp =Imputer(missing_values="NaN", strategy="mean",axis=0 )
df["price"]=imp.fit_transform(df[["price"]]) # 先只将处理price列的数据,使用fit_transform()函数即可完成缺失值填充了
print(df)
'''
size price color class boh
0 XXL 8.0 black class 1 22.0
1 L 9.0 gray class 2 20.0
2 XL 10.0 blue class 2 19.0
3 M 9.0 orange class 1 17.0
4 M 11.0 green class 3 NaN
5 M 7.0 red class 1 22.0
'''
df[['price', 'boh']] = imp.fit_transform(df[['price', 'boh']]) # 这是处理price列和both列的数据
print(df)
'''
size price color class boh
0 XXL 8.0 black class 1 22.0
1 L 9.0 gray class 2 20.0
2 XL 10.0 blue class 2 19.0
3 M 9.0 orange class 1 17.0
4 M 11.0 green class 3 20.0
5 M 7.0 red class 1 22.0
'''
df=imp.fit_transform(df) #这是处理整个df数据,当然这是行不通的,因为DataFrame不是只含有数字
print(df)
利用中位数或平均数来弥补缺失值
import numpy as np
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp.fit([[1, 2], [np.nan, 3], [7, 6]])
'''
第一列有两个数字,均值是4
第二列有三个数字,均值是3.6666
这两个均值就会应用在下面的imp.transform(x)中
'''
x = [[np.nan, 2], [6, np.nan], [7, 6]]
imp.transform(x)
'''
array([[ 4. , 2. ],
[ 6. , 3.66666667],
[ 7. , 6. ]])
'''
②Imputer类同样也可以支持稀疏矩阵,以下例子将0作为了缺失值,为其补上均值
import scipy.sparse as sp
# 创建一个稀疏矩阵
x = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
imp = Imputer(missing_values=0, strategy='mean', verbose=0)
imp.fit(x)
x_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
imp.transform(x_test)
③用knn近邻来补缺失值
这个KNNImputer类提供了使用k-最近邻方法填充缺失值的估算。
import numpy as np
from sklearn.impute import KNNImputer
nan = np.nan
X = [[1, 2, nan], [3, 4, 3], [nan, 6, 5], [8, 8, 7]]
imputer = KNNImputer(n_neighbors=2, weights="uniform")
imputer.fit_transform(X)
'''
array([[1. , 2. , 4. ],
[3. , 4. , 3. ],
[5.5, 6. , 5. ],
[8. , 8. , 7. ]])
'''
2.7自定义特征的转换函数
通俗的讲,就是把原始的特征放进一个函数中做转换,这个函数出来的值作为新的特征。
比如说将特征数据做log转换,做倒数转换等等。
FunctionTransformer 可以实现这个功能
import numpy as np
from sklearn.preprocessing import FunctionTransformer
transformer = FunctionTransformer(np.log1p)
x = np.array([[0, 1], [2, 3]])
transformer.transform(x)
array([[ 0. , 0.69314718],
[ 1.09861229, 1.38629436]])
2.8当我们拿到一批原始的数据
- 首先要明确有多少特征,哪些是连续的,哪些是类别的。
- 检查有没有缺失值,对确实的特征选择恰当方式进行弥补,使数据完整。
- 对连续的数值型特征进行标准化,使得均值为0,方差为1。
- 对类别型的特征进行one-hot编码。
- 将需要转换成类别型数据的连续型数据进行二值化。
- 为防止过拟合或者其他原因,选择是否要将数据进行正则化。
- 在对数据进行初探之后发现效果不佳,可以尝试使用多项式方法,寻找非线性的关系。
- 根据实际问题分析是否需要对特征进行相应的函数转换。
3,数据集拆分
在得到训练数据集时,通常我们经常会把训练数据进一步拆分成训练集和验证集,这样有助于我们模型参数的选取。
train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和testdata,形式为:
X_train,X_test, y_train, y_test =train_test_split(train_data,train_target,test_size=0.4, random_state=0)
参数解释
- train_data:所要划分的样本特征集
- train_target:所要划分的样本结果
- test_size:样本占比,若在0-1之间,为测试机样本数目与原始数目的比值。如果是整数的话就是样本的数量。
train_size同test_size- random_state:是随机数的种子。
- 随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
- 随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
种子不同,产生不同的随机数
种子相同,即使实例不同也产生相同的随机数- shuffle - 用来控制是否在分割数据前打乱原数据集的顺序,默认为True
stratify:控制分类问题中的分层抽样,默认为None,即不进行分层抽样,当传入为数组时,则依据该数组进行分层抽样(一般传入因变量所在列);
如何用?
# 作用:train_test_split将数据集划分为 训练集和测试集
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)
实例:
from sklearn.model_selection import train_test_split
from sklearn import datasets
import pandas as pd
X,y = datasets.load_iris(return_X_y=True)
'''不采取分层抽样时的数据集分割'''
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)
'''打印各个数据集的形状'''
print(X_train.shape,X_test.shape,y_train.shape,y_test.shape)
'''打印训练集中因变量的各类别数目情况'''
print(pd.value_counts(y_train))
'''打印验证集集中因变量的各类别数目情况'''
print(pd.value_counts(y_test))