数据挖掘工具---sklearn使用总结

本文来源Cer_ml和Jorocco;
sklearn是一个数据挖掘的python库,github地址,该库集成了大量的数据挖掘算法,并可以对数据做预处理,对算法进行集成和预测结果进行验证和评估。sklearn在数据量不是特别大的时候是很好用的;在大数据时,spark平台有差不功能的mllib库。

1、sklearn基础介绍

1.1、估计器(Estimator)

估计器很多时候可以直接理解为分类器,主要包含两个函数:
fit(): 训练算法,接收训练集和类别两个输入参数。
predict(): 预测测试集类别,接收测试集作为输入。
大多数sklearn的输入和输出的数据格式均为numpy格式或类似格式。

1.2、转换器(Transformer)

用于数据的预处理和数据转换,主要包含3个函数:
fit(): 训练算法。
transform(): 用于数据转换。
fit_transform(): 合并fit()和transform()两个函数的功能

1.3、流水线(Pipeline)

流水线的功能主要有3个:
一是跟踪记录各步骤的操作,以便重现实现结果;
二是对各操作步骤进行封闭;
三是使代码的复杂程度不至于超出掌控的范围。
基本的使用方法:
流水线的输入为一连窜的数据挖掘步骤(装在列表中),前几步通过为转换器,但最后一步必须为估计器。输入的数据集经过转换器的处理后,其输出作为下一步的输入,最后经过估计器对数据进行分类。每一步都用元组(名称,函数)来表示。
下面来创建流水线。

scaling_pipeline=Pipeline([('scale',MinMaxScaler()),('predict',KNeighborsClassifier())])

上面的这个例子中包含两个步骤,每个步骤都放在元组内,元组的第一个元素即为该步骤的名称,随便取便于理解功能即可,第二个元素为sklearn中实现相应功能的函数,很多时候直接看函数名便可猜到大致的功能。

1.4、预处理(Preprocessing)

在sklearn中我们会优先使用sklearn.preprocessing来完成预处理,但如果不能够满足自己的要求,我个人会使用map函数来做变换。

样本不平衡

怎样解决样本不平衡问题?
总结的很好
采样
合成
加权
一分类

基于训练样本少,特征过多的处理方法

解决样本不平衡问题的奇技淫巧 汇总

数据查看

参考下面缺失值处理部分

数据类型的转换

利用pandas.read_csv之类的接口来读取数据,会自动判断类型,并转换。
如果数值型混杂着字符型,那么后续处理过程很可能报错,尤其是代入模型的时候。

缺失值处理

查看各列有无缺失值
在sklearn中查看缺失值可以利用pandas.DataFrame的一些特性,比如df[‘XX’].value_counts()函数来查看各个值的情况,对于离散型数据较好用,会详细列出有哪些值,每个值的个数,因为数据来源我们是不知道,不同的数据来源对缺失值的表示方法可能不同,比如用’'表示,用null表示,用NaN表示;或者利用df.describe()或df.info()来查看。但是df.describe()只适用于缺失值用标准的NaN表示的时候,df.info()在缺失值用标准的NaN表示时会将缺失值排除在外进行基本的统计,因为我们也可以发现缺失值的情况,但如果存在一些其他方法的表示,就会造成不同类型数据混合而无法得到统计结果,我们就需要进一步的查看了。如下所示

a={'a':[1,'',2],'b':[3,4,float('NaN')],'c':[5,6,'Null']}
c=pd.DataFrame(a)
# print(c)
"""
    a    b     c
0  1  3.0     5
1     4.0     6
2  2  NaN  Null
"""
# print(c['a'].value_counts())
"""
2    1
1    1
     1
Name: a, dtype: int64
"""
# print(c['b'].value_counts())
"""
4.0    1
3.0    1
Name: b, dtype: int64
"""
# print(c['c'].value_counts())
"""
Null    1
6       1
5       1
Name: c, dtype: int64
"""
# print(c.info())
"""

RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
a    3 non-null object
b    2 non-null float64
c    3 non-null object
dtypes: float64(1), object(2)
memory usage: 152.0+ bytes
None
"""
# print(c.describe())
"""
             b
count  2.000000
mean   3.500000
std    0.707107
min    3.000000
25%    3.250000
50%    3.500000
75%    3.750000
max    4.000000
"""

转换器

