机器学习入门笔记


机器学习入门笔记

前言

这个是根据“黑马程序员”的一套机器学习课程编写的博客。这篇博客上的案例均为课程里面的,但并没有包含所有案例,只是记录了部分。

B站视频原地址

特征工程

Tf-idf文本特征提取

Tf-idf介绍

  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

  • TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

  • 词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率

  • 逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到

tfidf公式

最终得出结果可以理解为重要程度。

注:假如一篇文件的总词语数是100个,而词语”非常”出现了5次,那么”非常”一词在该文件中的词频就是5/100=0.05。而计算文件频率(IDF)的方法是以文件集的文件总数,除以出现”非常”一词的文件数。所以,如果”非常”一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是lg(10,000,000 / 1,0000)=3。最后”非常”对于这篇文档的tf-idf的分数为0.05 * 3=0.15

from sklearn.feature_extraction.text import TfidfVectorizer    # Tf-idf文本特征提取
import jieba    # 分词模块

def cut_word(text):
    """
    对中文进行分词
    "我爱北京天安门"————>"我 爱 北京 天安门"
    :param text:
    :return: text
    """
    # 用结巴对中文字符串进行分词
    text = " ".join(list(jieba.cut(text)))

    return text

def text_chinese_tfidf_demo():
    """
    对中文进行特征抽取
    :return: None
    """
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类
    # transfer = CountVectorizer(sparse=False)
    transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要'])
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print("文本特征抽取的结果:\n", data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names())

    return None

返回结果:

Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache
Loading model cost 0.856 seconds.
Prefix dict has been built succesfully.
['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
文本特征抽取的结果:
 [[ 0.          0.          0.          0.43643578  0.          0.          0.
   0.          0.          0.21821789  0.          0.21821789  0.          0.
   0.          0.          0.21821789  0.21821789  0.          0.43643578
   0.          0.21821789  0.          0.43643578  0.21821789  0.          0.
   0.          0.21821789  0.21821789  0.          0.          0.21821789
   0.        ]
 [ 0.2410822   0.          0.          0.          0.2410822   0.2410822
   0.2410822   0.          0.          0.          0.          0.          0.
   0.          0.2410822   0.55004769  0.          0.          0.          0.
   0.2410822   0.          0.          0.          0.          0.48216441
   0.          0.          0.          0.          0.          0.2410822
   0.          0.2410822 ]
 [ 0.          0.644003    0.48300225  0.          0.          0.          0.
   0.16100075  0.16100075  0.          0.16100075  0.          0.16100075
   0.16100075  0.          0.12244522  0.          0.          0.16100075
   0.          0.          0.          0.16100075  0.          0.          0.
   0.3220015   0.16100075  0.          0.          0.16100075  0.          0.
   0.        ]]
返回特征名字:
 ['之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']

Tf-idf的重要性

分类机器学习算法进行文章分类中前期数据处理方式

无量纲化处理—标准化

注意:无量纲化包括归一化和标准化,因为经常使用标准化所以这里只介绍标准化。

为什么我们要进行标准化?

  • 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级容易影响(支配)目标结果,使得一些算法无法学习到其它的特征

约会对象数据

我们需要用到一些方法进行无量纲化使不同规格的数据转换到同一规格

定义

  • 通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内

API

  • sklearn.preprocessing.StandardScaler( )
    • 处理之后每列来说所有数据都聚集在均值0附近标准差差为1
    • StandardScaler.fit_transform(X)
      • X:numpy array格式的数据[n_samples,n_features]
    • 返回值:转换后的形状相同的array
import pandas as pd
from sklearn.preprocessing import StandardScaler    # 标准化

def stand_demo():
    """
    标准化演示
    :return: None
    """
    data = pd.read_csv("dating.txt")
    print(data)
    # 1、实例化一个转换器类
    transfer = StandardScaler()
    # 2、调用fit_transform
    data = transfer.fit_transform(data[['milage','Liters','Consumtime']])
    print("标准化的结果:\n", data)
    print("每一列特征的平均值:\n", transfer.mean_)
    print("每一列特征的方差:\n", transfer.var_)

    return None

返回结果:

     milage     Liters  Consumtime  target
0     40920   8.326976    0.953952       3
1     14488   7.153469    1.673904       2
2     26052   1.441871    0.805124       1
..      ...        ...         ...     ...
997   26575  10.650102    0.866627       3
998   48111   9.134528    0.728045       3
999   43757   7.882601    1.332446       3

[1000 rows x 4 columns]
标准化的结果:
 [[ 0.33193158  0.41660188  0.24523407]
 [-0.87247784  0.13992897  1.69385734]
 [-0.34554872 -1.20667094 -0.05422437]
 ..., 
 [-0.32171752  0.96431572  0.06952649]
 [ 0.65959911  0.60699509 -0.20931587]
 [ 0.46120328  0.31183342  1.00680598]]
每一列特征的平均值:
 [  3.36354210e+04   6.55996083e+00   8.32072997e-01]
每一列特征的方差:
 [  4.81628039e+08   1.79902874e+01   2.46999554e-01]

标准化总结

在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。

PCA降维

什么是主成分分析(PCA)

  • 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量
  • 作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
  • 应用:回归分析或者聚类分析当中

对于信息一词,在决策树中会进行介绍

那么更好的理解这个过程呢?我们来看一张图

PCA解释图

API

  • sklearn.decomposition.PCA(n_components=None)
    • 将数据分解为较低维数空间
    • n_components:
      • 小数:表示保留百分之多少的信息
      • 整数:减少到多少特征
    • PCA.fit_transform(X) X:numpy array格式的数据[n_samples,n_features]
    • 返回值:转换后指定维度的array
from sklearn.decomposition import PCA    # PCA


def pca_demo():
    """
    对数据进行PCA降维
    :return: None
    """
    data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]]

    # 1、实例化PCA, 小数——保留多少信息
    transfer = PCA(n_components=0.9)
    # 2、调用fit_transform
    data1 = transfer.fit_transform(data)

    print("保留90%的信息,降维结果为:\n", data1)

    # 1、实例化PCA, 整数——指定降维到的维数
    transfer2 = PCA(n_components=3)
    # 2、调用fit_transform
    data2 = transfer2.fit_transform(data)
    print("降维到3维的结果:\n", data2)

    return None

