AI | 第2章 机器学习算法 - sklearn 分类算法


前言

仅供参考


1. sklearn 的转换器和估计器

1.1 转换器

  • 特征工程的步骤:实例化一个转换器类(Transformer)、调用 fit_transform() 方法;
  • 把特征工程的接口称之为转换器,其中转换器调用有这么几种形式:
    • fit_transform:fit 与 transform 的合成;
    • fit:进行列计算(例如标准化:求 mean);
    • transform:最终转换(例如标准化:求 (x-mean)/std);

1.2 估计器

  • 作用:sklearn 机器学习算法的实现;
  • sklearn 拥有的估计器
    • 用于分类的估计器:
      • sklearn.neighbors k-近邻算法;
      • sklearn.naive_bayes 贝叶斯;
      • sklearn.linear_model.LogisticRegression 逻辑回归;
      • sklearn.tree 决策树与随机森林;
    • 用于回归的估计器:
      • sklearn.linear_model.LinearRegression 线性回归;
      • sklearn.linear_model.Ridge 岭回归;
    • 用于无监督学习的估计器:
      • sklearn.cluster.KMeans 聚类;
  • 步骤
    • 实例化一个 estimator;
    • 调用 estimator.fit(x_train, y_train) 方法计算,调用完毕模型生成;
    • 模型评估:直接比对预测值与真实值、计算准确率 estimator.score(x_test, y_test)
  • 工作流程
    估计器工作流程

2. K-近邻算法(KNN 算法)

2.1 概述

  • 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别;
  • 距离公式:欧式距离 r = ( a 1 − b 1 ) 2 + ( a 2 − b 2 ) 2 + ( a 3 − b 3 ) 2 r=\sqrt{(a_1-b_1)^2 + (a_2-b_2)^2 + (a_3-b_3)^2} r=(a1b1)2+(a2b2)2+(a3b3)2
    • 其他:曼哈顿距离(绝对值距离)、明科夫斯基距离 minkowski;
  • 问题
    • K 值取得过小,容易受到异常点影响;
    • K 值取得过大,会有样本不均匀的影响;
    • 需要先进行无量钢化处理-标准化;
  • 优点
    • 简单,易于理解,易于实现,无需训练;
  • 缺点
    • 懒惰算法,对测试样本分类时的计算量大,内存开销大;
    • 必须指定 K 值,K 值选择不当则分类精度不能保证;
  • 应用场景:小数据场景,几千~几万样本,具体场景具体业务去测试;

2.2 应用

  • 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 方法的值来决定最合适的算法。 (不同实现方式影响效率)
*Code1 KNN 算法代码示例
def knn_iris():
    # 1.获取数据
    iris = load_iris()
    print(iris)
    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)
    print(x_train)
    print(x_test)
    print(y_train)
    print(y_test)
    # 3.特征工程:标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test) #测试集使用训练集的数据(平均值)等进行标准化
    # 4.KNN 算法预估器
    estimator = KNeighborsClassifier(n_neighbors=3)
    estimator.fit(x_train, y_train)
    # 5.模型评估
    # 方法一:直接比对预测值与真实值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("y_test:\n", y_test)
    print("预测值与真实值比对:\n",  y_predict == y_test)
    # 方法二:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)

    return None

3. 模型选择与调优

3.1 交叉验证 cross validation

  • 目的:为了让被评估的模型更加准确可信;
  • 定义:将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成 4 份,其中一份作为验证集。然后经过 4 次(组)的测试,每次都更换不同的验证集。即得到 4 组模型的结果,取平均值作为最终结果。又称 4 折交叉验证。

 4 折交叉验证

3.2 超参数搜索-网格搜索 Grid Search

  • 超参数:有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数;
  • 网格搜索:但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型;
  • 模型选择与调优
    • API:sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
      • 对估计器的指定参数值进行详尽搜索;
      • estimator:估计器对象;
      • param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]};
      • cv:指定几折交叉验证;
      • fit:输入训练数据;
      • score:准确率;
      • 结果分析:
        • bestscore:在交叉验证中验证的最好结果;
        • bestestimator:最好的参数模型;
        • cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结果;

 超参数搜索-网格搜索