主要在sklearn.preprocessing包下。这里的预处理都是针对特征值来操作的。具体功能如下:
规范化:
MinMaxScaler(): 将特征值缩放至0~1之间,公式 ( x i − m i n ( x ) ) / ( m a x ( x ) − m i n ( x ) ) (x_i-min(x))/(max(x)-min(x)) (ximin(x))/(max(x)min(x))
Normalizer(): 通过缩放使特征值的和为1,公式 x i / s u m ( x ) x_i/sum(x) xi/sum(x)
StandScaler(): 通过缩放使特征值的均值为0,方差为1,即为通常意义上的标准化,公式 ( x i − m e a n ( x ) ) / s t d ( x i − m e a n ( x ) ) (x_i-mean(x))/std(x_i-mean(x)) (ximean(x))/std(ximean(x))
编码:是特征工程的一部分
在sklearn中我们很多时候不需要去fit整个训练集,只要把训练集中包含的所有元素列出来,拿去fit就可以得到元素与编码之间的映射关系,个人觉得这样处理可以节省程序运行时间。
借助pandas的replace,get_dummies等函数也同样能实现LabelEncoder和OneHotEncoder的效果。
LabelEncoder: 将字符串类型的数据转换为整形

le = LabelEncoder()
le.fit([90063345,89950166,89950167,99999828,89016252,99104722,90109916,89950168,99999827,99999826,
                                  90155946,99999830,99999825,89016253,89016259])
y =le.transform(data['current_service'])
le.inverse_transform(yPred)

OneHotEncoder: 用二进制数来表示特征

enc=OneHotEncoder()
OneHotData={'service_type':[1,3,4,1,3,4,1,3,4,1,3,4,1,3,4,1,3,4,1,3,4,1,1,4,1,3,4,1,3,4,1,3,4,1,3,4,1,3,4,1,1],
            'is_mix_service':[0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1],
            'many_over_bill':[0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1],
            'contract_type':[0,1,3,9,12,7,6,2,8,0,1,3,9,12,7,6,2,8,0,0,0,0,0,7,6,2,8,0,1,3,9,12,7,6,2,8,0,0,0,0,0],
            'is_promise_low_consume':[0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1],
            'net_service':[4,3,2,9,4,3,2,9,4,3,2,9,4,3,2,9,4,3,2,9,4,3,3,3,2,9,4,3,2,9,4,3,2,9,4,3,2,9,4,3,3],
            'gender':[0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,0.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,2.0,0.0,1.0,1.0],
            'complaint_level':[0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,1,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1],
            'former_complaint_num':[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,21,22,23,37,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
            'contract_time':[0,12,24,36,10,13,30,23,11,26,15,18,100,8,7,34,35,16,19,17,25,20,6,29,27,21,33,31,9,14,28,32,22,45,39,48,50,52,5,37,40]}
OneHotData=pd.DataFrame(OneHotData)[discreteVar]
# print(OneHotData)
enc.fit(OneHotData)
discreteData=enc.transform(discreteData).toarray()

Binarizer: 将数值型特征二值化

>>> X = [[ 1., -1.,  2.],
...      [ 2.,  0.,  0.],
...      [ 0.,  1., -1.]]

>>> binarizer = preprocessing.Binarizer().fit(X)  # fit does nothing
>>> binarizer
Binarizer(copy=True, threshold=0.0)

>>> binarizer.transform(X)
array([[ 1.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])
>>> binarizer = preprocessing.Binarizer(threshold=1.1)
>>> binarizer.transform(X)
array([[ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  0.,  0.]])

分桶
sklearn可惜没有Bucketizer,但应该有其他方式来实现对特征进行分段。下面是一个例子,也可以使用更方便的接口,pd.cut()和pd.qcut()

import numpy as np
np.set_printoptions(precision=2) #np.set_printoptions设置数组打印信息,precision设置输出浮点数精度
bins = np.linspace(-3, 3, 11) #构造连续特征切割分桶边界
print(bins)
#array([-3. , -2.4, -1.8, -1.2, -0.6,  0. ,  0.6,  1.2,  1.8,  2.4,  3. ])
#共10段,按1-10编码
X=[[-0.75],[ 2.7 ],[ 1.39],[ 0.59],[-2.06]]
which_bin = np.digitize(X, bins=bins) #np.digitize返回参数数组对应分桶的索引
print("\nData points:\n", X)
print("\nBin membership for data points:\n", which_bin)
"""
Data points:
[[-0.75], [2.7], [1.39], [0.59], [-2.06]]
Bin membership for data points:
[[ 4]
 [10]
 [ 8]
 [ 6]
 [ 2]]
"""

FunctionTransformer:自定义一些变换,之前我是用map实现,看来直接就有现成的接口了。不过效果差不多

>>> 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]])

