学习笔记:机器学习day2

一、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个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
欧式距离公式:
( a 1 + b 1 ) 2 + ( a 2 + b 2 ) 2 + ( a 3 + b 3 ) 2 \sqrt {(a_1+b_1)^2+(a_2+b_2)^2+(a_3+b_3)^2}
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.朴素贝叶斯介绍
特征独立
公式:
P ( C W ) = P ( W C ) P ( C ) P ( W ) P(C|W) = \frac{P(W|C)P(C)}{P(W)}
注:W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
公式可以理解为:
P ( C F 1 , F 2 , . . . ) = P ( F 1 , F 2 , . . . C ) P ( C ) P ( F 1 , F 2... ) P(C|F1,F2,...) = \frac{P(F1,F2,...|C)P(C)}{P(F1,F2...)}
其中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,很可能计算结果都为零。

解决方法:拉普拉斯平滑系数
P ( F 1 C ) = N I + α N + α m P(F1|C)= \frac{N_I + α}{N+α_m}
α为指定的系数一般为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,反映了模型得稳健性
公式:
F 1 = 2 T P 2 T P + F N + F P = 2 P r e c i s i o n R e c a l l P r e c i s i o n + R e c a l l F_1= \frac{2TP}{2TP+FN+FP} = \frac{2*Precision*Recall}{Precision+Recall}

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)之差,即公式为:
g ( D , A ) = H ( D ) H ( D A ) g(D,A)=H(D)-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_)

随机森林的优缺点:

几乎没有缺点

优点:

  • 在当前所有算法中,具有极好的准确率
  • 能够有效运行在大数据集上
  • 能够处理具有高维特征的输入样本,而且不需要降维
  • 能够评估各个特征在分类问题上的重要性
发布了5 篇原创文章 · 获赞 5 · 访问量 136

猜你喜欢

转载自blog.csdn.net/Rick_Restart/article/details/105629272