*Code2 网格搜索代码示例
def knncls():
    # 一、处理数据以及特征工程
    # 1、读取收
    data = pd.read_csv("../resources/p01_machine_learning_sklearn/FBlocation/train.csv")

    # 2、数据处理
    # 1)数据逻辑筛选操作,缩小数据的范围 df.query()
    data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
    # 2)处理时间特征
    time_value = pd.to_datetime(data["time"], unit="s")
    date = pd.DatetimeIndex(time_value)
    data["day"] = date.day
    data["weekday"] = date.weekday
    data["hour"] = date.hour
    # 3)删除入住次数少于三次位置
    place_count = data.groupby('place_id').count()["row_id"]
    tf = place_count[place_count > 3].index.values
    data_final = data[data['place_id'].isin(tf)]

    # 3、取出特征值和目标值
    y = data_final['place_id']
    # y = data[['place_id']]
    x = data_final[["x","y","accuracy","day","weekday","hour"]]

    # 4、数据分割与特征工程
    # (1)、数据分割
    x_train, x_test, y_train, y_test = train_test_split(x, y)
    # (2)、标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)  # 测试集使用训练集的数据(平均值)等进行标准化
    # (3).KNN 算法预估器
    estimator = KNeighborsClassifier()
    # 4.1 加入网格搜索与交叉验证
    param_dict = {"n_neighbors": [3, 5, 7, 9]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
    estimator.fit(x_train, y_train)
    # (4).模型评估
    # 方法一:直接比对预测值与真实值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("y_test:\n", y_test)
    print("预测值与真实值比对:\n", y_predict == y_test)
    # 方法二:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)

    # 最佳参数 best_params_
    print("最佳参数:\n", estimator.best_params_)
    # 最佳结果 best_score_
    print("最佳结果:\n", estimator.best_score_)
    # 最佳估计器 best_estimator_
    print("最佳估计器:\n", estimator.best_estimator_)
    # 交叉验证结果 cv_results_
    print("交叉验证结果:\n", estimator.cv_results_)

    return None

4. 朴素贝叶斯算法

4.1 联合概率、条件概率与相互独立

  • 联合概率:包含多个条件,且所有条件同时成立的概率;
    • 记作:P(A,B)
    • 特性:P(A, B) = P(A)P(B)
  • 条件概率:就是事件A在另外一个事件B已经发生条件下的发生概率;
    • 记作:P(A|B)
    • 特性:P(A1,A2|B) = P(A1|B)P(A2|B)
  • 相互独立:如果 P(A,B) = P(A)P(B),则称事件 A 与事件 B 相互独立;

4.2 朴素 + 贝叶斯公式

  • 朴素:假设特征与特征之间是相互独立的;
  • 公式

P ( C ∣ W ) = P ( W ∣ C ) P ( C ) P ( W ) P(C|W)=\frac{P(W|C)P(C)}{P(W)} P(CW)=P(W)P(WC)P(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,...)} P(CF1,F2,...)=P(F1,F2,...)P(F1,F2,...∣C)P(C)

  • 应用场景:文本分类;
  • 优点
    • 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率;
    • 对缺失数据不太敏感,算法也比较简单,常用于文本分类;
    • 分类准确度高,速度快;
  • 缺点
    • 由于使用了样本属性独立性的假设,所以如果特征属性有关联时其效果不好;

4.3 朴素贝叶斯算法在文本分类中的应用

  • 公式分为三个部分
    • P(C ):每个文档类别的概率(某文档类别数/总文档数量);
    • P(W│C):给定类别下特征(被预测文档中出现的词)的概率;
      • 计算方法:P(F1│C)=Ni/N (训练文档中去计算);
        • Ni为该F1词在C类别所有文档中出现的次数;
        • N为所属类别C下的文档所有词出现的次数和;
    • P(F1,F2,…) 预测文档中每个词的概率;
  • 问题:样本数量少时可能会出现概率为 0 的情况。解决:引入拉普拉斯平滑系数;

朴素贝叶斯算法的问题

4.3.1 拉普拉斯平滑系数

  • 目的:防止计算出的分类概率为 0;
  • 公式:α 为指定的系数,一般为 1。m 为训练文档中统计出的特征词个数;

P ( F 1 ∣ C ) = N i + α N + α m P(F_1|C)=\frac{N_i+\alpha}{N+\alpha m} P(F1C)=N+αmNi+α

引入拉普拉斯平滑系数

  • API:sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
    • 朴素贝叶斯分类;
    • alpha:拉普拉斯平滑系数;
*Code3 朴素贝叶斯算法代码示例
def nb_cls():
    # 1.获取新闻的数据
    news = fetch_20newsgroups(subset='all')
    # 2.进行数据集分割
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target,test_size=0.3)
    # 3.对于文本数据,进行特征抽取
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4.estimator估计器流程,朴素贝叶斯算法
    mlb = MultinomialNB(alpha=1.0)
    mlb.fit(x_train, y_train)
    # 5.进行预测
    y_predict = mlb.predict(x_test)
    print("预测每篇文章的类别:", y_predict[:100])
    print("真实类别为:", y_test[:100])
    print("预测准确率为:", mlb.score(x_test, y_test))
    return None

5. 决策树

5.1 概述

  • 信息是为了消除不确定性;
  • 信息的衡量用信息熵;
  • 信息和消除不确定性是相联系的;
  • 信息熵单位为比特;
  • 信息增益表示得知特征 X 的信息而息的不确定性减少的程度使得类 Y 的信息熵减少的程度;
  • 决策树划分的依据是信息增益;

5.2 信息熵、信息增益与条件熵

  • 信息熵公式:Ck 表示属于某个类别的样本数;