MultiLabelBinarizer: 多标签二值化

1.5、特征

特征工程

更多参考使用sklearn做单机特征工程

  • sklearn.preprocessing.add_dummy_feature
    其实是添加常数项的
  • sklearn.preprocessing.quantile_transform(X, axis=0, n_quantiles=1000, output_distribution=’uniform’, ignore_implicit_zeros=False, subsample=100000, random_state=None, copy=False)
  • sklearn.preprocessing.PolynomialFeatures(degree=2, interaction_only=False, include_bias=True)
>>> import numpy as np
>>> from sklearn.preprocessing import PolynomialFeatures
>>> X = np.arange(6).reshape(3, 2)
>>> X                                                 
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> poly = PolynomialFeatures(2)
>>> poly.fit_transform(X)                             
array([[  1.,   0.,   1.,   0.,   0.,   1.],
       [  1.,   2.,   3.,   4.,   6.,   9.],
       [  1.,   4.,   5.,  16.,  20.,  25.]])

( X 1 , X 2 ) t o ( 1 , X 1 , X 2 , X 1 2 , X 1 X 2 , X 2 2 ) (X_1, X_2) to (1, X_1, X_2, X_1^2, X_1X_2, X_2^2) (X1,X2)to(1,X1,X2,X12,X1X2,X22)

1.5.1特征抽取

通过包sklearn.feature_extraction来实现
特征抽取是数据挖掘非常重要的一环,对最终结果的影响要高过数据挖掘算法本身。只有将现实事件用合适的特征表示出来,才能借助数据挖掘的力量找到其他的规律。特征抽取也可以降低事情的复杂程度。
一般最常用的特征抽取技术都是高度针对特定领域的。如图像处理领域,提出了很多特征抽取技术,但是这些技术在其他领域的应用却非常有限。
DictVectorizer(): 将dict类型的list数据转换为numpy array
FeatureHasher(): 将特征哈希,将数据做哈希映射,同时能达到降维的效果
image(): 图像相关的特征抽取
text(): 文本相关的特征抽取
text.CountVectorizer(): 将文本转换为每个词出现个数的向量
text.TfidfVectorizer(): 将文本转换为逆文本词频向量
text.HashingVectorizer(): 将文本作哈希向量化

1.5.2、特征选择

更多参考特征选择 (feature_selection)
包:sklearn.feature_selection
特征选择的原因:
(1)降低数据复杂度
(2)降低噪声
(3)增强数据的可解释性
VarianceThreshold(): 删除方差达不到最低标准的特征
SelectKBest(): 返回K个最佳特征
SelectPercentile(): 返回表现最佳的前r%个特征
单个特征和某一类型特征之间相关性的计算方法有很多,如 χ 2 \chi^2 χ2,其他的方法还有互信息和信息熵
chi2(): 卡方检验

1.6、降维

包:sklearn.decomposition
算法的采用的是主成分降维(PCA)

1.7、组合

包:sklearn.ensemble
ensemble下的算法均为组合算法,组合技术也就是通过聚合多个分类器的结果来提高分类等预测的准确率。
常用的组合分类器有下面3种处理方式:
(1)通过随机抽取部分样本,组成多个训练集,得到多个模型,从而同一个样本有多个预测结果,从中得到最后的预测结果,从而提高预测准确性,如bagging和boosting。
(2)通过随机抽取部分特征,从而构成多个新的训练集,得到多个模型,从而可以对一个样本进行多次预测,采用少数服从多数的原则,得到最后的预测结果。随机森林则是综合了(1)、(2)两种处理方方法。
(3)通过对标签进行处理,适用于多分类的情况,将标号随机分成两个不相交的子集,把问题变成二分类问题,每一次都会得到一个预测结果,,重复构建多次模型,进行分类投票。
有以下的组合方法:
BaggingClassifier:
BaggingRegressor:
AdaBoostClassifier:
AdaBoostRegressor:
GradientBoostingClassifier:
GradientBoostingRegressor:
ExtraTreeClassifier:
ExtraTreeRegressor:
RandomTreeClassifier:
RandomTreeRegressor:
举例:

AdaBoostClassifier(DecisionTreeClassifier(max_depth=1),algorithm="SAMME",n_estimators=200)

