0%

Python-机器学习

使用 Python 进行机器学习的相关实践。如:

  • Scikit-learn:sklearn:面向 python 的机器学习库。
  • pyflux:时间序列分析库,如 RIMA、GARCH 和 VAR 等模型
  • NuPIC:专注时间序列的机器学习平台,核心算法为 HTM 算法

概述

  • 参考《机器学习方法》

机器学习过程

  1. 加载库:numpy, pandas, matplotlib,Scikit-Learn
  2. 加载数据集:xx.cxv, html,json,数据汇总
  3. 描述性统计:均值、标准差、四分位数等 pandas.DataFrame.describe
  4. 数据可视化:
  5. 数据清洗:缺失值、异常值、pandas.DataFrame.isna pandas.DataFrame.replace
  6. 特征选择:SelectKBest、特征消除方法(例如 RFE(递归特征消除))和嵌入式方法(例如 LassoCV)。
  7. 特征工程:为增加与目标的相关性,对特征进行一些处理,如缩放 (StandardScaler,Normalizer,MinMaxScaler)、线性/二次组合来增加特征、对数转换、交互作或 Box-Cox 转换等。

Scikit-learn

Scikit-learn:sklearn:面向 python 的机器学习库。

  • 基于 numpy、scipy 模块,处理数据方面的不错选择。
  • 意义:
    • scikit-learn,是传统机器学习方法,有助于理解机器学习,能解决深度学习难以解决的问题。深度学习的 gpu 限制,只有在深度学习效果远好于传统机器学习时才用,比如语音识别、图像识别等 ,而 nlp 邻域除了机器翻译外,其他大部分任务使用的是传统方法。它有着更好的解释性,方便调试。“能解决问题。”`
  • 特点:
    • 开源、商业可用 - BSD 许可
    • 性能优秀:算法高效 + Cython 编译器
    • 不支持深度学习与强化学习,此外,它也不支持图模型和序列预测,不支持 Python 之外的语言,不支持 PyPy,也不支持 GPU 加速。
  • 功能:
    • 数据挖掘与分析:数据预处理、交叉验证、算法与可视化算法等一系列接口
    • 机器学习算法:分类、回归、聚类、数据降维、模型选择
      • 支持向量机、逻辑回归、朴素贝叶斯、随机森林、Gradient Boosting、K-means、DBSCAN 等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from sklearn.linear_model import LinearRegression
import numpy as np

np.random.seed(0)
# 初始化数据
x = np.random.rand(100, 1)
y = 1+2*x+0.1*np.random.randn(100, 1)
# 打乱
idx = np.arange(100)
np.random.shuffle(idx)
# 数据集
train_idx = idx[:80]
val_idx = idx[80:]
x_train, y_train = x[train_idx], y[train_idx]
x_val, y_val = x[val_idx], y[val_idx]
print(x_val)

a = np.random.randn(1)
b = np.random.randn(1)
lr = 1e-1
epochs = 1000

for epoch in range(epochs):
y_calc = a+b*x_train
error = y_train-y_calc
loss = (error**2).mean()
a_grad = -2*error.mean()
b_grad = -2*(x_train*error).mean()
a = a-lr*a_grad
b = b-lr*a_grad
print(a, b)
# Sanity Check: do we get the same results as our gradient descent?
linr = LinearRegression()
linr.fit(x_train, y_train)
print(linr.intercept_, linr.coef_[0])

加载数据集

  • Sklearn datasets:提供了一些标准数据
    • load_boston
    • load_iris
    • load_diabetes
    • load_digits
    • load_linnerud
    • load_wine
    • load_breast_cancer
1
2
3
from sklearn import datasets

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

数据预处理

数据预处理:指数据的特征提取和归一化,

  • 是机器学习过程中的第一个也是最重要的一个环节
  • 这里归一化是指将输入数据转换为具有零均值和单位权方差的新变量,但因为大多数时候都做不到精确等于零,因此会设置一个可接受的范围,一般都要求落在 0-1 之间。
  • 而特征提取是指将文本或图像数据转换为可用于机器学习的数字变量。

归一化:将特征数据缩放到 0-1 范围

  • 标准化是依照特征矩阵的列处理数据,其通过求 z-score 的方法,将样本的特征值转换到同一量纲下。归一化是依照特征矩阵的行处理数据,其目的在于样本向量在点乘运算或其他核函数计算相似性时,拥有统一的标准,也就是说都转化为“单位向量”。
  • 标准化:对某个特征中心化,再除以非常量特征(non-constant features)的标准差进行缩放
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from sklearn import preprocessing
# 归一化(Normalization)
normalized_X = preprocessing.normalize(feature_matrix)

# 标准化(Standardization)
standardized_X = preprocessing.scale(feature_matrix)


from sklearn.preprocessing import StandardScaler

#标准化,返回值为标准化后的数据
StandardScaler().fit_transform(iris.data)


from sklearn.preprocessing import Normalizer

#归一化,返回值为归一化后的数据
Normalizer().fit_transform(iris.data)

白化:降低输入数据的冗余信息,如图像的相邻像素的相关性。

  • 白化处理后
    • 特征之间相关性较低
    • 所有特征具有相同的方差。

区间缩放法:利用两个最值进行缩放

$x’=\frac{x-Min}{Max-Min}$

1
2
3
4
from sklearn.preprocessing import MinMaxScaler

#区间缩放,返回值为缩放到[0, 1]区间的数据
MinMaxScaler().fit_transform(iris.data)

定量特征二值化:核心在于设定一个阈值,大于阈值的赋值为 1,小于等于阈值的赋值为 0

1
2
3
4
from sklearn.preprocessing import Binarizer

#二值化,阈值设置为 3,返回值为二值化后的数据
Binarizer(threshold=3).fit_transform(iris.data)

定性特征哑编码: 假设有 N 种定性值,则将这一个特征扩展为 N 种特征,当原始特征值为第 i 种定性值时,第 i 个扩展特征赋值为 1,其他扩展特征赋值为 0。

由于 IRIS 数据集的特征皆为定量特征,故使用其目标值进行哑编码(实际上是不需要的)。使用 preproccessing 库的 OneHotEncoder 类对数据进行哑编码的代码如下:

1
2
3
4
from sklearn.preprocessing import OneHotEncoder

#哑编码,对 IRIS 数据集的目标值,返回值为哑编码后的数据
OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))

缺失值处理

由于 IRIS 数据集没有缺失值,故对数据集新增一个样本,4 个特征均赋值为 NaN,表示数据缺失。使用 preproccessing 库的 Imputer 类对数据进行缺失值计算的代码如下:

1
2
3
4
5
6
7
from numpy import vstack, array, nan
from sklearn.preprocessing import Imputer

#缺失值计算,返回值为计算缺失值后的数据
#参数 missing_value 为缺失值的表示形式,默认为 NaN
#参数 strategy 为缺失值填充方式,默认为 mean(均值)
Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))

将缺失值作为一个特征。

数据变换

基于多项式的、基于指数函数的、基于对数函数的。

1
2
3
4
5
6
7
8
9
10
11
from sklearn.preprocessing import PolynomialFeatures

#多项式转换
#参数 degree 为度,默认值为 2
PolynomialFeatures().fit_transform(iris.data)  基于单变元函数的数据变换可以使用一个统一的方式完成,使用 preproccessing 库的 FunctionTransformer 对数据进行对数函数转换的代码如下:from numpy import log1p
from sklearn.preprocessing import FunctionTransformer

#自定义转换函数为对数函数的数据变换
#第一个参数是单变元函数
FunctionTransformer(log1p).fit_transform(iris.data)

特征工程

特征工程:从所有特征中抽取或构造有用特征,提高特征的泛化能力与可解释性。

  • 如在图像分类任务中,提取图像的边缘特征、尺度不变特征
  • 数据与特征决定了机器学习的上限,模型与算法则只能逼近这个上限

意义:

  • 增强鲁棒性
  • 简化模型设计
  • 优化结果
  • 可用性评估:获取难度、覆盖率、准确率
  • 特征清洗:清洗异常样本
  • 采样:数据不均衡、样本权重
  • 单个特征:无量纲化 (标准化、归一化)、二值化、离散化、缺失值(均值)、哑编码(一个定性特征扩展为 N 个定量特征)
  • 数据变换:log、指数、Box-Cox
  • 衍生变量:组合特征
  • 特征监控:监控重要特征,fa 特征质量下降

数据降维

数据降维:减少要考虑的变量的个数,应用于可视化处理、效率提升

  • 将原有特征重组成包含更多信息的特征,改变了原有特征空间
  • 特征抽取:Feature extraction:主成分分析(PCA)、线性判别分析法(LDA)
  • 特征选择:Feature Selection:互信息、TF-IDF
  • SVD 分解
  • 非负矩阵分解(NMF)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#  主成分分析法(PCA)
from sklearn.decomposition import PCA

#主成分分析法,返回降维后的数据
#参数 n_components 为主成分数目
PCA(n_components=2).fit_transform(iris.da
ta)

# 线性判别分析法(LDA)
from sklearn.lda import LDA

#线性判别分析法,返回降维后的数据
#参数 n_components 为降维后的维数
LDA(n_components=2).fit_transform(iris.data, iris.target)

特征选择

特征选择:为避免维度灾难下模型过于复杂,推广能力的下降,剔除不相关或冗余的特征

  • Filter:过滤法,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。
    • 以统计的方法给特征赋权衙,选取阈值,大于的保留下
    • Fisher 比、信息增益 Relief、T-test、方差分析
  • Wrapper:包装法,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。
    • 通过迭代法的方式,从一个局部最优解出发,逐渐向全局最优解适应
  • Embedded:集成法,先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于 Filter 方法,但是是通过训练来确定特征的优劣。

我们使用 sklearn 中的 feature_selection 库来进行特征选择。

  • 常用完全搜索,启发式搜索,和随机算法
  • Filter(相关系数、卡方检验)、Wrapper(AUC、设计评价函数 A*、Embedded(L1-Lasso、L2-Ridge、决策树、DL)
1
2
3
4
5
6
7
8
9
# Random Forest
from sklearn.ensemble import RandomForestClassifier

# xgboost
import xgboost as xgb

# 对于稀疏的数据
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

Filter

方差选择法

使用方差选择法,先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用 feature_selection 库的 VarianceThreshold 类来选择特征的代码如下:

1
2
3
4
5
from sklearn.feature_selection import VarianceThreshold

#方差选择法,返回值为特征选择后的数据
#参数 threshold 为方差的阈值
VarianceThreshold(threshold=3).fit_transform(iris.data)

相关系数法

使用相关系数法,先要计算各个特征对目标值的相关系数以及相关系数的 P 值。用 feature_selection 库的 SelectKBest 类结合相关系数来选择特征的代码如下:

1
2
3
4
5
6
7
8
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr

#选择 K 个最好的特征,返回选择特征后的数据
#第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,输出二元组(评分,P 值)的数组,数组第 i 项为第 i 个特征的评分和 P 值。在此定义为计算相关系数
#参数 k 为选择的特征个数
SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)

卡方检验

Chi-squared test:卡方检验:检验定性自变量对定性因变量的相关性。

  • 假设自变量有 N 种取值,因变量有 M 种取值,考虑自变量等于 i 且因变量等于 j 的样本频数的观察值与期望的差距,构建统计量
1
2
3
4
5
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

#选择 K 个最好的特征,返回选择特征后的数据
SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)

互信息法

定性自变量对定性因变量的相关性的,

为了处理定量数据,最大信息系数法被提出,使用 feature_selection 库的 SelectKBest 类结合最大信息系数法来选择特征的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
 from sklearn.feature_selection import SelectKBest
from minepy import MINE

#由于 MINE 的设计不是函数式的,定义 mic 方法将其为函数式的,返回一个二元组,二元组的第 2 项设置成固定的 P 值 0.5
def mic(x, y):
m = MINE()
m.compute_score(x, y)
return (m.mic(), 0.5)

#选择 K 个最好的特征,返回特征选择后的数据
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)

Wrapper

将子集的选择看成是一个搜索寻优问题,生成不同的组合,对组合进行评价,再与其他组合比较

  • 将子集的选择变成一个优化问题

递归特征消除法

递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。使用 feature_selection 库的 RFE 类来选择特征的代码如下:

1
2
3
4
5
6
7
8
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

#递归特征消除法,返回特征选择后的数据
#参数 estimator 为基模型
#参数 n_features_to_select 为选择的特征个数
RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)

Embadded

在模型既定的情况下学习出对提高模型准确性最好的属性。这句话并不是很好理解,其实是讲在确定模型的过程中,挑选出那些对模型的训练有重要意义的属性。 主要方法:**正则化,**可以见“简单易学的机器学习算法——岭回归 (Ridge Regression)”,岭回归就是在基本线性回归的过程中加入了正则项。

基于惩罚项的特征选择法

使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。使用 feature_selection 库的 SelectFromModel 类结合带 L1 惩罚项的逻辑回归模型,来选择特征的代码如下:

1
2
3
4
5
6
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression

#带 L1 惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data, iris.target)

基于树模型的特征选择法

树模型中 GBDT 也可用来作为基模型进行特征选择,使用 feature_selection 库的 SelectFromModel 类结合 GBDT 模型,来选择特征的代码如下:

1
2
3
4
5
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier

#GBDT 作为基模型的特征选择
SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)

模型算法

对于给定参数和模型的比较、验证和选择,其主要目的是通过参数调整来提升精度。

  • 实现的模块包括:格点搜索,交叉验证和各种针对预测误差评估的度量函数。
  • Linear Regression
  • RandomForestClassifier
  • RandomForestRegressor
  • ExtraTreesClassifier
  • ExtraTreesRegressor
  • XGBClassifier
  • XGBRegressor
1
2
3
4
5
6
# y = m * x + b
reg=sklearn.linear_model.LinearRegression()
# 训练这个模型,第一个参数是已知的数据,第二个参数是未来要预测的值
reg.fit(df['area'],df.price)
reg.coef_ # m 的值
reg.intercept_ # b 的值

pyflux

pyflux:时间序列分析库,如 RIMA、GARCH 和 VAR 等模型

NuPIC

NuPIC:专注时间序列的机器学习平台,核心算法为 HTM 算法

  • 用于预测及异常检测
给博主来一杯卡布奇诺