H ( X ) = − ∑ r i = 1 n ( P ( x i ) ∗ l o g b P ( x i ) ) H(X)=-\sum_{ri=1}^n(P(x_i)*log_bP(x_i)) H(X)=ri=1n(P(xi)logbP(xi))

H ( D ) = − ∑ k = 1 K ∣ C k ∣ ∣ D ∣ l o g ∣ C k ∣ ∣ D ∣ H(D)=-\sum_{k=1}^K\frac{|C_k|}{|D|}log\frac{|C_k|}{|D|} H(D)=k=1KDCklogDCk

  • 信息增益公式

g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)H(DA)

  • 条件熵公式:(信息熵 - 条件熵)

H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ D H ( D i ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ ∑ k = 1 K ∣ D i k ∣ ∣ D i ∣ l o g ∣ D i k ∣ ∣ D i ∣ H(D|A)=\sum_{i=1}^n\frac{|D_i|}{D}H(D_i)=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}log\frac{|D_{ik}|}{|D_i|} H(DA)=i=1nDDiH(Di)=i=1nDDik=1KDiDiklogDiDik

  • 示例

信息熵、信息增益与条件熵

5.3 决策树概述

  • 优点
    • 简单的理解和解释,树木可视化;
  • 缺点
    • 决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合;
  • 进:
    • 减枝 cart 算法(决策树 API 当中已经实现,随机森林参数调优有相关介绍);
    • 随机森林;
  • :企业重要决策,由于决策树很好的分析能力,在决策过程应用较多, 可以选择特征;

5.4 决策树的三种算法实现

  • 三种算法:

    • ID3
      • 信息增益,最大的准则;
    • C4.5
    • 信息增益比,最大的准则;
  • CART

    • 分类树:基尼系数 最小的准则,在 sklearn 中可以选择划分的默认原则;
    • 优势:划分更加细致;
  • API:class sklearn.tree.DecisionTreeClassifier(criterion=’gini’,max_depth=None,random_state=None)

    • 决策树分类器;
    • criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’;
    • max_depth:树的深度大小;
    • random_state:随机数种子;
  • 其中会有些超参数:max_depth:树的深度大小;

    • 其它超参数会结合随机森林;
*Code4 决策树代码示例
def decision_iris():
    # 1.获取数据集
    iris = load_iris()
    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)
    # 3.决策树预估器
    estimator = DecisionTreeClassifier(criterion="entropy")
    estimator.fit(x_train, y_train)
    # 4.模型评估
    # 方法一:直接比对预测值与真实值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("y_test:\n", y_test)
    print("预测值与真实值比对:\n",  y_predict == y_test)
    # 方法二:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)
    return None

5.5 决策树的可视化

  • API:sklearn.tree.export_graphviz() 该函数能够导出 DOT 格式;
    • tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])
  • 工具:(能够将dot文件转换为pdf、png)
  • 运行命令
    • 然后运行命令:dot -Tpng tree.dot -o tree.png
*Code5 可视化决策树代码示例
export_graphviz(estimator, out_file="iris_tree.dot", feature_names=iris.feature_names)

6. 集成学习方法 - 随机森林

6.1 概述

  • 集成学习方法:通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测;
  • 随机森林:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定;
  • 特点
    • 在当前所有算法中,具有极好的准确率;
    • 能够有效地运行在大数据集上,处理具有高维特征的输入样本,而且不需要降维;
    • 能够评估各个特征在分类问题上的重要性;

6.2 随机森林原理过程

  • 两个随机
    • 训练集随机:BootStrap 随机有放回抽样;
      • N 个样本中随机有放回的抽样 N 个;
    • 特征随机
      • 从 M 个特征中随机抽取 m 个特征,M >> m;(降维效果)
  • 为什么采用 BootStrap 抽样:
    • 为什么要随机抽样训练集:
      • 如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的;
    • 为什么要有放回地抽样:
      • 如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决;
  • API:class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)
    • 随机森林分类器;
    • n_estimators:integer,optional(default = 10)森林里的树木数量 120,200,300,500,800,1200;
    • criteria:string,可选(default =“gini”)分割特征的测量方法;
    • max_depth:integer或None,可选(默认=无)树的最大深度 5,8,15,25,30;
    • 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:boolean,optional(default = True)是否在构建树时使用放回抽样;
    • min_samples_split:节点划分最少样本数;
    • min_samples_leaf:叶子节点的最小样本数;
  • 超参数:n_estimator, max_depth, min_samples_split,min_samples_lea
*Code6 随机森林代码示例
def random_iris():
    # 1.获取数据集
    iris = load_iris()
    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)
    # 3.随机森林预估器
    estimator = RandomForestClassifier(criterion="entropy", max_depth=8)
    estimator.fit(x_train, y_train)
    # 4.模型评估
    # 方法一:直接比对预测值与真实值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("y_test:\n", y_test)
    print("预测值与真实值比对:\n",  y_predict == y_test)
    # 方法二:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)
    return None


最后

新人制作,如有错误,欢迎指出,感激不尽!
如需转载,请标注出处!
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多氯环己烷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值