返回结果:

保留90%的信息,降维结果为:
 [[ -3.13587302e-16   3.82970843e+00]
 [ -5.74456265e+00  -1.91485422e+00]
 [  5.74456265e+00  -1.91485422e+00]]
降维到3维的结果:
 [[ -3.13587302e-16   3.82970843e+00   4.59544715e-16]
 [ -5.74456265e+00  -1.91485422e+00   4.59544715e-16]
 [  5.74456265e+00  -1.91485422e+00   4.59544715e-16]]

分类算法

数据集划分

定义

机器学习一般的数据集会划分为两个部分:

  • 训练数据:用于训练,构建模型
  • 测试数据:在模型检验时使用,用于评估模型是否有效

划分比例:

  • 训练集:70% 80% 75%
  • 测试集:30% 20% 30%

API

  • sklearn.model_selection.train_test_split(arrays, *options)
    • x 数据集的特征值
    • y 数据集的标签值
    • test_size 测试集的大小,一般为float
    • random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
    • return ,测试集特征训练集特征值值,训练标签,测试标签(默认随机取)

结合后面的数据集作介绍

K-近邻算法

K-近邻算法定义

  • 如果一个样本在特征空间中的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方法的值来决定最合适的算法。 (不同实现方式影响效率)
    """
    1. 获取数据
    2. 数据集划分
    3. 特征工程---标准化
    4. KNN预估器流程
    5. 模型评估
    """
    
    from sklearn.datasets import load_iris    # 数据集
    from sklearn.model_selection import train_test_split    # 数据集划分
    from sklearn.preprocessing import StandardScaler    # 标准化
    from sklearn.neighbors import KNeighborsClassifier    # KNN算法
    
    
    def knn_iris():
        """
        用KNN算法对鸢尾花进行分类
        """
        # 1. 获取数据
        iris = load_iris()
        # 2. 数据集划分
        """
        x是特征值 y是目标值
        训练集的特征值x_train 测试集的特征值x_test 训练集的目标值y_train 测试集的目标值y_test
        """
        # random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
        x_train, x_test, y_train, y_test = train_test_split(
            iris.data, iris.target, random_state=6)
        # 3. 特征工程---标准化
        # 训练集和测试集都要进行标准化
        transfer = StandardScaler()
        # 训练集标准化
        x_train = transfer.fit_transform(x_train)
        # 测试集标准化    注意与训练集标准化的区分
        x_test = transfer.transform(x_test)
        # 4. KNN预估器流程
        # n_neighbors就是k值
        estimator = KNeighborsClassifier(n_neighbors=3)
        estimator.fit(x_train, y_train)
        # 5. 模型评估
        # 方法1:直接比对真实值和预测值
        y_predict = estimator.predict(x_test)
        print("y_predict:\n", y_predict)
        print("直接比对真实值和预测值:\n", y_test == y_predict)
    
        # 方法2:计算准确率
        score = estimator.score(x_test, y_test)
        print("准确率为:\n", score)
        return None
    
    
    if __name__ == "__main__":
        knn_iris()
    
    结果:
y_predict:
 [0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
 2]
直接比对真实值和预测值:
 [ True  True  True  True  True  True False  True  True  True  True  True
  True  True  True False  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True False  True
  True  True]
准确率为:
 0.9210526315789473

模型选择与调优

模型选择与调优这里有”交叉验证“和”超参数搜索(网格搜索)“两种,通过调用sklearn中的函数可以直接同时实现这两种功能。

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:每次交叉验证后的验证集准确率结果和训练集准确率结果
"""
1. 获取数据
2. 数据集划分
3. 特征工程---标准化
4. KNN预估器流程
5. 模型评估
"""

from sklearn.datasets import load_iris    # 数据集
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.preprocessing import StandardScaler    # 标准化
from sklearn.neighbors import KNeighborsClassifier    # KNN算法
from sklearn.model_selection import GridSearchCV    # 模型优化


def knn_iris_gscv():
    """
    用KNN算法对鸢尾花进行分类
    使用交叉验证和网格搜索进行模型优化与调优
    """
    iris = load_iris()
    x_train, x_test, y_train, y_test = train_test_split(
        iris.data, iris.target, random_state=6)

    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    estimator = KNeighborsClassifier()

    # 加入网格搜索与交叉验证
    param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
    # param_grid:估计器参数(dict) 例如:{“n_neighbors”:[1,3,5]}
    # cv:指定几折交叉验证
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)

    estimator.fit(x_train, y_train)
    # 模型评估
    # 方法1:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法2:计算准确率
    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


if __name__ == "__main__":
    knn_iris_gscv()

结果:

y_predict:
 [0 2 0 0 2 1 2 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
 2]
直接比对真实值和预测值:
 [ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True False  True  True  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True False  True
  True  True]
准确率为:
 0.9473684210526315
最佳参数:
 {'n_neighbors': 11}
最佳结果:
 0.9734848484848484
最佳估计器:
 KNeighborsClassifier(n_neighbors=11)
交叉验证结果:
 {'mean_fit_time': array([0.00069556, 0.00049865, 0.0005944 , 0.00069988, 0.00059845,
       0.0003933 ]), 'std_fit_time': array([0.00045544, 0.00049865, 0.00048581, 0.00045873, 0.00048918,
       0.00048186]), 'mean_score_time': array([0.00119884, 0.00119665, 0.00120168, 0.00109487, 0.0012959 ,
       0.00129161]), 'std_score_time': array([0.00039571, 0.00039928, 0.00038471, 0.00030016, 0.00044617,
       0.00045765]), 'param_n_neighbors': masked_array(data=[1, 3, 5, 7, 9, 11],
             mask=[False, False, False, False, False, False],
       fill_value='?',
            dtype=object), 'params': [{'n_neighbors': 1}, {'n_neighbors': 3}, {'n_neighbors': 5}, {'n_neighbors': 7}, {'n_neighbors': 9}, {'n_neighbors': 11}], 'split0_test_score': array([1., 1., 1., 1., 1., 1.]), 'split1_test_score': array([0.91666667, 0.91666667, 1.        , 0.91666667, 0.91666667,
       0.91666667]), 'split2_test_score': array([1., 1., 1., 1., 1., 1.]), 'split3_test_score': array([1.        , 1.        , 1.        , 1.        , 0.90909091,
       1.        ]), 'split4_test_score': array([1., 1., 1., 1., 1., 1.]), 'split5_test_score': array([0.90909091, 0.90909091, 1.        , 1.        , 1.        ,
       1.        ]), 'split6_test_score': array([1., 1., 1., 1., 1., 1.]), 'split7_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 1.        ,
       1.        ]), 'split8_test_score': array([1., 1., 1., 1., 1., 1.]), 'split9_test_score': array([0.90909091, 0.81818182, 0.81818182, 0.81818182, 0.81818182,
       0.81818182]), 'mean_test_score': array([0.96439394, 0.95530303, 0.97272727, 0.96439394, 0.96439394,
       0.97348485]), 'std_test_score': array([0.04365767, 0.0604591 , 0.05821022, 0.05965639, 0.05965639,
       0.05742104]), 'rank_test_score': array([5, 6, 2, 3, 3, 1])}

与不使用模型优化的KNN算法相对比,可以发现使用模型优化的KNN算法的结果更好。

朴素贝叶斯算法

朴素贝叶斯算法多用于文本分类。