从上例可以看到,AdaBoostClassifier是一种处理方式,但还需要指明与之配合的基础分类算法。

1.8、模型评估

包:sklearn.metrics
包含评分方法、性能度量、成对度量和距离计算
评估的方式可通过传入y_true,y_pred给metrics的相关接口,得到计算结果;也可以在交叉验证的时候指标评估标准。

分类结果度量

输入大多为y_true,y_pred
具体评价指标如下:
**metrics.confusion_matrix(y_true, y_pred[, …])**分类混淆矩阵
accuracy_score: 分类准确度
正确分类的样本数与检测样本总数(S)的比值
分类准确率这一衡量分类器的标准比较容易理解,但是它不能告诉你响应值的潜在分布,并且它也不能告诉你分类器犯错的类型。
metrics.precision_score(y_true, y_pred[, …])
**metrics.average_precision_score(y_true, y_score) **
metrics.recall_score(y_true, y_pred[, …])
metrics.f1_score(y_true, y_pred[, labels, …])
precision_recall_fscore_support: 计算精确度、召回率、f、支持度
metrics.roc_curve(y_true, y_score[, …])
metrics.auc
metrics.roc_auc_score(y_true, y_score[, …])
metrics.precision_recall_curve(y_true, …)
metrics.brier_score_loss(y_true, y_prob[, …])
jaccard_similarity_score: 计算jaccard相似度
杰卡德相似系数:两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示。​
metrics.matthews_corrcoef(y_true, y_pred[, …])
metrics.cohen_kappa_score(y1, y2[, labels, …])
metrics.fbeta_score(y_true, y_pred, beta[, …])
hamming_loss: 计算汉明损失
zero_one_loss: 计算0-1损失
hinge_loss: 计算hinge损失
可参考机器学习中的损失函数 (着重比较:hinge loss vs softmax loss)
log_loss: 计算log损失
更多,可参考sklearn中的损失函数
classification_report: 分类报告

回归结果度量

mean_absolute_error: 平均绝对误差
mean_squared_erro 均方误差
metrics.mean_squared_log_error(y_true, y_pred):
metrics.median_absolute_error(y_true, y_pred):
explained_variance_score: 可解释方差的回归评分,与决定系数相比,这里是1-残差平方和/y的方差,而决定系数是1-残差的方差/比上y 的方差。总体上两者的趋势是一致的,但有细微差别,结果上一般决定系数的更接近1.
metrics.r2_score(y_true, y_pred[, …]): 也就通过说的决定系数 r 2 r^2 r2
相关计算公式可参考:scikit-learn中拟合结果的评价指标

多标签的度量

当有多列标签时,实际上还没生成多列标签处理过,不知道这样处理有什么优势
coverage_error: 涵盖误差
label_ranking_average_precision_score: 基于排名的平均精度
metrics.label_ranking_loss(y_true, y_score)

聚类结果度量

adjusted_mutual_info_score: 调整的互信息得分
silhouette_score: 所有样本轮廓系数的平均值
silhouette_sample: 所有样本轮廓系数
官网上有更多指标

1.9、交叉验证

包:sklearn.cross_validation
http://scikit-learn.org/stable/modules/classes.html#module-sklearn.model_selection
KFold(): 交叉验证迭代器,接收元素个数、fold数、是否清洗
LeaveOneOut(): 交叉验证迭代器
LeavePOut(): 交叉验证迭代器
LeaveOneLableOut(): 交叉验证迭代器
LeavePLableOut(): 交叉验证迭代器
交叉验证是利用训练集本身来测试模型精度,思路是将训练集分成n份,然后按一定比例取其中的几份(大头)作为真正的训练集来训练模型,其中的几份(少数)不参与训练来验证模型精度。然后循环这个过程,得到多组测试精度。所以在交叉验证器里就涉及到抽取测试集的比例问题。
LeaveOneOut()就是从n份(全校样本)里抽1份作为测试集,LeavePOut()就是从n份(全校样本)里抽p份作为测试集。
LeaveOneOut(n) 相当于 KFold(n_folds=n) ,当n等于全体样本数时(KFold的n_folds参数指的是将全体样本分成几份,每次拿其中的1份或几份做为测试集,而且它多次操作,会让测试覆盖整个数据集);相当于LeavePOut(n, p=1)(LeavePOut中p参数指p个样本)。三者均会重复,让测试集覆盖全体样本。
而LeaveOneLableOut()和LeavePLableOut()与上面的区别在于,这里可以直接加入第三方的标签作为数据集的区分,也就是第三方标签已经把数据分成n份了。们的数据是一些季度的数据。那么很自然的一个想法就是把1,2,3个季度的数据当做训练集,第4个季度的数据当做测试集。这个时候只要输入每个样本对应的季度Label,就可以实现这样的功能。
常用方法:
train_test_split: 分离训练集和测试集,这一步一般是在交叉验证前做的,与KFold()不同
cross_val_score: 交叉验证得分即精度,为一组数据,存放于列表中
分类中

