判别模型(discriminative model)
已知输入变量x,通过求解条件概率分布P(y|x)或者直接计算y的值来预测y。
例如:
生成模型(generative model)
已知输入变量x,通过对观测值和标注数据计算联合概率分布P(x,y)来达到判定估算y的目的。
例如:
K Nearest Neighbor算法又叫KNN算法,如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
1)计算已知类别数据集中的点与当前点之间的距离
2)按距离递增次序排序
3)选取与当前点距离最小的k个点
4)统计前k个点所在的类别出现的频率(分类
:样本出现最多个数 回归
:K个杨样本的平均值)
5)返回前k个点出现频率最高的类别作为当前点的预测分类
1 K值选择
K值的减小就意味着整体模型变得复杂,容易发生过拟合;
K值的增大就意味着整体模型变得简单,容易发生欠拟合;
注:实际应用中,K值一般取一个比较小的数值,例如采用交叉验证来选择最优的K值。
2 误差估计
- 近似误差:对训练集的训练误差,关注训练集,近似误差小可能出现过拟合。
- 估计误差:对测试集的测试误差,关注测试集,估计误差小说明对未知数据的预测能力好。
线性扫描(穷举搜索)
计算输入实例与每一个训练实例的距离。计算后再查找K近邻。当训练集很大时,计算非常耗时。
KD树
一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构
kd树是一种二叉树,表示对k维空间的一个划分,构造kd树相当于不断地用垂直于坐标轴的超平面将K维空间切分,构成一系列的K维超矩形区域。kd树的每个结点对应于一个k维超矩形区域。
利用kd树可以省去对大部分数据点的搜索,从而减少搜索的计算量。
距离计算
欧式距离(Euclidean Distance)
曼哈顿距离(Manhattan Distance)
切比雪夫距离 (Chebyshev Distance)
闵可夫斯基距离(Minkowski Distance)
其中p是一个变参数:
根据p的不同,闵氏距离可以表示某一类/种的距离。
其它距离:标准化欧氏距离 (Standardized EuclideanDistance)、余弦距离(Cosine Distance)、汉明距离(Hamming Distance)、杰卡德距离(Jaccard Distance)、马氏距离(Mahalanobis Distance)。
总结
闵氏距离的缺点:
将各个分量的量纲(scale),也就是“单位”相同的看待了;
未考虑各个分量的分布(期望,方差等)可能是不同的。
fit()
: Method calculates the parameters μ and σ and saves them as internal objects.transform()
: Method using these calculated parameters apply the transformation to a particular dataset.fit_transform()
: joins the fit() and transform() method for transformation of dataset.transform()
和fit_transform()
二者的功能都是对数据进行某种统一处理(比如标准化~N(0,1),将数据缩放(映射)到某个固定区间,归一化,正则化等)fit_transform(trainData)
对部分数据先拟合fit,找到该part的整体指标,如均值、方差、最大值最小值等等(根据具体转换的目的),然后对该trainData进行转换transform,从而实现数据的标准化、归一化等等。利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
from sklearn.linear_model import LinearRegression
x = [[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]]
y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]
# 实例化API
estimator = LinearRegression()
# 使用fit方法进行训练
estimator.fit(x,y)
print('回归系数:\n', estimator.coef_)
print('预测结果:\n', estimator.predict([[100, 80]]))
1 总损失函数:(最小二乘法
)
2 优化算法:
2.1 正规方程
缺点:当特征过多过复杂时,求解速度太慢并且得不到结果
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
def linear_model1():
"""
线性回归:正规方程
:return:None
"""
# 1.获取数据
data = load_boston()
# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state=22)
# 3.特征工程-标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习-线性回归(正规方程)
# fit_intercept:是否计算偏置;
estimator = LinearRegression(fit_intercept=True)
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 获取系数等值
y_predict = estimator.predict(x_test)
print("预测值为:\n", y_predict)
print("模型中的回归系数为:\n", estimator.coef_)
print("模型中的偏置为:\n", estimator.intercept_)
# 5.2 评价
# 均方误差
error = mean_squared_error(y_test, y_predict)
print("误差为:\n", error)
return None
均方误差(Mean Squared Error)MSE)评价机制:
2.2 梯度下降法(Gradient Descent)
α为学习率或者步长
单变量函数
中,梯度其实就是函数的微分
,代表着函数在某个给定点的切线的斜率
;多变量函数
中,梯度是一个向量
,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向
;算法选择依据:
- 小规模数据:
- 正规方程:LinearRegression(不能解决拟合问题)
- 岭回归
- 大规模数据:
- 梯度下降法:SGDRegressor
from sklearn.linear_model import SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
def linear_model2():
"""
线性回归:梯度下降法
:return:None
"""
# 1.获取数据
data = load_boston()
# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state=22)
# 3.特征工程-标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习-线性回归(特征方程)
# loss:损失类型 loss=”squared_loss”: 普通最小二乘法
# fit_intercept:是否计算偏置
# learning_rate: 学习率
# 'constant': eta = eta0
# 'optimal': eta = 1.0 / (alpha * (t + t0)) [default]
# 'invscaling': eta = eta0 / pow(t, power_t) # power_t=0.25:存在父类当中
# 对于一个常数值的学习率来说,可以使用learning_rate=’constant’ ,并使用eta0来指定学习率。
estimator = SGDRegressor(loss="squared_loss",fit_intercept=True,max_iter=1000,learning_rate="constant",eta0=0.1)
estimator.fit(x_train, y_train)
# 5.模型评估
# 5.1 获取系数等值
y_predict = estimator.predict(x_test)
print("预测值为:\n", y_predict)
print("模型中的系数为:\n", estimator.coef_)
print("模型中的偏置为:\n", estimator.intercept_)
# 5.2 评价
# 均方误差
error = mean_squared_error(y_test, y_predict)
print("误差为:\n", error)
return None
全梯度下降算法(Full gradient descent)
在更新参数时使用所有的样本来进行更新
计算训练集所有样本误差,对其求和再取平均值作为目标函数。
缺点:
因为在执行每次更新时,我们需要在
整个数据集
上计算所有的梯度
,所以批梯度下降法的速度会很慢,同时,批梯度下降法无法处理超出内存容量限制的数据集。批梯度下降法同样也不能在线更新模型,即在
运行的过程中,不能增加新的样本
。
随机梯度下降算法(Stochastic gradient descent)
优点:此过程简单,高效,通常可以较好地避免更新迭代收敛到局部最优解。
缺点:由于SG每次只使用一个样本迭代,若遇上噪声则容易陷入局部最优解。
小批量梯度下降算法(Mini-batch gradient descent)
小批量梯度下降算法是FG和SG的折中方案,在一定程度上兼顾了以上两种方法的优点。
batch_size:被抽出的小样本集所含样本点的个数,通常设置为2的幂次方,利于GPU加速处理。
特别的,若batch_size=1,则变成了SG;若batch_size=n,则变成了FG.
随机平均梯度下降算法(Stochastic average gradient descent)
在SG方法中,虽然避开了运算成本大的问题,但对于大数据训练而言,SG效果常不尽如人意,因为每一轮梯度更新都完全与上一轮的数据和梯度无关。SAG能克服该问题。
它们都是为了正确地调节权重向量,通过为每个权重计算一个梯度,从而更新权值,使目标函数尽可能最小化。其差别在于样本的使用方式不同。
添加其他特征项
,有时候我们模型出现欠拟合的时候是因为特征项不够导致的,可以添加其他特征项来很好地解决。例如,“组合”、“泛化”、“相关性”三类特征是特征添加的重要手段,无论在什么场景,都可以照葫芦画瓢,总会得到意想不到的效果。除上面的特征之外,“上下文特征”、“平台特征”等等,都可以作为特征添加的首选项。添加多项式特征
,这个在机器学习算法里面用的很普遍,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强。清洗数据
,导致过拟合的一个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重新清洗数据。增大数据的训练量
,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。正则化
维灾难
在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的数据点异常较多,所以算法在学习的时候尽量减少这个特征的影响(甚至删除某个特征的影响)
正则化类别
from sklearn.linear_model import Ridge, ElasticNet, Lasso
L1正则化
作用:可以使得其中一些权重直接为0,删除这个特征的影响
LASSO回归
(正则项为权值向量的ℓ1范数
)
代价函数如下:
Lasso Regression 能够自动进行特征选择,并输出一个稀疏模型(只有少数特征的权重是非零的)。
L2正则化
作用:可以使得其中一些权重都很小,都接近于0,削弱某个特征的影响
优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
Ridge回归
(实现了SAG
)
代价函数如下:
# alpha:正则化力度,也叫 λ λ取值:0~1 1~10;
# solver:会根据数据自动选择优化方法
# sag:如果数据集、特征都比较大,选择该随机梯度下降优化
# normalize:数据是否进行标准化
# normalize=False:可以在fit之前调用preprocessing.StandardScaler标准化数据
# Ridge.coef_:回归权重
# Ridge.intercept_:回归偏置
sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,solver="auto", normalize=False)
Elastic Net (弹性网络)
弹性网络在岭回归和Lasso回归中进行了折中,通过混合比(mix ratio) r 进行控制:
弹性网络的代价函数 :
回归模型选择:
- 常用:岭回归
- 假设只有少部分特征是有用的:
- 弹性网络
- Lasso
- 一般来说,弹性网络的使用更为广泛。因为在特征维度高于训练样本数,或者特征是强相关的情况下,Lasso回归的表现不太稳定。
在高维空间中,大多数训练数据驻留在定义特征空间的超立方体的角落中。
所需的训练实例数量随着使用的维度数量呈指数增长。
from sklearn.externals import joblib
def load_dump_demo():
"""
模型保存和加载
:return:
"""
# 1.获取数据
data = load_boston()
# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state=22)
# 3.特征工程-标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.机器学习-线性回归(岭回归)
# # 4.1 模型训练
# estimator = Ridge(alpha=1)
# estimator.fit(x_train, y_train)
#
# # 4.2 模型保存
# joblib.dump(estimator, "./data/test.pkl")
# 4.3 模型加载
estimator = joblib.load("./data/test.pkl")
# 5.模型评估
# 5.1 获取系数等值
y_predict = estimator.predict(x_test)
print("预测值为:\n", y_predict)
print("模型中的系数为:\n", estimator.coef_)
print("模型中的偏置为:\n", estimator.intercept_)
# 5.2 评价
# 均方误差
error = mean_squared_error(y_test, y_predict)
print("误差为:\n", error)
逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法,逻辑回归就是解决二分类问题的利器。
算法原理:将线性回归的输出作为逻辑回归的输入,然后经过sigmoid函数变换将整体的值映射到[0,1],再设定阈值进行分类。
from klearn.linear_models import LogisticRegression
# solver可选参数:{'liblinear', 'sag', 'saga','newton-cg', 'lbfgs'},
# 对于小数据集来说,“liblinear”是个不错的选择,而“sag”和'saga'对于大型数据集会更快。
# 对于多类问题,只有'newton-cg', 'sag', 'saga'和'lbfgs'可以处理多项损失;“liblinear”仅限于“one-versus-rest”分类。
# penalty:正则化的种类
# C:正则化力度
estimator = LogisticRegression(solver='liblinear', penalty=‘l2’, C = 1.0)
准确率
:所有样本中预测对的比例
精确率
:预测结果为正例样本中真实为正例的比例(预测为正的样本中的正样本)
召回率
:真实为正例的样本中预测结果为正例的比例(正样本中预测为正的样本)
F1-score
:反映模型的稳健性
from sklearn.metrics import classification_report
# labels:指定类别对应的数字 target_names:目标类别名称 return:每个类别精确率与召回率
ret = classification_report(y_test, y_predict, labels=(2,4), target_names=("良性", "恶性"))
击中率
>
虚惊率
>
AUC指标
API
from sklearn.metrics import roc_auc_score
# 计算所得为ROC曲线面积
roc_auc_score(y_test, y_predict)
增加一些少数类样本使得正、反例数目接近,然后再进行学习。
关于类别不平衡的问题,主要有两种处理方式:
1 过采样方法
# 使用imblearn进行随机过采样
from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler(random_state=0)
1.1 过采样经典方法
1 随机过采样法
通过复制所选择的样本生成样本集
缺点:易产生模型过拟合问题
2 SMOTE算法
(Synthetic Minority Oversampling,合成少数类过采样技术)
对每个少数类样本,从它的最近邻中随机选择一个样本,然后在两个样本之间的连线上随机选择一点作为新合成的少数类样本。
SMOTE算法摒弃了随机过采样复制样本的做法,可以防止随机过采样中容易过拟合的问题,实践证明此方法可以提高分类器的性能。
# SMOTE过采样
from imblearn.over_sampling import SMOTE
X_resampled, y_resampled = SMOTE().fit_resample(X, y)
2 欠采样方法
# 随机欠采样
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(random_state=0)
缺点:
- 随机欠采样方法通过改变多数类样本比例以达到修改样本分布的目的,从而使样本分布较为均衡,但由于采样的样本集合要少于原来的样本集合,因此会造成一些信息缺失,即将多数类样本删除有可能会导致分类器丢失有关多数类的重要信息。
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法
信息熵
(information entropy):度量样本集合纯度最常用的一种指标。
篮球比赛里,有4个球队 {A,B,C,D} ,获胜概率分别为{1/2, 1/4, 1/8, 1/8},求Ent(D)
信息增益
(information gain):以某特征划分数据集前后的熵的差值,用来衡量使用当前特征对于样本集合D划分效果的好坏。
通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。
1) 采样不同数据集
2) 训练分类器
3) 平权投票,获取最终结果
Bagging + 决策树/线性回归/逻辑回归/深度学习… = bagging集成学习方法
包外数据:没有选择到的数据,称之为 Out-of-bag(OOB)数据,当数据足够多,对于任意一组数据是包外数据的概率为1/e。
经验证,包外估计是对集成分类器泛化误差的无偏估计.
API实现
# n_estimators:(default = 10)森林里的树木数量
# Criterion:(default =“gini”) 分割特征的测量方法
# max_features="auto”,每个决策树的最大特征数量
"""
If "auto", then max_features=sqrt(n_features).
If "sqrt", then max_features=sqrt(n_features)(same as "auto").
If "log2", then max_features=log2(n_features).
If None, then max_features=n_features.
"""
# bootstrap:(default = True) 是否在构建树时使用放回抽样
# min_samples_split 内部节点再划分所需最小样本数
# min_samples_leaf 叶子节点的最小样本数
# min_impurity_split: 节点划分最小不纯度
sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)
每新加入一个弱学习器,整体能力就会得到提升,代表算法有:Adaboost,GBDT,XGBoost,LightGBM
Bagging集成与Boosting集成的区别
from sklearn.ensemble import AdaBoostClassifier
GBDT
GBDT 的全称是 Gradient Boosting Decision Tree,梯度提升树,在传统机器学习算法中,GBDT算的上TOP3的算法。
GBDT使用的决策树是CART回归树
无论是处理回归问题还是二分类以及多分类,GBDT使用的决策树通通都是都是CART回归树。
在这里插入图片描述
一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。
在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。
# n_clusters:开始的聚类中心数量
# 参数
# estimator.fit(x)
# estimator.predict(x)
# estimator.fit_predict(x)
sklearn.cluster.KMeans(n_clusters=8)
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score
# 创建数据集
# X为样本特征,Y为样本簇类别, 共1000个样本,每个样本2个特征,共4个簇,
# 簇中心在[-1,-1], [0,0],[1,1], [2,2], 簇方差分别为[0.4, 0.2, 0.2, 0.2]
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=9)
# 数据集可视化
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()
y_pred = KMeans(n_clusters=2, random_state=9).fit_predict(X)
# 分别尝试n_cluses=2\3\4,然后查看聚类效果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
# 用Calinski-Harabasz Index评估的聚类分数
print(calinski_harabaz_score(X, y_pred))
K-Means算法优缺点总结
优化方法
优化方法 | 思路 |
---|---|
Canopy+kmeans | Canopy粗聚类配合kmeans |
kmeans++ | 距离越远越容易成为新的质心 |
二分k-means | 拆除SSE最大的簇 |
k-medoids | 和kmeans选取中心点的方式不同 |
kernel kmeans | 映射到高维空间 |
ISODATA | 动态聚类,可以更改K值大小 |
Mini-batch K-Means | 大数据集分批聚类 |
商品评论情感分析
import pandas as pd
import numpy as np
import jieba
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
# 加载数据
data = pd.read_csv("./data/书籍评价.csv", encoding="gbk")
# 数据基本处理
# 2.1) 取出内容列,对数据进行分析
content = data["内容"]
# 2.2) 判定评判标准 -- 1好评;0差评
data.loc[data.loc[:, '评价'] == "好评", "评论标号"] = 1 # 把好评修改为1
data.loc[data.loc[:, '评价'] == '差评', '评论标号'] = 0
# data.head()
good_or_bad = data['评价'].values # 获取数据
print(good_or_bad)
# ['好评' '好评' '好评' '好评' '差评' '差评' '差评' '差评' '差评' '好评' '差评' '差评' '差评']
# 2.3) 选择停用词
# 加载停用词
stopwords=[]
with open('./data/stopwords.txt','r',encoding='utf-8') as f:
lines=f.readlines()
print(lines)
for tmp in lines:
line=tmp.strip()
print(line)
stopwords.append(line)
# stopwords # 查看新产生列表
#对停用词表进行去重
stopwords=list(set(stopwords))#去重 列表形式
print(stopwords)
# 2.4) 把“内容”处理,转化成标准格式
comment_list = []
for tmp in content:
print(tmp)
# 对文本数据进行切割
# cut_all 参数默认为 False,所有使用 cut 方法时默认为精确模式
seg_list = jieba.cut(tmp, cut_all=False)
print(seg_list) #
seg_str = ','.join(seg_list) # 拼接字符串
print(seg_str)
comment_list.append(seg_str) # 目的是转化成列表形式
# print(comment_list) # 查看comment_list列表。
# 2.5) 统计词的个数
# 进行统计词个数
# 实例化对象
# CountVectorizer 类会将文本中的词语转换为词频矩阵
con = CountVectorizer(stop_words=stopwords)
# 进行词数统计
X = con.fit_transform(comment_list) # 它通过 fit_transform 函数计算各个词语出现的次数
name = con.get_feature_names() # 通过 get_feature_names()可获取词袋中所有文本的关键字
print(X.toarray()) # 通过 toarray()可看到词频矩阵的结果
print(name)
# 2.6)准备训练集和测试集
# 准备训练集 这里将文本前10行当做训练集 后3行当做测试集
x_train = X.toarray()[:10, :]
y_train = good_or_bad[:10]
# 准备测试集
x_text = X.toarray()[10:, :]
y_text = good_or_bad[10:]
# 模型训练
# 构建贝叶斯算法分类器
mb = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参数
# 训练数据
mb.fit(x_train, y_train)
# 预测数据
y_predict = mb.predict(x_text)
#预测值与真实值展示
print('预测值:',y_predict)
print('真实值:',y_text)
# 模型评估
print(mb.score(x_text, y_text))
【data】数据
【classifier】分类
【optimization】最优化
【kernelling】核方法
【hyperplane】超平面
SVM(supported vector machine,支持向量机),即寻找到一个超平面使样本分成两类,并且间隔最大。
线性或非线性分类、回归,甚至是异常值检测
特别适用于中小型复杂数据集的分类
硬间隔:严格地让所有实例都不在最大间隔之间,并且位于正确的一边。它只在数据是线性可分离的时候才有效;其次,它对异常值非常敏感。
软间隔:尽可能在保持最大间隔宽阔和限制间隔违例(即位于最大间隔之上,甚至在错误的一边的实例)之间找到良好的平衡。
SVM Hinge损失(折页损失函数、铰链损失函数)
让尽可能多的实例位于预测线上,同时限制间隔违例(也就是不在预测线距上的实例)。
sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3,coef0=0.0,random_state=None)
"""
C:
惩罚系数,用来控制损失函数的惩罚系数,类似于线性回归中的正则化系数。
- C越大,相当于惩罚松弛变量,希望松弛变量接近0,即**对误分类的惩罚增大**,趋向于对训练集全分对的情况,这样会出现训练集测试时准确率很高,但泛化能力弱,容易导致过拟合。
- C值小,对误分类的惩罚减小,容错能力增强,泛化能力较强,但也可能欠拟合。
- kernel:
算法中采用的核函数类型,核函数是用来将非线性问题转化为线性问题的一种方法。
- 参数选择有RBF, Linear, Poly, Sigmoid或者自定义一个核函数。
- 默认的是"RBF",即径向基核,也就是高斯核函数;
- 而Linear指的是线性核函数,
- Poly指的是多项式核,
- Sigmoid指的是双曲正切函数tanh核;。
- degree:
- 当指定kernel为'poly'时,表示选择的多项式的最高次数,默认为三次多项式;
- 若指定kernel不是'poly',则忽略,即该参数只对'poly'有用。
- 多项式核函数是将低维的输入空间映射到高维的特征空间。
- coef0:核函数常数值(y=kx+b中的b值),
- 只有‘poly’和‘sigmoid’核函数有,默认值是0。
"""
sklearn.svm.LinearSVC(penalty='l2', loss='squared_hinge', dual=True, C=1.0)
"""
penalty:正则化参数,L1和L2两种参数可选,仅LinearSVC有。
loss:损失函数,有hinge和squared_hinge两种可选,前者又称L1损失,后者称为L2损失,默认是squared_hinge,其中hinge是SVM的标准损失,
squared_hinge是hinge的平方
dual:是否转化为对偶问题求解,默认是True。
C:惩罚系数,用来控制损失函数的惩罚系数,类似于线性回归中的正则化系数。
"""
隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。
马尔科夫链即为状态空间中从一个状态到另一个状态转换的随机过程。
马尔科夫链的无记忆性:下一状态的概率分布只能由当前状态决定,在时间序列中它前面的事件均与之无关。
1) 齐次马尔科夫链假设
2) 观测独立性假设
一个HMM模型,可以由隐藏状态初始概率分布Π , 状态转移概率矩阵A和观测状态概率矩阵B决定。Π,A决定状态序列,B决定观测序列。
因此,HMM模型可以由一个三元组λ
表示如下:
1)评估观察序列概率 —— 前向后向的概率计算
模型λ
=(A,B,Π)和观测序列
O={o_1,o_2,…o_T},计算在模型λ下某一个观测序列O出现的概率
P(O|λ)。2)预测问题,也称为解码问题 ——维特比(Viterbi)算法
模型λ
=(A,B,Π)和观测序列
O={o_1,o_2,…o_T},求给定观测序列条件下,最可能出现的对应的状态序列
。3)模型参数学习问题 —— 鲍姆-韦尔奇(Baum-Welch)算法(状态未知) ,这是一个学习问题
观测序列
O={o_1,o_2,…o_T},估计模型λ
=(A,B,Π)的参数,使该模型下观测序列的条件概率P(O∣λ)最大。import numpy as np
from hmmlearn import hmm
# 设定隐藏状态的集合
states = ["box 1", "box 2", "box3"]
n_states = len(states)
# 设定观察状态的集合
observations = ["red", "white"]
n_observations = len(observations)
# 设定初始状态分布
start_probability = np.array([0.2, 0.4, 0.4])
# 设定状态转移概率分布矩阵
transition_probability = np.array([
[0.5, 0.2, 0.3],
[0.3, 0.5, 0.2],
[0.2, 0.3, 0.5]
])
# 设定观测状态概率矩阵
emission_probability = np.array([
[0.5, 0.5],
[0.4, 0.6],
[0.7, 0.3]
])
# 设定模型参数
model = hmm.MultinomialHMM(n_components=n_states)
model.startprob_=start_probability # 初始状态分布
model.transmat_=transition_probability # 状态转移概率分布矩阵
model.emissionprob_=emission_probability # 观测状态概率矩阵
seen = np.array([[0,1,0]]).T # 设定观测序列
box = model.predict(seen)
print("球的观测顺序为:\n", ", ".join(map(lambda x: observations[x], seen.flatten())))
# 注意:需要使用flatten方法,把seen从二维变成一维
print("最可能的隐藏状态序列为:\n", ", ".join(map(lambda x: states[x], box)))
print(model.score(seen))
# 输出结果是:-2.03854530992
# 对数处理结果,概率值
import math
math.exp(model.score(seen))
# ln0.13022≈−2.0385
# 输出结果是:0.13021800000000003
XGBoost(Extreme Gradient Boosting)全名叫极端梯度提升树,XGBoost是集成学习方法的王牌,在Kaggle数据挖掘比赛中,大部分获胜者用了XGBoost。
构建最优模型的一般方法是最小化训练数据的损失函数
目标函数,即损失函数,通过最小化损失函数来构建最优模型。
其中yi是模型的实际输出结果,yi是模型的输出结果;
等式右边第一部分是模型的训练误差,第二部分是正则化项,这里的正则化项是K棵树的正则化项相加而来的。
XGBoost使用CART树,则树的复杂度为
其中T为叶子节点的个数,||w||为叶子节点向量的模 。γ表示节点切分的难度,λ表示L2正则化系数。
主要由三种类型构成:
1 通用参数(general parameters):主要是宏观函数控制;
booster [缺省值=gbtree]
决定使用哪个booster,可以是gbtree,gblinear或者dart。
silent [缺省值=0]
nthread [缺省值=设置为最大可能的线程数]
2 Booster参数(booster parameters):取决于选择的Booster类型,用于控制每一步的booster(tree, regressiong);
3 学习目标参数(task parameters):控制训练目标的表现。
objective [缺省值=reg:linear]
eval_metric [缺省值=通过目标函数选择]
可供选择的如下所示:
“rmse”: 均方根误差
“mae”: 平均绝对值误差
“logloss”: 负对数似然函数值
“
“error@t”: 不同的划分阈值可以通过 ‘t’进行设置
“merror”: 多分类错误率,计算公式为(wrong cases)/(all cases)
“mlogloss”: 多分类log损失
“auc”: 曲线下的面积
seed [缺省值=0]
泰坦尼克号乘客存活分析
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
# 1、获取数据
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
# 2.数据基本处理
# 2.1 确定特征值,目标值
x = titan[["pclass", "age", "sex"]]
y = titan["survived"]
# 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
x['age'].fillna(x['age'].mean(), inplace=True)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 对于x转换成字典数据x.to_dict(orient="records")
# [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]
# 3.特征工程(字典特征抽取)
transfer = DictVectorizer(sparse=False)
x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.fit_transform(x_test.to_dict(orient="records"))
# 4.xgboost模型训练和模型评估
# 模型初步训练
from xgboost import XGBClassifier
xg = XGBClassifier()
xg.fit(x_train, y_train)
print(xg.score(x_test, y_test))
# 针对max_depth进行模型调优
depth_range = range(10)
score = []
for i in depth_range:
xg = XGBClassifier(eta=1, gamma=0, max_depth=i)
xg.fit(x_train, y_train)
s = xg.score(x_test, y_test)
print(s)
score.append(s)
# 结果可视化
import matplotlib.pyplot as plt
plt.plot(depth_range, score)
plt.show()
LightGBM提出的主要原因就是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地用于工业实践。
GBDT在每一次迭代的时候,都需要遍历整个训练数据多次。
如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。
尤其面对工业级海量的数据,普通的GBDT算法是不能满足其需求的。
在开源之后,就被别人冠以“速度惊人”、“支持分布式”、“代码清晰易懂”、“占用内存小”等属性。
LightGBM主打的高效并行训练让其性能超越现有其他boosting工具。在Higgs数据集上的试验表明,LightGBM比XGBoost快将近10倍
,内存占用率大约为XGBoost的1/6
。
LightGBM 主要基于以下方面优化,提升整体特特性:
基于Histogram(直方图)的决策树算法
直方图算法的基本思想是
内存消耗的降低,计算上的代价也大幅降低
Lightgbm 的Histogram(直方图)做差加速
一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。
通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的k个桶。
利用这个方法,LightGBM可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。
带深度限制的Leaf-wise的叶子生长策略
Level-wise便利一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。
Leaf-wise则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。
直接支持类别特征
实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化到多维的0/1特征,降低了空间和时间的效率。
而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。
在Expo数据集上的实验,相比0/1展开的方法,训练速度可以加速8倍,并且精度一致。目前来看,LightGBM是第一个直接支持类别特征的GBDT工具。
直接支持高效并行
LightGBM还具有支持高效并行的优点。LightGBM原生支持并行学习,目前支持特征并行和数据并行的两种。
LightGBM针对这两种并行方法都做了优化:
4.1 Control Parameters
Control Parameters | 含义 | 用法 |
---|---|---|
max_depth | 树的最大深度 | 当模型过拟合时,可以考虑首先降低 max_depth |
min_data_in_leaf | 叶子可能具有的最小记录数 | 默认20,过拟合时用 |
feature_fraction | 例如 为0.8时,意味着在每次迭代中随机选择80%的参数来建树 | boosting 为 random forest 时用 |
bagging_fraction | 每次迭代时用的数据比例 | 用于加快训练速度和减小过拟合 |
early_stopping_round | 如果一次验证数据的一个度量在最近的early_stopping_round 回合中没有提高,模型将停止训练 | 加速分析,减少过多迭代 |
lambda | 指定正则化 | 0~1 |
min_gain_to_split | 描述分裂的最小 gain | 控制树的有用的分裂 |
max_cat_group | 在 group 边界上找到分割点 | 当类别数量很多时,找分割点很容易过拟合时 |
n_estimators | 最大迭代次数 | 最大迭代数不必设置过大,可以在进行一次迭代后,根据最佳迭代数设置 |
4.2 Core Parameters
Core Parameters | 含义 | 用法 |
---|---|---|
Task | 数据的用途 | 选择 train 或者 predict |
application | 模型的用途 | 选择 regression: 回归时, binary: 二分类时, multiclass: 多分类时 |
boosting | 要用的算法 | gbdt, rf: random forest, dart: Dropouts meet Multiple Additive Regression Trees, goss: Gradient-based One-Side Sampling |
num_boost_round | 迭代次数 | 通常 100+ |
learning_rate | 学习率 | 常用 0.1, 0.001, 0.003… |
num_leaves | 叶子数量 | 默认 31 |
device | cpu 或者 gpu | |
metric | mae: mean absolute error , mse: mean squared error , binary_logloss: loss for binary classification , multi_logloss: loss for multi classification |
4.3 IO parameter
IO parameter | 含义 |
---|---|
max_bin | 表示 feature 将存入的 bin 的最大数量 |
categorical_feature | 如果 categorical_features = 0,1,2, 则列 0,1,2是 categorical 变量 |
ignore_column | 与 categorical_features 类似,只不过不是将特定的列视为categorical,而是完全忽略 |
save_binary | 这个参数为 true 时,则数据集被保存为二进制文件,下次读数据时速度会变快 |
调参建议
IO parameter | 含义 |
---|---|
num_leaves |
取值应 <= 2^{(max_depth)}2(max_depth), 超过此值会导致过拟合 |
min_data_in_leaf |
将它设置为较大的值可以避免生长太深的树,但可能会导致 underfitting,在大型数据集时就设置为数百或数千 |
max_depth |
这个也是可以限制树的深度 |
下表对应了 Faster Speed ,better accuracy ,over-fitting 三种目的时,可以调的参数
Faster Speed | better accuracy | over-fitting |
---|---|---|
将 max_bin 设置小一些 |
用较大的 max_bin |
max_bin 小一些 |
num_leaves 大一些 |
num_leaves 小一些 |
|
用 feature_fraction 来做 sub-sampling |
用 feature_fraction |
|
用 bagging_fraction 和 bagging_freq |
设定 bagging_fraction 和 bagging_freq |
|
training data 多一些 | training data 多一些 | |
用 save_binary 来加速数据加载 |
直接用 categorical feature | 用 gmin_data_in_leaf 和 min_sum_hessian_in_leaf |
用 parallel learning | 用 dart | 用 lambda_l1, lambda_l2 ,min_gain_to_split 做正则化 |
num_iterations 大一些,learning_rate 小一些 |
用 max_depth 控制树的深度 |
鸢尾花数据集处理
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error
import lightgbm as lgb
# 加载数据
iris = load_iris()
data = iris.data
target = iris.target
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# 模型训练
gbm = lgb.LGBMRegressor(objective='regression', learning_rate=0.05, n_estimators=20)
gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1', early_stopping_rounds=5)
print(gbm.score(X_test, y_test))
# 0.810605595102488
# 网格搜索,参数优化
estimator = lgb.LGBMRegressor(num_leaves=31)
param_grid = {
'learning_rate': [0.01, 0.1, 1],
'n_estimators': [20, 40]
}
gbm = GridSearchCV(estimator, param_grid, cv=4)
gbm.fit(X_train, y_train)
print('Best parameters found by grid search are:', gbm.best_params_)
# Best parameters found by grid search are: {'learning_rate': 0.1, 'n_estimators': 40}
# 模型调优
gbm = lgb.LGBMRegressor(num_leaves=31, learning_rate=0.1, n_estimators=40)
gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1', early_stopping_rounds=5)
print(gbm.score(X_test, y_test))
# 0.9536626296481988
1.1 方法一:
from sklearn.datasets import load_iris
iris = load_iris()
1.2 方法二:
import pandas as pd
data = pd.read_csv("C:\\data\\FBlocaltion\\train.csv")
# (备选):缺失值处理
data = data.replace(to_replace="?", value=np.NaN)
data = data.dropna()
# x_train,x_test,y_train,y_test为训练集特征值、测试集特征值、训练集目标值、测试集目标值
# x:数据集的特征值 y:数据集的标签值 test_size:测试集的大小,一般为float random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
# 通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程
# 方法一:( 标准化) <在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。>
from sklearn.preprocessing import StandardScaler
transfer = StandardScaler()
# 方法二:(归一化) <鲁棒性较差,只适合传统精确小数据场景。>
from sklearn.preprocessing import StandardScaler
transfer = MinMaxScaler()
# 方法三:(特征工程(字典特征抽取))
from sklearn.feature_extraction import DictVectorizer
transfer = DictVectorizer(sparse=False)
# 特征中出现类别符号,需要进行one-hot编码处理(DictVectorizer),x.to_dict(orient="records") 需要将数组特征转换成字典数据
x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.fit_transform(x_test.to_dict(orient="records"))
# 对部分数据先拟合fit,找到该part的整体指标,如均值、方差、最大值最小值等等(根据具体转换的目的),然后对该trainData进行转换transform,从而实现数据的标准化。
x_train = transfer.fit_transform(x_train)
# 对剩余的数据(testData)使用同样的均值、方差、最大最小值等指标进行转换transform(testData),从而保证train、test处理方式相同。
x_test = transfer.transform(x_test)
# 方法一:(K-近邻算法)
from sklearn.neighbors import KNeighborsClassifier
# n_neighbors:查询默认使用的邻居数(默认= 5)
# algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’}
estimator = KNeighborsClassifier(n_neighbors=7,algorithm='auto')
# 方法二:(线性回归)
from sklearn.linear_model import LinearRegression
estimator = LinearRegression()
# 方法三:(逻辑回归)
from sklearn.linear_model import LogisticRegression
estimator = LogisticRegression()
# 方法四:(决策树)
from sklearn.tree import DecisionTreeClassifier, export_graphviz
# criterion:特征选择标准("gini"或者"entropy"),前者代表基尼系数,后者代表信息增益。默认"gini",即CART算法。
# min_samples_split:内部节点再划分所需最小样本数(默认:2)
# min_samples_leaf:叶子节点最少样本数(默认:1)
# max_depth:决策树最大深度(10-100)# random_state:随机数种子
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
# 方法一:(网格搜索)
# estimator:估计器对象 param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]} cv:指定几折交叉验证
from sklearn.model_selection import GridSearchCV
estimator = GridSearchCV(estimator, param_grid={
"n_neighbors": [1, 3, 5]}, cv=3)
# 方法二:(留出法)
from sklearn.model_selection import train_test_split
train_X , test_X, train_Y ,test_Y = train_test_split(X, Y, test_size=0.2,random_state=0)
# 方法三:(留一法)
from sklearn.model_selection import LeaveOneOut
data = [1, 2, 3, 4]
loo = LeaveOneOut()
for train, test in loo.split(data):
print("%s %s" % (train, test))
# 方法四:(K折交叉验证)
from sklearn.model_selection import KFold
folder = KFold(n_splits = 4, random_state=0, shuffle = False)
# 方法五:(分层K折交叉验证)
from sklearn.model_selection import StratifiedKFold
sfolder = StratifiedKFold(n_splits = 4, random_state = 0, shuffle = False)
# 方法六:(自助法)
estimator.fit(x_train, y_train)
# 方法一:比对真实值和预测值
y_predict = estimator.predict(x_test)
print(">>>预测结果为:\n", y_predict)
print(">>>比对真实值和预测值:\n", y_predict == y_test)
# 方法二:回归系数(线性回归)
# 回归系数(regression coefficient):在回归方程中表示自变量x 对因变量y 影响大小的参数。回归系数越大表示x 对y 影响越大,正回归系数表示y 随x 增大而增大,负回归系数表示y 随x增大而减小。
print('回归系数:\n', estimator.coef_)
estimator.predict([[100, 80]]) # 平时成绩100, 期末成绩80的概率
# 方法二:直接计算准确率
score = estimator.score(x_test, y_test)
print(">>>准确率为:\n", score)
print(">>>预测最优得分:\n", estimator.best_score_)
print(">>>最优估计器:\n", estimator.best_estimator_)
print(">>>最优结果:\n", pd.DataFrame(estimator.cv_results_))
# 方法三:分类评估报告生成
from sklearn.metrics import classification_report
ret = classification_report(y_test, y_predict, labels=(2, 4), target_names=("良性", "恶性")
# 方法四:AUC指标评测
from sklearn.metrics import roc_auc_score
# 0.5~1之间,越接近于1约好
y_test = np.where(y_test > 2.5, 1, 0)
roc_auc_score(y_test, y_predict)