Scikit-learn使用总结
1 scikit-learn基础介绍
1.1 估计器(Estimator)
估计器,很多时候可以直接理解成分类器,主要包含两个函数:
fit():训练算法,设置内部参数。接收训练集和类别两个参数。
predict():预测测试集类别,参数为测试集。
大多数scikit-learn估计器接收和输出的数据格式均为numpy数组或类似格式。
1.2 转换器(Transformer)
转换器用于数据预处理和数据转换,主要是三个方法:
fit():训练算法,设置内部参数。
transform():数据转换。
fit_transform(): 合并fit和transform两个方法。
1.3 预处理
主要在sklearn.preprcessing包下
规范化:
MinMaxScaler :最大最小值规范化,实现 min-max 标准化,标准化后,所有的属性的值都在feature_range区间内。
原型:class sklearn.preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True)
from sklearn.preprocessing import MinMaxScaler
X = [[1, 5, 1, 2, 10],
[2, 6, 3, 2, 7],
[3, 7, 5, 6, 4],
[4, 8, 7, 8, 1]]
print("before transfom:",X)
scaler=MinMaxScaler(feature_range=(0,2))
scaler.fit(X)
print("min_ is:",scaler.min_)
print("scale_ is:",scaler.scale_)
print("data_max_ is:",scaler.data_max_)
print("data_min_ is:",scaler.data_min_)
print("data_range_ is:",scaler.data_range_)
print("after transform:",scaler.transform(X))
#### 结果 ####
before transfom: [[1, 5, 1, 2, 10], [2, 6, 3, 2, 7], [3, 7, 5, 6, 4], [4, 8, 7, 8, 1]]
min_ is: [-0.66666667 -3.33333333 -0.33333333 -0.66666667 -0.22222222]
scale_ is: [ 0.66666667 0.66666667 0.33333333 0.33333333 0.22222222]
data_max_ is: [ 4. 8. 7. 8. 10.]
data_min_ is: [ 1. 5. 1. 2. 1.]
data_range_ is: [ 3. 3. 6. 6. 9.]
after transform: [[ 0. 0. 0. 0. 2. ]
[ 0.66666667 0.66666667 0.66666667 0. 1.33333333]
[ 1.33333333 1.33333333 1.33333333 1.33333333 0.66666667]
[ 2. 2. 2. 2. 0. ]]
Normalizer : 将数据正则化,使每条数据各特征值的和为1,正则化后,每个样本的L2范数为1。
原型:class sklearn.preprocessing.Normalizer(norm=’l2’, copy=True)
norm:指定正则化方法
l1:采用L1范数正则化
l2:采用L2范数正则化
- max:采用L∞范数正则化
from sklearn.preprocessing import Normalizer
X = [[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[1, 3, 5, 2, 4],
[2, 4, 1, 3, 5]]
print("before transfom:",X)
normalizer = Normalizer(norm='l2')
print("after transform:",normalizer.transform(X))
#### 结果 ####
before transfom: [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1], [1, 3, 5, 2, 4], [2, 4, 1, 3, 5]]
after transform: [[ 0.13483997 0.26967994 0.40451992 0.53935989 0.67419986]
[ 0.67419986 0.53935989 0.40451992 0.26967994 0.13483997]
[ 0.13483997 0.40451992 0.67419986 0.26967994 0.53935989]
[ 0.26967994 0.53935989 0.13483997 0.40451992 0.67419986]]
MaxAbsScaler :实现属性绝对值最大值 标准化,将每个属性值除以该属性的绝对值中的最大值,标准化后,每个属性值得绝对值都在[0, 1]之间。
原型:class sklearn.preprocessing.MaxAbsScaler(copy=True)
from sklearn.preprocessing import MaxAbsScaler
X = [[1, 5, 1, 2, 10],
[2, 6, 3, 2, 7],
[3, 7, 5, 6, 4],
[4, 8, 7, 8, 1]]
print("before transfom:",X)
scaler = MaxAbsScaler()
scaler.fit(X)
print("scale_ is :",scaler.scale_)
print("max_abs_ is :",scaler.max_abs_)
print("after transform:",scaler.transform(X))
#### 结果 ####
before transfom: [[1, 5, 1, 2, 10], [2, 6, 3, 2, 7], [3, 7, 5, 6, 4], [4, 8, 7, 8, 1]]
scale_ is : [ 4. 8. 7. 8. 10.]
max_abs_ is : [ 4. 8. 7. 8. 10.]
after transform: [[ 0.25 0.625 0.14285714 0.25 1. ]
[ 0.5 0.75 0.42857143 0.25 0.7 ]
[ 0.75 0.875 0.71428571 0.75 0.4 ]
[ 1. 1. 1. 1. 0.1 ]]
StandardScaler : z-score标准化,为使各特征的均值为0,方差为1
原型:class sklearn.preprocessing.StandardScaler(copy=True,with_mean=True,with_std=True)
from sklearn.preprocessing import StandardScaler
X = [[1, 5, 1, 2, 10],
[2, 6, 3, 2, 7],
[3, 7, 5, 6, 4],
[4, 8, 7, 8, 1]]
print("before transfom:",X)
scaler = StandardScaler()
scaler.fit(X)
print("scale_ is :",scaler.scale_)
print("mean_ is :",scaler.mean_)
print("var_ is :",scaler.var_)
print("after transform:",scaler.transform(X))
#### 结果 ####
before transfom: [[1, 5, 1, 2, 10], [2, 6, 3, 2, 7], [3, 7, 5, 6, 4], [4, 8, 7, 8, 1]]
scale_ is : [ 1.11803399 1.11803399 2.23606798 2.59807621 3.35410197]
mean_ is : [ 2.5 6.5 4. 4.5 5.5]
var_ is : [ 1.25 1.25 5. 6.75 11.25]
after transform: [[-1.34164079 -1.34164079 -1.34164079 -0.96225045 1.34164079]
[-0.4472136 -0.4472136 -0.4472136 -0.96225045 0.4472136 ]
[ 0.4472136 0.4472136 0.4472136 0.57735027 -0.4472136 ]
[ 1.34164079 1.34164079 1.34164079 1.34715063 -1.34164079]]
编码:
Binarizer :为将数值型特征的二元化
原型:class sklearn.preprocessing.Binarizerr(threshold=0.0, copy=True)
threshold用于指定阈值,大于此阈值的数标记为1,小于此阈值的数为0
from sklearn.preprocessing import Binarizer
#class sklearn.preprocessing.Binarizer(threshold=0.0, copy=True)
#threshold用于指定阈值,大于此阈值的数标记为1,小于此阈值的数为0
X = [[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[3, 3, 3, 3, 3],
[1, 1, 1, 1, 1]]
print("before transfom:",X)
binarizer = Binarizer(threshold=2.5)
print("after transform:",binarizer.transform(X))
#### 结果 ####
before transfom:
[[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[3, 3, 3, 3, 3],
[1, 1, 1, 1, 1]]
after transform:
[[0 0 1 1 1]
[1 1 1 0 0]
[1 1 1 1 1]
[0 0 0 0 0]]
OneHotEncoder :scikit-learn提供的OneHotEncoder能够实现数据独热码,特征用一个二进制数字来表示
原型:class sklearn.preprocessing.OneHotEncoder(n_values=’auto’, categorical_features=’all’, sparse=True,handle_unknown=error”)
快速了解原理:
from sklearn.preprocessing import OneHotEncoder
X = [[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[3, 3, 3, 3, 3],
[1, 1, 1, 1, 1]]
print("before transfom:",X)
encoder = OneHotEncoder(sparse=False)
encoder.fit(X)
print("active_features_:",encoder.active_features_)
print("feature_indices_:",encoder.feature_indices_)
print("n_values_:",encoder.n_values_)
print("after transform:",encoder.transform([[1,2,3,4,5]]))
#### 结果 ####
before transfom:
[[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[3, 3, 3, 3, 3],
[1, 1, 1, 1, 1]]
active_features_: [ 1 3 5 7 8 9 10 12 14 16 17 18 19 21 23 25]
feature_indices_: [ 0 6 11 15 20 26]
n_values_: [6 5 4 5 6]
after transform:
[[ 1. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 1.]]
- LabelEncoder :把字符串类型的数据转化为整型
- MultiLabelBinarizer :多标签二值化估计器,很多时候可以直接理解成分类器
1.4 特征
*1.4.1 特征抽取*
主要在sklearn.feature_extraction包下
特征抽取是数据挖掘任务最为重要的一个环节,一般而言,它对最终结果的影响要高过数据挖掘算法本身。只有先把现实用特征表示出来,才能借助 数据挖掘的力量找到问题的答案。特征选择的另一个优点在于:降低真实世界的复杂度,模型比现实更容易操纵。
一般最常使用的特征抽取技术都是高度针对具体领域的,对于特定的领域,如图像处理,在过去一段时间已经开发了各种特征抽取的技术,但这些技术在其他领域的应用却非常有限。
DictVectorizer: 将dict类型的list数据,转换成numpy array
FeatureHasher : 特征哈希,相当于一种降维技巧
image:图像相关的特征抽取
text: 文本相关的特征抽取
text.CountVectorizer:将文本转换为每个词出现的个数的向量
text.TfidfVectorizer:将文本转换为tfidf值的向量
text.HashingVectorizer:文本的特征哈希
*1.5.2 特征选择*
主要在sklearn.feature_selection包下
特征选择的原因如下:
(1)降低复杂度
(2)降低噪音
(3)增加模型可读性特征抽
过滤式特征提取
VarianceThreshold: 删除特征值的方差达不到最低标准的特征,当一个熟悉的方差小时,说明该特征的价值不大,不应该优选,应该删除。
原型:class sklearn.feature_selection.VarianceThreshold(threshold=0.0)
threshold:用于指定方差阈值,低于此阈值的方差应该被剔除
#根据特征方差,方差小则该属性的识别能力差
from sklearn.feature_selection import VarianceThreshold
X = [[100, 1, 2, 3],
[100, 4, 5, 6],
[100, 7, 8, 9],
[100, 11, 12, 13]]
selector = VarianceThreshold(threshold=1)
selector.fit(X)
print("Variances is:", selector.variances_) # 成员分别各属性的方差
print("After transform::", selector.transform(X))
print("The surport is:", selector.get_support(True)) #返回被选出的特征的下标
print("After reverse transform is:", selector.inverse_transform(selector.transform(X)))
SelectKBest : 返回在该统计指标上得分最高的k个最佳特征,(通过计算每个特征的某个统计指标,
然后根据该指标来选取特征)
SelectPercentile :返回在该统计指标上得分最高的前K%个特征,(通过计算每个特征的某个统计指
标,然后根据该指标来选取特征)
原型:class sklearn.feature_selection.SelectKBest(score_func=f_classif, k=3)
k:用于指定保留特征个数
score_func:给出统计指标的函数,
f_regression:基于线性回归分析来计算统计指标,适用于回归问题
chi2:卡方统计量,适用于分类问题
f_classif:方差分析,适用于分类问题
# 单变量特征提取
from sklearn.feature_selection import SelectKBest, f_classif
X = [[1, 2, 3, 4, 5],
[5, 4, 3, 2, 1],
[3, 3, 3, 3, 3],
[1, 1, 1, 1, 1]]
y = [0, 1, 0, 1]
print("before transform:", X)
selector_2 = SelectKBest(score_func=f_classif, k=3)
selector_2.fit(X, y)
print("scores_ :", selector_2.scores_)
print("pvalues_ :", selector_2.pvalues_)
print("selected index", selector_2.get_support(True))
print("After transform:", selector_2.transform(X))
包裹式特征提取
RFE: 通过外部提供的一个学习器来选择特征,要求学习器学习的是特征的权重(通常使用SVM和广义线性模型)
原型:class sklearn.feature_selection.RFE(estimator, n_features_to_select=None, step=1)
estimator:通常使用SVM和广义线性模型
n_features_to_select:指定要选出几个特征
步骤:
- 初始化集合运用学习器进行训练
- 剔除其中权重特别小的特征
- 重新训练直到筛选出特征数量满足条件
# RFE
from sklearn.feature_selection import RFE
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
estimator = LinearSVC()
selector = RFE(estimator=estimator, n_features_to_select=2)
selector.fit(X, y)
print("N_features ",selector.n_features_)
print("Support is ",selector.support_)
print("Ranking ", selector.ranking_)
RFECV : 执行一个交叉验证来寻找最优的剩余特征数量,因此不需要指定保留多少个特征
原型:class sklearn.feature_selection.RFECV(estimator, cv=None, step=1)
estimator:通常使用SVM和广义线性模型
cv:交叉验证生成器,如果为整数k,则使用k折交叉验证
#RFECV
import numpy as np
from sklearn.feature_selection import RFECV
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
estimator = LinearSVC()
selector = RFECV(estimator=estimator, cv=3)
selector.fit(X, y)
print("N_features ",selector.n_features_)
print("Support is ",selector.support_)
print("Ranking ", selector.ranking_)
print("Grid Scores ",selector.grid_scores_)
嵌入式特征提取
SelectFromModel: 删除特征值的方差达不到最低标准的特征
原型:class sklearn.feature_selection.SelectFromModel(estimator, threshold=None)
threshold:用于指定阈值,低于此阈值的方差应该被剔除
#嵌入式特征选取from sklearn.feature_selection import SelectFromModel
import numpy as np
from sklearn.feature_selection import SelectFromModel
from sklearn.svm import LinearSVC
from sklearn.datasets import load_digits
digits = load_digits()
X = digits.data
y = digits.target
estimator = LinearSVC(penalty='l1', dual=False)
selector = SelectFromModel(estimator=estimator, threshold='mean') #阈值为'mean',表示特征重要性的均值
selector.fit(X, y)
selector.transform(X)
print("Threshold ",selector.threshold_)
print("Support is ",selector.get_support(indices=True))
数据预处理实战总结:
1、绘制箱型图判断数据是否有异常值
运用Python的Pandas库中,读入数据,然后使用describe()函数查看数据的基本情况
import pandas as pd
import numpy as np
#文件地址
catering_sale = 'E:/PyCharm/MyPyCharm/Python_data_analysis/chapter3/demo/data/catering_sale.xls'
#pd.read_excel()用于读取文件
data = pd.read_excel(catering_sale, index_col=r'日期')
#数据描述,其中count可以得到非空值数
#运用data.describe与len对比得到空值个数
data.describe()
len(data)
# df.index 是获取行名称,对应后面的[0]取行号/通过以下方式
np.where(data.isnull())#可以获取NAN的行号,如下为14行
(array([14], dtype=int64), array([0], dtype=int64))
data.index[np.where(data.isnull())[0]]#可以获取NAN的索引,如下为'2015-02-14'
DatetimeIndex(['2015-02-14'], dtype='datetime64[ns]', name='日期', freq=None)
#绘制箱型图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
plt.figure() #建立图像
p = data.boxplot(return_type='dict') #画箱线图,直接使用DataFrame的方法
x = p['fliers'][0].get_xdata() # 'flies'即为异常值的标签
y = p['fliers'][0].get_ydata()
y.sort() #从小到大排序,该方法直接改变原对象
#用annotate添加注释
#其中有些相近的点,注解会出现重叠,难以看清,需要一些技巧来控制。
#以下参数都是经过调试的,需要具体问题具体调试。
for i in range(len(x)):
if i>0:
plt.annotate(y[i], xy = (x[i],y[i]), xytext=(x[i]+0.05 -0.8/(y[i]-y[i-1]),y[i]))
else:
plt.annotate(y[i], xy = (x[i],y[i]), xytext=(x[i]+0.08,y[i]))
plt.show() #展示箱线图
通过绘制箱型图可以筛选查看出异常数据,箱型图识别异常值的结果比较客观,在识别异常值方面有一定的优越性,超过上下界的数据为可疑的异常值,然后通过编写过滤程序,进行后续处理。
2、数据清洗
运用拉格朗日插值法《python数据分析与挖掘实战P63》
from scipy.interpolate import lagrange #导入拉格朗日插值函数
# -*- coding:utf-8 -*-
# __author__ = 'Administrator'
#拉格朗日插值代码
import pandas as pd #导入数据分析库Pandas
from scipy.interpolate import lagrange #导入拉格朗日插值函数
inputfile = '../data/catering_sale.xls' #销量数据路径
outputfile = '../text/sales.xls' #输出数据路径
data = pd.read_excel(inputfile) #读入数据
# print(data)
data[u'销量'][(data[u'销量'] < 400) | (data[u'销量'] > 5000)] = None #过滤异常值,将其变为空值
#自定义列向量插值函数
#s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_column(s, n, k=5):
y = s[list(range(n-k, n)) + list(range(n+1, n+1+k))] #取数
y = y[y.notnull()] #剔除空值
return lagrange(y.index, list(y))(n) #插值并返回插值结果
#逐个元素判断是否需要插值
for i in data.columns:
for j in range(len(data)):
if (data[i].isnull())[j]: #如果为空即插值。
data[i][j] = ployinterp_column(data[i], j)
data.to_excel(outputfile) #输出结果,写入文件
在进行插值之前会对数据进行异常值检查,数据大于5000以及数据小于400的会被过滤检测出来(通过第一步的箱型图得来),然后再使用拉格朗日插值法填补数据。
很多情况下,要先分析异常值出现的可能原因,在判断异常值是否应该被舍弃,如果是正确的数据,可以直接在具有异常值的数据集上进行数据挖掘。