API

  • sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
    • 朴素贝叶斯分类
    • alpha:拉普拉斯平滑系数
"""
朴素贝叶斯算法
应用场景:文本分类  单词作为特征
优点:
    对缺失数据不太敏感,算法也比较简单,常用于文本分类。
    分类准确度高,速度快
缺点:
    由于使用了样本属性独立性的假设,所以如果特征属性有关联时其效果不好
"""
from sklearn.datasets import fetch_20newsgroups    # 获取数据集
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.model_selection import GridSearchCV    # 模型优化
from sklearn.naive_bayes import MultinomialNB    # 朴素贝叶斯
from sklearn.feature_extraction.text import TfidfVectorizer    # 文本特征抽取


def nb_news():
    # 1. 获取数据
    news = fetch_20newsgroups(subset="all")
    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)
    transfer = TfidfVectorizer()
    # 标准化
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    estimator = MultinomialNB()

    # 模型优化
    param_dict = {"alpha": [1, 3, 5, 7, 9, 11]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)

    estimator.fit(x_train, y_train)
    # 5. 模型评估
    # 方法1:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法2:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)
    return None


if __name__ == "__main__":
    nb_news()

结果:

y_predict:
 [ 9  4 17 ...  8  2  0]
直接比对真实值和预测值:
 [ True  True  True ...  True  True  True]
准确率为:
 0.8548387096774194

决策树

API

  • class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
    • 决策树分类器
    • criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
    • max_depth:树的深度大小
    • random_state:随机数种子
  • 其中会有些超参数:max_depth:树的深度大小
    • 其它超参数我们会结合随机森林讲解
from sklearn.datasets import load_iris    # 数据集
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.tree import DecisionTreeClassifier    # 决策树


def decision_iris():
    """
    用决策树对鸢尾花进行分类
    优点:可视化 - 可解释能力强
    缺点:如果数据很多还不设置树的深度这样可能会产生过拟合。
    """

    # 1. 获取数据集
    iris = load_iris()

    # 2. 划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target)

    # 3. 决策树预估器
    # 参数max_depth:树的深度大小 如果数据集大则树的深度也大这样可能会导致准确率降低
    # 所以如果有必要的话可以设置树的深度来提高准确率
    estimator = DecisionTreeClassifier(criterion="entropy")
    estimator.fit(x_train, y_train)
    # 4. 模型评估
    # 方法1:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法2:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)
    return None


if __name__ == "__main__":
    decision_iris()

结果:

y_predict:
 [0 2 1 0 1 0 0 0 2 1 2 1 2 2 1 1 1 0 0 1 2 2 0 0 2 1 0 2 1 2 1 0 1 1 0 1 1
 1]
直接比对真实值和预测值:
 [ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True False  True  True  True False  True  True  True  True
  True  True  True  True False False  True  True  True  True  True False
  True  True]
准确率为:
 0.868421052631579

随机森林

随机森林原理过程

学习算法根据下列算法而建造每棵树:

  • 用N来表示训练用例(样本)的个数,M表示特征数目。
    • 1、一次随机选出一个样本,重复N次, (有可能出现重复的样本)
    • 2、随机去选出m个特征, m <<M,建立决策树
  • 采取bootstrap抽样

为什么采用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_leaf

from sklearn.datasets import load_iris    # 数据集
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.ensemble import RandomForestClassifier    # 随机森林
from sklearn.model_selection import GridSearchCV    # 模型优化


def iris_demo():
    # 加载数据集
    iris = load_iris()

    # 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target)

    # 随机森林
    estimator = RandomForestClassifier()

    # 网格化搜索
    param_dict = {"n_estimators": [10, 20, 30, 40, 50, 100]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)

    # 训练
    estimator.fit(x_train, y_train)

    # 模型评估
    # 方法1:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法2:计算准确率
    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


if __name__ == "__main__":
    iris_demo()

结果:

y_predict:
 [0 1 2 2 1 2 2 1 2 2 0 0 0 0 0 0 1 2 0 2 1 2 2 0 0 0 1 2 2 2 1 1 1 1 0 2 1
 2]
直接比对真实值和预测值:
 [ True  True  True  True  True  True  True  True  True  True  True  True  
  True  True  True  True  True  True  True  True  True  True  True  True   
  True  True  True  True  True  True False  True  True  True  True  True   
  True  True]
准确率为:
 0.9736842105263158
最佳参数:
 {'n_estimators': 30}
最佳结果:
 0.9553030303030303
最佳估计器:
 RandomForestClassifier(n_estimators=30)