>> from sklearn import metrics
>>> scores = cross_val_score(
...     clf, iris.data, iris.target, cv=5, scoring='f1_macro')
>>> scores                                              
array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])

在回归中

>>> X = diabetes.data[:150]
>>> y = diabetes.target[:150]
>>> lasso = linear_model.Lasso()
>>> print(cross_val_score(lasso, X, y))  
[ 0.33150734  0.08022311  0.03531764]

cross_validate
似乎可以得到比cross_val_score更丰富的信息,也可以同时设置多少评估标准

>>> cv_results = cross_validate(lasso, X, y, return_train_score=False)
>>> sorted(cv_results.keys())                         
['fit_time', 'score_time', 'test_score']
>>> cv_results['test_score']    
array([ 0.33...,  0.08...,  0.03...])
>>> scores = cross_validate(lasso, X, y,
...                         scoring=('r2', 'neg_mean_squared_error'))
>>> print(scores['test_neg_mean_squared_error'])      
[-3635.5... -3573.3... -6114.7...]
>>> print(scores['train_r2'])                         
[ 0.28...  0.39...  0.22...]

cross_val_predict: 交叉验证的预测结果
因为交叉验证中每一次的测试样本只是全体中的部分,要得到全体样本的预测值就需要做完整个交叉验证。因而不是通过交叉验证得到最佳的预测结果。

1.10、网络搜索

包:sklearn.grid_search
网络搜索是用来寻找最佳参数的。
GridSearchCV: 搜索指定参数网格中的最佳参数
ParameterGrid: 参数网络
ParameterSampler: 用给定分布生成参数的生成器
RandomizedSearchCV: 超参的随机搜索
通过best_estimator_get_params() 方法获取最佳参数

1.11、多分类、多标签分类

包:sklearn.multiclass
OneVsRestClassifier: 1-rest多分类(多标签)策略
OneVsOneClassifier: 1-1多分类策略
OutputCodeClassifier: 1个类用一个二进制码表示
在多标签的情况下,输入必须是二值化的。所以需要MultiLabelBinarizer()先处理。
sklearn 用户手册之1.12. 多类别与多标签算法
python机器学习库sklearn——多类、多标签、多输出

多输出回归

# =========多输出回归================
from sklearn.datasets import make_regression
from sklearn.multioutput import MultiOutputRegressor
from sklearn.ensemble import GradientBoostingRegressor
from sklearn import metrics
X, y = make_regression(n_samples=10, n_targets=3, random_state=1)  # 产生10个样本,每个样本100个属性,每个样本3个输出值
print('样本特征维度',X.shape)
print('样本输出维度',y.shape)
clf = GradientBoostingRegressor(random_state=0)
clf =MultiOutputRegressor(clf)
clf.fit(X, y)
y_pred = clf.predict(X) # 预测样本
print('均方误差:',metrics.mean_squared_error(y, y_pred))  # 均方误差

2、scikit-learn扩展

2.1 概览

具体的扩展,通常要继承sklearn.base包下的类。
BaseEstimator: 估计器的基类
ClassifierMixin : 分类器的混合类
ClusterMixin: 聚类器的混合类
RegressorMixin : 回归器的混合类
TransformerMixin : 转换器的混合类

2.2 创建自己的转换器

在特征抽取的时候,经常会发现自己的一些数据预处理的方法,sklearn里可能没有实现,但若直接在数据上改,又容易将代码弄得混乱,难以重现实验。这个时候最好自己创建一个转换器,在后面将这个转换器放到pipeline里,统一管理。
例如《Python数据挖掘入门与实战》书中的例子,我们想接收一个numpy数组,根据其均值将其离散化,任何高于均值的特征值替换为1,小于或等于均值的替换为0。

from sklearn.base import TransformerMixin
from sklearn.utils import as_float_array

