一、sklearn数据集与估计器
1.sklearn数据集
1.数据集划分
一般划分两部分
训练集:用于训练,构建模型 (70%,75%,80%)
测试集:在模型检验时使用,用于评估模型是否有效 (30%,25%,20%)
一般划分75%,25%比较好
API
sklearn.model_selection.train_test_split
- sklearn.datasets
加载获取流行数据集
- datasets.load_*()
获取小规模数据集,数据包含在datasets里 - datasets.fetch_*(data_home=None)
获取大规模数据集,需要从网络上下载,函数第一个参数是data_home,表示数据集下载的目录,默认是~/scikit_learn_data/
获取数据集返回的类型
load和fetch返回的数据类型datasets.base.Bunch(字典格式)
- data:特征数据数组,是[n_samples*n_features]的二维numpy.ndarray数据
- target:标签数组,是n_samples的一维numpy.ndarray数组
- DESCR:数据描述
- feature_names:特征名, 新闻数据、手写数字、回归数据集没有
- target_names:标签名
from sklearn.datasets import load_iris
iris = load_iris()
print("获取特征值",iris.data)
print("获取目标值",iris.target)
print(iris.DESCR)
2.sklearn数据集的接口介绍
数据集进行分割
**sklearn.model_selection.train_test_split(*arrays,options)
- x 数据集的特征值
- y 数据集的标签值
- test_size 测试集的大小,一般为float
- random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
- return 训练集特征值,测试集特征值,训练标签,测试标签(默认随机取)
示例:划分训练集与测试集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=0,test_size=0.25)
3.sklearn分类数据集
sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
- subset:‘train’或者‘test’,‘all’,可选,选择要加载的数据集,训练集的‘训练’,测试集的‘测试’,两者的‘全部’
- dataset.clear_data_home(data_home=None)
清除目录下的数据
4.sklearn回归数据集
sklearn.datasets.load_boston()
加载并返回波士顿房价数据集
sklearn.datasets_load_diabetes()
加载并返回糖尿病数据集
5.转换器与估计器
转换器类(transformer)
-
fit():输入数据 (类似建立公式f(x),不同的数据调用fit(),会得到不同的公式)
-
transform(): 进行数据的转换 (类似运算)
-
fit_transform():输入数据直接转换
sklear机器学习算法的实现-估计器(estimator)
在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API
1.用于分类的估计器:
- sklean.neighbors k-近邻算法
- sklearn.naive_bayes 贝叶斯
- sklearn.linear_model.logistcRegression 逻辑回归
- sklearn.tree 决策树
2.用于回归的估计器
- sklearn.linear_model.LinearRegression 线性回归
- sklearn.linear_model.Ridge 岭回归
1.y_predict= predict(x_test)
2.预测的准确率:score(x_test,y_test)
二、分类算法-K近邻算法(几乎不用)
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
欧式距离公式:
k-近邻算法需要做标准化处理
sklearn k-近邻算法API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto)
- n_neighbors: int可选(默认=5),k_neighbors查询默认使用的邻居数
- algorithm: {‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法;‘ball_tree’将会使用BallTree,‘kd_tree’将使用KDTree,‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。(不同实现方式影响效率)
以鸢尾花数据集示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
iris_datasets = load_iris() #实例化数据集
print(iris_datasets.keys())
X_train, X_test, y_train, y_test = train_test_split(iris_datasets['data'], iris_datasets['target'],random_state=0)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train,y_train)
prediction = knn.predict(X_test)
print(prediction)
print("Predicted target name: {}".format(iris_datasets['target_names'][prediction]))
问题:
1.K值取多大? 有什么影响?
K值取很小:容易受异常点影响
K值取很大:容易受K值数量(类别)波动)
2.性能问题
**优点:**简单,易于理解,容易实现,无需估计参数,无需训练
缺点:
懒惰算法,对测试样本分类时的计算量大。内存开销大
必须指定K值,K值选择不当则分类精度不能保证
**使用场景:**小数据场景,几千~几万样本,具体场景具体业务去测试
三、分类算法-朴素贝叶斯算法(常用于文本分类,神经网络会比较好)
1.概率基础
所有特征之间是条件独立的
2.朴素贝叶斯介绍
特征独立
公式:
注:W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
公式可以理解为:
其中C可以是不同类别
公式分为三个部分:
P( C ):每个文档类别的概率(某文档类别数/总文档数量)
P(W|C):给定类别下特征(被预测文档中出现的词)的概率
计算方法:P(F1|C) = Ni/N (训练文档中去计算)
Ni为该F1词在C类别所有文档中出现的次数
N为所属类别C下的文档所有词出现的次数和
P(F1,F2,…)预测文档中每个词的概率
示例:
训练集统计结果(指定统计词频):
特征\统计 | 科技(30篇) | 娱乐(60篇) | 汇总(90篇) |
---|---|---|---|
“商场” | 9 | 51 | 60 |
“影院” | 8 | 56 | 64 |
“支付宝” | 20 | 15 | 35 |
“云计算” | 63 | 0 | 63 |
“汇总(求和)” | 100 | 121 | 221 |
现有一篇被预测文档:出现了影院,支付宝,云计算,计算属于科技/娱乐的类别概率?
P(科技|影院,支付宝,云计算)=P(影院,支付宝,云计算|科技)P(科技)
=8/10020/10063/100*30/90
P(娱乐|影院,支付宝,云计算)=P(影院,支付宝,云计算|娱乐)P(娱乐)
=56/12115/1210/121*60/90
=0
问题:从上面的例子我们得到娱乐概率为0,这是不合理的,如果词频列表里面有很多出现次数都为0,很可能计算结果都为零。
解决方法:拉普拉斯平滑系数
α为指定的系数一般为1,m为训练文档中统计出的特征词个数
以上式子变为:
=(56+1)/(121+1) * (15+1)/(121+1)*(0+1)/(121+1)*60/90
API
sklearn.naive_bayes.MultinomiaNB(alpha=1.0)
- 朴素贝叶斯分类
- alpha:拉普拉斯平滑系数
注:朴素贝叶斯没有超参数,不能通过调参调优,所以对训练集要求比较高。
朴素贝叶斯算法优缺点:
优点:
- 朴素贝叶斯模型发源于古典教学理论,有稳定的分类效率。
- 对缺失数据不太敏感,算法也比较简单,常用于文本分类。
- 分类准确度高,速度块。
缺点:
- 由于使用了样本属性独立的假设,所以如果样本属性有关联时其效果不好
四、朴素贝叶斯算法实例
示例:
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
#实例化加载新闻数据,’all’加载全部数据
news = fetch_20newsgroups(subset="all")
#数据分割
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,random_state=0)
# Tfidf文本特征抽取
tf = TfidfVectorizer()
x_train=tf.fit_transform(x_train)
# print(tf.get_feature_names())
#出问题:MemoryError: Unable to allocate 14.9 GiB for an array with shape (14134, 141276) and data type float64
# print(x_train.toarray())
x_test = tf.transform(x_test)
# 实例化朴素贝叶斯算法
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train,y_train)
#进行朴素贝叶斯算法预测
y_prediction = mlt.predict(x_test)
print('预测文章类别为',y_prediction)
print('训练集集准确率为:',mlt.score(x_test,y_test))
print('测试集准确率为:',mlt.score(x_test,y_test))
五、模型的选择与调优
分类模型的评估
1.estimator.score()
- 一般最常见使用的式准确率,即预测结果正确的百分比
2.混淆矩阵
在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适合于多分类)
正例 | 反例 | |
---|---|---|
正例 | 真正例TP(true positive) | 伪反利FN(false negative) |
反例 | 伪正例FP | 真反利TN |
评估标准:
精确率(Precision)和召回率(Recall)
精确率: 预测结果为正例样本中真实为正例的比例(查得准)
召回率: 真实为正例的样本中预测结果为正例的比例(查得全,对正样本得区分能力)
- 准确率(Accuracy) = (TP + TN) / 总样本
- 精确率(Precision) = TP / (TP + FP)
- 召回率(Recall) = TP / (TP + FN)
准确率就是找得对,召回率就是找得全
其他分类标准:F1-score,反映了模型得稳健性
公式:
API
sklearn.metrics.classification_report
sklearn.metrics.classification_report(y_true,y_pred,target_names=None)
- y_true: 真实目标值
- y_prrd:估计器预测目标值n
- target_names:目标类别名称
- return:每个类别精确率与召回率
接上例 朴素贝叶斯算法 - fetch_20newsgroups数据集 为示例
from sklearn.metrics import classification_report
report=classification_report(y_test,y_prediction,target_names=news.target_names)
print(report)
结果输出:
模型的选择与调优
1.交叉验证
目的:为了让评估的模型更加准确可信
所有数据分为n等份,每份进行数据验证,最后求平均值得到结果。(常用10折)
2.网格搜索(超参数搜索)
作用:调参数
通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的k值),这种叫超参数,但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都是采用交叉验证来进行评估。最后选出最优参数组合建立模型。
K值 | K=3 | K=5 | k=7 |
---|---|---|---|
模型 | 模型1 | 模型2 | 模型3 |
API
sklearn.model_selection.GridSearchCV
sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)
- 对估计器的指定参数值进行详尽搜索
- param_grid:估计器参数(dict){‘n_neighbors’:[1,3,5]}
- cv:指定几折交叉验证
- fit:输入训练数据
- score:准确率
- 结果分析:
- best_score_:在交叉验证中验证的最好结果
- best_estimator_:最好的参数模型
- cv_results_:每次交叉验证后的测试集准确率结果和训练集准确结果
示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
iris = load_iris()
cv = GridSearchCV(KNeighborsClassifier(),param_grid={'n_neighbors':[5,7,10]},cv=2)
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=0,test_size=0.25)
cv.fit(x_train,y_train)
print('在测试集上准确率',cv.score(x_test,y_test))
print('交叉验证最好的结果',cv.best_score_)
print('最好的模型是',cv.best_estimator_)
print('每个超参数每次交叉验证的结果',cv.cv_results_)
六、决策树与随机森林
决策树
认识决策树:
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
信息的度量和作用:信息和消除不确定性是相联系的
决策树的划分依据之一:信息增益
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件熵H(D|A)之差,即公式为:
注:信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。
常见决策树使用的算法:
ID3
信息增益 最大的准则
C4.5
信息增益比 最大的准则
CART
回归树:平方误差 最小
分类树:基尼系数 最小的准则 在sklearn中可以选择划分的默认原则
API
class sklearn,tree.DecisionTreeClasssifier(criterion=‘gini’,max_depth=None,random_state=None)
- 决策树分类器
- criterion:默认是‘gini’系数,也可以选择信息增益的熵‘entropy’
- max_depth:树的深度大小
- random_state:随机数种子
- method:
- decision_path:返回决策树的路径
示例:泰坦尼克号生存预测数据集
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction import DictVectorizer
train = pd.read_csv(r'C:\Desktop\titanic\train.csv')
test = pd.read_csv(r'C:\Desktop\titanic\test.csv')
y_test = pd.read_csv(r'C:\Desktop\titanic\gender_submission.csv')
print('训练集表头:',train.columns)
print('测试集表头:',test.columns)
x_train = train[['Pclass','Age','Sex']]
y_train = train['Survived']
x_train['Age'].fillna(x_train['Age'].mean(),inplace=True)
x_test = test[['Pclass','Age','Sex']]
x_test['Age'].fillna(x_test['Age'].mean(),inplace=True)
y_test = y_test['Survived']
#进行特征工程(one-hot)
dict =DictVectorizer(sparse=False)
#pd转换字典,x_train.to_dict('records')把每一行转换成字典
x_train=dict.fit_transform(x_train.to_dict('records'))
x_test = dict.transform(x_test.to_dict('records'))
tree = DecisionTreeClassifier()
tree.fit(x_train,y_train)
print(tree.score(x_test,y_test))
决策树的结构,本地保存
1.sklearn.tree.export_graphviz 该函数能够导出DOT格式
tree.export_graphviz(estimator,out_file=‘tree.dot,feature_names=[","])
from sklearn.tree import export_graphviz
print(dict.get_feature_names())
export_graphviz(tree,out_file='tree.dot',feature_names=['Age', 'Pclass', 'Sex=female', 'Sex=male'])
2.工具:(能够将dot文件转换为pdf、pdg)
安装graphviz
Windows下载请参考https://www.cnblogs.com/onemorepoint/p/8310996.html
3.运行命令
先在命令窗口切换到dot文件所在目录再运行命令
$ dot-Tpng tree.dot -o tree.png
图片如下:
决策树的优缺点:
优点:
- 简单的了解和解释,树木可视化
- 需要很少的数据准备,其他技术通常需要数据归一化
缺点:
- 决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。
改进:
- 减少cart算法(决策树API当中已经实现,随机森林参数调优有关介绍)
- 随机森林
注:企业重要决策,由于决策树很好地分析能力,在决策过程应用较多。
随机森林
集成学习方法
集成学习通过建立几个模型组合来解决单一预测问题。它的工作原理是生产多个分类/模型,各自独立地学习和做出预测,这些预测最后结合成单预测,因此由于任何一个单分类的做出预测。
什么是随机森林
定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
单个决策树建立:
假设有N个样本,M个特征
1.在N个样本当中选择一个样本,重复N次,样本有可能重复
2.随机在M个特征当中选出m个特征,m<<M,建立决策树
采取bootstrap采样
为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集一样,那么最终训练出的树分类结果也是完全一样的
为什么要又放回抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。
API
class sklearn.ensemble.RandomForestClassfier(n_estimators=10,criterion=‘gini’,max_depth=None,bootstrap=True,random_state=None)
- 随机森林分类器
- n_estimators:integer,optional(default=10)森林里的树木数量
- criteria:string,可选(default=‘gini’)分割特征的测量方法
- max_depth:integer或者None,可选(默认=无) 数的最大深度
- max_feature=‘auto’每个决策树的最大特征数量
auto: max_featues=sqrt(n_features)
sqrt:: max_featues=sqrt(n_features) (same as ‘auto’)
log2: max_featues=log2(n_features)
None:max_featues=n_features - bootstrp:boolean,optional(default=True)是否在构建树时使用放回抽样
调参:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
rf = RandomForestClassifier(random_state=0)
param = {'n_estimators':[50,100,150],'max_depth':[5,10,20]}
gc = GridSearchCV(rf,param_grid=param,cv=2)
gc.fit(x_train,y_train)
print(gc.score(x_test,y_test))
print(gc.best_params_)
随机森林的优缺点:
几乎没有缺点
优点:
- 在当前所有算法中,具有极好的准确率
- 能够有效运行在大数据集上
- 能够处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性