交叉验证结果:
 {'mean_fit_time': array([0.01545861, 0.0299505 , 0.04111712, 0.05707047, 0.06866693,
       0.145067  ]), 'std_fit_time': array([0.00215007, 0.00540963, 0.00032881, 0.00359371, 0.00326092,
       0.0084516 ]), 'mean_score_time': array([0.00159588, 0.0027936 , 0.00379615, 0.00488796, 0.00544808,
       0.01146989]), 'std_score_time': array([0.00048815, 0.00040718, 0.00039285, 0.00054974, 0.00046851,
       0.00091972]), 'param_n_estimators': masked_array(data=[10, 20, 30, 40, 50, 100],
             mask=[False, False, False, False, False, False],
       fill_value='?',
            dtype=object), 'params': [{'n_estimators': 10}, {'n_estimators': 20}, {'n_estimators': 30}, {'n_estimators': 40}, {'n_estimators': 50}, {'n_estimators': 100}], 'split0_test_score': array([0.91666667, 0.91666667, 0.91666667, 0.91666667, 0.91666667,
       0.91666667]), 'split1_test_score': array([1., 1., 1., 1., 1., 1.]), 'split2_test_score': array([0.90909091, 1.        , 1.        , 1.        , 1.        ,
       1.        ]), 'split3_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 0.90909091,
       0.90909091]), 'split4_test_score': array([0.81818182, 0.81818182, 0.81818182, 0.81818182, 0.81818182,
       0.81818182]), 'split5_test_score': array([1., 1., 1., 1., 1., 1.]), 'split6_test_score': array([1., 1., 1., 1., 1., 1.]), 'split7_test_score': array([0.90909091, 0.90909091, 1.        , 0.90909091, 1.        ,
       1.        ]), 'split8_test_score': array([1.        , 0.90909091, 1.        , 0.90909091, 1.        ,
       1.        ]), 'split9_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 0.90909091,
       0.90909091]), 'mean_test_score': array([0.93712121, 0.93712121, 0.95530303, 0.93712121, 0.95530303,
       0.95530303]), 'std_test_score': array([0.05789881, 0.05789881, 0.0604591 , 0.05789881, 0.0604591 ,
       0.0604591 ]), 'rank_test_score': array([4, 4, 1, 4, 1, 1])}

总结

  • 在当前所有算法中,具有极好的准确率
  • 能够有效地运行在大数据集上,处理具有高维特征的输入样本,而且不需要降维
  • 能够评估各个特征在分类问题上的重要性

回归与聚类算法

线性回归

线性回归API

  • sklearn.linear_model.LinearRegression(fit_intercept=True)
    • 通过正规方程优化
    • fit_intercept:是否计算偏置
    • LinearRegression.coef_:回归系数
    • LinearRegression.intercept_:偏置
  • sklearn.linear_model.SGDRegressor(loss=”squared_loss”, fit_intercept=True, learning_rate =’invscaling’, eta0=0.01)
    • SGDRegressor类实现了随机梯度下降学习,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型。
    • loss:损失类型
      • loss=”squared_loss”: 普通最小二乘法
    • fit_intercept:是否计算偏置
    • learning_rate : string, optional
      • 学习率填充
      • ‘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来指定学习率。
    • SGDRegressor.coef_:回归系数
    • SGDRegressor.intercept_:偏置

sklearn提供给我们两种实现的API, 可以根据选择使用

回归性能评估

sklearn.metrics.mean_squared_error(y_true, y_pred)

  • 均方误差回归损失
  • y_true:真实值
  • y_pred:预测值
  • return:浮点数结果
from sklearn.datasets import load_boston    # 加载数据集
from sklearn.model_selection import train_test_split    # 数据集划分
from sklearn.preprocessing import StandardScaler    # 特征工程 标准化
from sklearn.linear_model import LinearRegression, SGDRegressor    # 正规方程 梯度下降
from sklearn.metrics import mean_squared_error    # 回归评估 均方误差(值越小越好)