class MeanDiscrete(TransformerMixin):

#计算出数据集的均值,用内部变量保存该值。  
def fit(self, X, y=None):
      X = as_float_array(X)
      self.mean = np.mean(X, axis=0)
      #返回self,确保在转换器中能够进行链式调用(例如调用transformer.fit(X).transform(X))
      return self

def transform(self, X):
    X = as_float_array(X)
    assert X.shape[1] == self.mean.shape[0]
    return X > self.mean

3、使用sklearn数据挖掘一般流程

3.1、加载数据

sklearn的实现使用了numpy的arrays,所以需要使用numpy来读入数据。

# -*- coding: utf-8 -*-
import numpy as np
import urllib.request

#直接从网络上读取数据,该数据有767个样本,每个样本有9列,最后一列为标签列
url="http://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data"
rawdata=urllib.request.urlopen(url)
#利用numpy.loadtxt从网络地址上读数据
dataset=np.loadtxt(rawdata,delimiter=',')#也可以先将数据下载到本地,然后从本地路径上下载数据,只要将rawdata换成本地路径就可以了
X=dataset[:,0:8]
y=dataset[:,8]

3.2、数据预处理

大多数机器学习算法中的梯度方法对于数据的缩放和尺度都是很敏感的,在开始跑算法之前,我们应该进行归一化或者标准化的过程,这使得特征数据缩放到0-1范围中,归一化的方法,具体解释参考。
归一化(Normalization)
针对样本,例如

from sklearn import preprocessing
normalized_X=preprocessing.normalize(X)

尺度缩放(Scaling)
针对变量,如

scaled_X=preprocessing.scale(X)

标准化(Standardization)

standardized_X=preprocessing.StandardScaler(X)

独热编码

  • class sklearn.preprocessing.OneHotEncoder(n_values=’auto’, categorical_features=’all’, dtype=, sparse=True, handle_unknown=’error’)
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
>>> 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.]])

特征工程除了上面sklearn.preprocessing中一些标准的接口,其实也可以用map来实现各种变换

3.3、特征工程

特征工程也包括上面的数据预处理,如果仅仅从生成新的特征上来看,可以作一些诸如对数变换、变量之间的加减乘除的一些操作(这些一般会对应特定的物理意义),也可以用一些工具来生成很多特征。个人感觉像FM那样的算法或多项式回归这样的不就是生成了很多新的特征么?

3.4、模型训练

逻辑回归 为例

from sklearn.linear_model import LogisticRegression
from sklearn import metrics
model=LogisticRegression()
model.fit(X,y)
print("模型:")
print(model)
expected=y
predicted=model.predict(X)
print("结果报告 :")
print(metrics.classification_report(expected,predicted))
print("混淆矩阵:")
print(metrics.confusion_matrix(expected,predicted))

结果如下:

模型:
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
          verbose=0, warm_start=False)
结果报告 :
             precision    recall  f1-score   support

        0.0       0.79      0.90      0.84       500
        1.0       0.74      0.55      0.63       268

avg / total       0.77      0.77      0.77       768

混淆矩阵:
[[448  52]
 [121 147]]

3.5、算法参数优化

具体参考官方文档
整体思路是,将需要搜索最优参数的一系列候选值赋给一个数组,然后用参数搜索接口如GridSearchCV去训练,而不是直接用算法去训练,这些搜索接口接受具体的算法和候选参数作为输入。返回的结果中就包含了最佳得分和最佳参数。
不同的算法涉及的参数是不一样的,以后有时间再慢慢写。

3.6 sklearn模型的保存与恢复

用sklearn 保存和加载模型的两种方法
用sklearn 保存和加载模型的两种方法
模型的保存过程:

from sklearn.externals import joblib
from sklearn import svm
import os
 
# os.chdir("workspace/model_save")
X = [[0, 0], [1, 1]]
y = [0, 1]
clf = svm.SVC()
clf.fit(X, y)
joblib.dump(clf, "train_model.m")

模型的读取过程:

from sklearn.externals import joblib
 
clf = joblib.load("train_model.m")
X = [[0, 0], [1, 1]]
y = [0, 1]
 
print(clf.predict(X))

损失函数:
https://blog.csdn.net/u014114990/article/details/47974031

模型选择

VotingClassifier 模型聚合——投票
sklearn中的投票法

一个框架解决几乎所有机器学习问题

深度特征合成:自动化特征工程的运作机制

你可能感兴趣的:(算法模型)