def linear1():
    """
    正规方程的优化方法对波士顿房价进行预测
    """
    boston = load_boston()
    x_train, x_test, y_train, y_test = train_test_split(
        boston.data, boston.target, random_state=22)
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    estimator = LinearRegression()
    estimator.fit(x_train, y_train)
    print("正规方程-权重系数为:\n", estimator.coef_)
    print("正规方程-偏置为:\n", estimator.intercept_)
    y_predict = estimator.predict(x_test)
    print("正规方程-预测房价:\n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("正规方程-均方误差:\n", error)
    return None


def linear2():
    """
    梯度下降的优化方法对波士顿房价进行预测
    """
    boston = load_boston()
    x_train, x_test, y_train, y_test = train_test_split(
        boston.data, boston.target, random_state=22)
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    estimator = SGDRegressor()
    estimator.fit(x_train, y_train)
    print("梯度下降-权重系数为:\n", estimator.coef_)
    print("梯度下降-偏置为:\n", estimator.intercept_)
    y_predict = estimator.predict(x_test)
    print("梯度下降-预测房价:\n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("梯度下降-均方误差:\n", error)
    return None


if __name__ == "__main__":
    linear1()
    linear2()

结果:

正规方程-权重系数为:
 [-0.64817766  1.14673408 -0.05949444  0.74216553 -1.95515269  2.70902585
 -0.07737374 -3.29889391  2.50267196 -1.85679269 -1.75044624  0.87341624 
 -3.91336869]
正规方程-偏置为:
 22.62137203166228
正规方程-预测房价:
 [28.22944896 31.5122308  21.11612841 32.6663189  20.0023467  19.07315705
 21.09772798 19.61400153 19.61907059 32.87611987 20.97911561 27.52898011 
 15.54701758 19.78630176 36.88641203 18.81202132  9.35912225 18.49452615 
 30.66499315 24.30184448 19.08220837 34.11391208 29.81386585 17.51775647 
 34.91026707 26.54967053 34.71035391 27.4268996  19.09095832 14.92742976 
 30.86877936 15.88271775 37.17548808  7.72101675 16.24074861 17.19211608 
  7.42140081 20.0098852  40.58481466 28.93190595 25.25404307 17.74970308 
 38.76446932  6.87996052 21.80450956 25.29110265 20.427491   20.4698034  
 17.25330064 26.12442519  8.48268143 27.50871869 30.58284841 16.56039764 
  9.38919181 35.54434377 32.29801978 21.81298945 17.60263689 22.0804256  
 23.49262401 24.10617033 20.1346492  38.5268066  24.58319594 19.78072415 
 13.93429891  6.75507808 42.03759064 21.9215625  16.91352899 22.58327744 
 40.76440704 21.3998946  36.89912238 27.19273661 20.97945544 20.37925063 
 25.3536439  22.18729123 31.13342301 20.39451125 23.99224334 31.54729547 
 26.74581308 20.90199941 29.08225233 21.98331503 26.29101202 20.17329401 
 25.49225305 24.09171045 19.90739221 16.35154974 15.25184758 18.40766132 
 24.83797801 16.61703662 20.89470344 26.70854061 20.7591883  17.88403312 
 24.28656105 23.37651493 21.64202047 36.81476219 15.86570054 21.42338732 
 32.81366203 33.74086414 20.61688336 26.88191023 22.65739323 17.35731771 
 21.67699248 21.65034728 27.66728556 25.04691687 23.73976625 14.6649641  
 15.17700342  3.81620663 29.18194848 20.68544417 22.32934783 28.01568563 
 28.58237108]
正规方程-均方误差:
 20.6275137630954
梯度下降-权重系数为:
 [-0.52844184  0.94742828 -0.43896185  0.80011052 -1.70094588  2.83803954
 -0.15173308 -3.15314827  1.64459185 -0.92057374 -1.72092516  0.85822999
 -3.89079621]
梯度下降-偏置为:
 [22.62848948]
梯度下降-预测房价:
 [28.32292485 31.65691921 21.4754174  32.74532796 20.21502727 19.05803274
 21.38012862 19.40598106 19.65928004 32.83684983 21.37788237 27.27547404
 15.58434744 19.9543843  37.052139   18.66414622  9.64694632 18.60831548
 30.78911441 24.28055663 19.04506654 34.16527664 29.53666782 17.39899068
 34.86763757 26.51961514 34.42685759 27.38498522 19.1234001  15.69443705
 30.90416755 14.4629764  37.60886681  8.70471496 16.38818819 16.8388242
  7.70173349 19.7726613  40.59036302 29.18080616 25.25730687 17.82216674
 39.37499484  6.67884528 21.54796917 25.04507005 20.88378703 20.64882236
 17.03224546 26.32629603  9.6471961  27.18516688 30.67565735 16.69940767
  9.58964556 35.55768574 31.59626177 22.93550937 17.57965025 21.83043993
 23.62551177 23.94527301 20.3319314  38.24324246 25.72953353 19.68070738
 14.15726975  6.66109511 42.53435973 21.82504626 16.74834226 22.55184196
 41.01385643 21.71857114 36.98704919 27.16545173 21.83161702 20.78576019
 25.30987444 23.77003724 31.53599899 20.19287298 24.00693276 31.56432429
 27.2645538  20.86527222 29.1081147  21.95286144 26.74924411 18.76781794
 25.26458575 24.01985914 19.93042174 17.68510263 15.50813547 18.27522698
 24.59223379 16.73277678 20.66946955 26.79190915 20.72655782 17.97463708
 24.13232421 23.25410362 20.27914227 36.64368885 15.98551815 22.46864296
 32.71528599 33.73484378 20.54324486 25.9984172  23.32481418 17.74521574
 21.46651544 21.79381137 27.55126895 25.28602934 23.65813339 14.43211265
 15.64622064  3.64461024 29.25332792 20.65259117 22.31013756 28.06226938
 28.3763949 ]
梯度下降-均方误差:
 21.168264510208296

注意:均方误差越小表示效果越好。

岭回归—线性回归的改进

API

sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,solver=”auto”, normalize=False)

  • 具有l2正则化的线性回归
  • alpha:正则化力度,也叫 λ
    • λ取值:01 110
  • solver:会根据数据自动选择优化方法
    • sag:如果数据集、特征都比较大,选择该随机梯度下降优化
  • normalize:数据是否进行标准化
    • normalize=False:可以在fit之前调用preprocessing.StandardScaler标准化数据
  • Ridge.coef_:回归权重
  • Ridge.intercept_:回归偏置

Ridge方法相当于SGDRegressor(penalty=’l2’, loss=”squared_loss”),只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG)

  • sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)
    • 具有l2正则化的线性回归,可以进行交叉验证
    • coef_:回归系数
from sklearn.datasets import load_boston  # 加载数据集
from sklearn.linear_model import Ridge  # 岭回归
from sklearn.metrics import mean_squared_error  # 回归评估 均方误差(值越小越好)
from sklearn.model_selection import train_test_split  # 数据集划分
from sklearn.preprocessing import StandardScaler  # 特征工程 标准化


def linear3():
    # 加载数据集
    boston = load_boston()

    # 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(
        boston.data, boston.target, random_state=22)

    # 数据集标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 预估器
    estimator = Ridge()
    estimator.fit(x_train, y_train)

    # 得出模型
    print("岭回归-权重系数为:\n", estimator.coef_)
    print("岭回归-偏置为:\n", estimator.intercept_)

    # 模型评估
    y_predict = estimator.predict(x_test)
    print("岭回归-预测房价:\n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("岭回归-均方误差:\n", error)
    return None


if __name__ == "__main__":
    linear3()

结果:

岭回归-权重系数为:
 [-0.63591916  1.12109181 -0.09319611  0.74628129 -1.91888749  2.71927719
 -0.08590464 -3.25882705  2.41315949 -1.76930347 -1.74279405  0.87205004 
 -3.89758657]
岭回归-偏置为:
 22.62137203166228
岭回归-预测房价:
 [28.22119941 31.49858594 21.14690941 32.64962343 20.03976087 19.07187629
 21.11827061 19.61935024 19.64669848 32.83666525 21.01034708 27.47939935
 15.55875601 19.80406014 36.86415472 18.79442579  9.42343608 18.5205955
 30.67129766 24.30659711 19.07820077 34.08772738 29.77396117 17.50394928
 34.87750492 26.52508961 34.65566473 27.42939944 19.08639183 15.04854291
 30.84974343 15.76894723 37.18814441  7.81864035 16.27847433 17.15510852
  7.46590141 19.98474662 40.55565604 28.96103939 25.25570196 17.7598197
 38.78171653  6.87935126 21.76805062 25.25888823 20.47319256 20.48808719
 17.24949519 26.11755181  8.61005188 27.47070495 30.57806886 16.57080888
  9.42312214 35.50731907 32.20467352 21.93128073 17.62011278 22.08454636
 23.50121152 24.08248876 20.16840581 38.47001591 24.69276673 19.7638548
 13.96547058  6.76070715 42.04033544 21.9237625  16.88030656 22.60637682
 40.74664535 21.44631815 36.86936185 27.17135794 21.09470367 20.40689317
 25.35934079 22.35676321 31.1513028  20.39303322 23.99948991 31.54251155
 26.77734347 20.89368871 29.05880401 22.00850263 26.31965286 20.04852734
 25.46476799 24.08084537 19.90846889 16.47030743 15.27936372 18.39475348
 24.80822272 16.62280764 20.86393724 26.70418608 20.74534996 17.89544942
 24.25949423 23.35743497 21.51817773 36.76202304 15.90293344 21.52915882
 32.78684766 33.68666117 20.61700911 26.78345059 22.72685584 17.40478038
 21.67136433 21.6912557  27.66684993 25.08825085 23.72539867 14.64260535
 15.21105331  3.81916568 29.16662813 20.67913144 22.33386579 28.01241753
 28.531445  ]
岭回归-均方误差:
 20.65644821435496

逻辑回归与二分类—分类算法

逻辑回归API

  • sklearn.linear_model.LogisticRegression(solver=’liblinear’, penalty=‘l2’, C = 1.0)
    • solver:优化求解方式(默认开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数)
      • sag:根据数据集自动选择,随机平均梯度下降
    • penalty:正则化的种类
    • C:正则化力度

默认将类别数量少的当做正例

LogisticRegression方法相当于 SGDClassifier(loss=”log”, penalty=” “),SGDClassifier实现了一个普通的随机梯度下降学习,也支持平均随机梯度下降法(ASGD),可以通过设置average=True。而使用LogisticRegression(实现了SAG)

分类评估报告API

  • sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None )
    • y_true:真实目标值
    • y_pred:估计器预测目标值
    • labels:指定类别对应的数字
    • target_names:目标类别名称
    • return:每个类别精确率与召回率
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression  # 逻辑回归
from sklearn.metrics import classification_report, roc_auc_score    # 分类评估
from sklearn.model_selection import train_test_split  # 数据集划分
from sklearn.preprocessing import StandardScaler  # 特征工程 标准化

if __name__ == "__main__":
    # 加载数据
    column_name = ['Sample code number', 'Clump Thickness',
                   'Uniformity of Cell Size', 'Uniformity of Cell Shape',
                   'Marginal Adhesion', 'Single Epithelial Cell Size',
                   'Bare Nuclei', 'Bland Chromatin',
                   'Normal Nucleoli', 'Mitoses', 'Class']
    path = r"D:\痛苦の资料\不会真的有人学编程吧\机器学习\黑马程序员\自己的整理\day3\breast-cancer-wisconsin.data"
    data = pd.read_csv(path, names=column_name)

    # 数据处理  因为数据中有缺失值,缺失的地方使用 ? 替代,目标是删掉缺失值
    data = data.replace(to_replace='?', value=np.nan)
    data.dropna(inplace=True)

    # 数据处理  获取特征值和目标值
    x = data.iloc[:, 1:-1]
    y = data["Class"]

    # 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(x, y)

    # 数据标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 预估器
    estimator = LogisticRegression()
    estimator.fit(x_train, y_train)

    # 模型
    print("逻辑回归-权重系数为:\n", estimator.coef_)
    print("逻辑回归-偏置为:\n", estimator.intercept_)
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)
    score = estimator.score(x_test, y_test)
    print("准确率:\n", score)

    # 查看精确率、召回率、F1-score
    report = classification_report(y_test, y_predict, labels=[
                                   2, 4], target_names=['良性', '恶性'])

    # y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
    # 将y_test 转换成 0 1
    y_true = np.where(y_test > 3, 1, 0)
    print(roc_auc_score(y_true, y_predict))

结果:

逻辑回归-权重系数为:
 [[1.51911637 0.06401522 0.69614721 0.76445915 0.50264081 1.37783828
  1.13432057 0.6161716  0.85294448]]
逻辑回归-偏置为:
 [-0.90973535]
y_predict:
 [2 4 2 4 2 2 2 2 4 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2 2 2 2 2 4 4 4 2 2 2 2 4
 2 4 2 4 4 2 2 4 4 4 4 4 2 2 2 4 2 4 4 2 2 2 2 4 2 2 2 4 2 4 4 2 2 2 2 2 2
 2 2 4 2 2 2 4 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2 4 4 4 2 2 2 2 4 4 2 4 4 2 4
 2 4 4 4 2 2 2 2 2 2 4 2 4 2 2 2 2 2 4 2 4 4 2 4 2 2 4 4 4 2 2 2 2 2 2 2 2
 2 2 2 2 4 4 2 2 2 4 2 4 2 2 2 2 2 2 2 2 4 4 2]
直接比对真实值和预测值:
 137    True
506    True
578    True
100    True
600    True
       ...
426    True
390    True
336    True
289    True
444    True
Name: Class, Length: 171, dtype: bool
准确率:
 0.9649122807017544
0.9585488041370394

无监督学习—K-means算法

K-meansAPI

  • sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
    • k-means聚类
    • n_clusters:开始的聚类中心数量
    • init:初始化方法,默认为’k-means ++’
    • labels_:默认标记的类型,可以和真实值比较(不是值比较)

文章作者: LightningMaster
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LightningMaster !
评论
  目录