机器学习实战 --- sklearn

前言

        随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文主要介绍机器学习的基础内容。

源码:https://gitee.com/qinlewei/machine_learning.git


一、sklearn 数据集

       对于一个初入机器学习的小白来说,数据是分析必不可少的。sklearn中含有前人整理好的数据集可以直接导入调用,此外也可以从kaggle上下载数据集,上的数据具有一定的权威性。

scikit-learn数据集API:
       加载获取流行数据集:sklearn.datasets
            1)datasets.load_*() 获取小规模数据集
            2)datasets.fetch_*(data_home=None) 获取大规模数据集(需要从网上下载)

            load 和 fetch 返回的数据类型datasets.base.Bunch(字典格式)
                data:特征数据数组,是[n_samples * n_features]的二维 numpy.ndarray 数组
                target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
                DESCR:数据描述
                feature_names:特征名,新闻数据,手写数字、回归数据集没有
                target_names:标签名

        数据集的返回值:
            datasets.base.Bunch (继承自字典)
from sklearn.datasets import load_iris

iris = load_iris()
print('鸢尾花数据集的返回值:\n', iris)  # 返回值是一个继承自字典的Bunch
print('鸢尾花的特征值:\n', iris['data'])
print('鸢尾花的目标值:\n', iris['target'])
print('鸢尾花特征名字:\n', iris['feature_names'])
print('鸢尾花特目标值名字:\n', iris['target_names'])
print('鸢尾花的描述:\n', iris['DESCR'])

 二、数据预处理

数据预处理(data preprocessing)主要包括去除唯一属性、处理缺失值、属性编码、数据标准化正则化、特征选择、主成分分析等。
数据预处理主要通过一些转换函数将特征数据转换成更加适合算法模型的特征数据的过程。

1.去除唯一属性

唯一属性通常是一些id属性,这些属性对分析并不会有帮助,只会占用资源,删除即可。

2.缺失值处理

1)缺失值的分类

完全随机缺失、随机缺失、完全不随机缺失

2)缺失值处理的三种方法

a.均值插补。 数据的属性分为定距型和非定距型。如果缺失值是定距型的,就以该属性存在值的平均值来插补缺失的值;如果缺失值是非定距型的,就根据统计学中的众数原理,用该属性的众数(即出现频率最高的值)来补齐缺失的值。
b.利用同类均值插补。同均值插补的方法都属于单值插补,不同的是,它用层次聚类模型预测缺失变量的类型,再以该类型的均值插补。
c.极大似然估计(Max Likelihood ,ML)。在缺失类型为随机缺失的条件下,假设模型对于完整的样本是正确的,那么通过观测数据的边际分布可以对未知参数进行极大似然估计(Little and Rubin)。这种方法也被称为忽略缺失值的极大似然估计,对于极大似然的参数估计实际中常采用的计算方法是期望值最大化(Expectation Maximization,EM)。

d.多重插补(Multiple Imputation,MI)。多值插补的思想来源于贝叶斯估计,认为待插补的值是随机的,它的值来自于已观测到的值。具体实践上通常是估计出待插补的值,然后再加上不同的噪声,形成多组可选插补值。根据某种选择依据,选取最合适的插补值。

3)插值法填充

包括随机插值,多重差补法,热平台插补,拉格朗日插值,牛顿插值等

4)模型填充

使用回归、贝叶斯、随机森林、决策树等模型对缺失数据进行预测。

上述内容参考知乎[数据万花筒]的《机器学习(三):数据预处理--数据预处理的基本方法》。

三、特征工程

 数据决定了机器学习的上限,而算法只是尽可能逼近这个上限。特征工程指的是把原始数据转变为模型的训练数据的过程,它的目的就是获取更好的训练数据特征,使得机器学习模型逼近这个上限。特征工程能使得模型的性能得到提升,有时甚至在简单的模型上也能取得不错的效果。特征工程在机器学习中占有非常重要的作用,一般认为括特征构建、特征提取、特征选择三个部分。

1.特征构建

特征构建是指从原始数据中人工的找出一些具有物理意义的特征。属性分割和结合是特征构建时常使用的方法。如果存在时间相关属性,可以划出不同的时间窗口,得到同一属性在不同时间下的特征值。

2.特征提取

特征提取:特征值化是为了计算机更好地理解数据

API:sklearn.feature_extraction

2.1 字典特征提取

        字典特征提取(特征离散化)- 类别 -》 one-hot编码
            sklearn.feature_extraction.DictVectorizer(sparse=True, ...)
            vector 向量
                矩阵 matrix 二维数组
                向量 vector 一维数组
                DictVectorizer.fit_transform(X) X:字典或者包含字典的迭代器返回值:返回sparse矩阵
                DictVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
                DictVectorizer.get_feature_names() 返回类别名称

            应用场景:
                1)pclass,sex 数据集当中类别特征比较多
                    a.将数据集的特征 -》 字典类型
                    b.DictVectorizer 转换
                2)拿到的数据本身就是字典类型
def dict_demo():
    """
    提取字典格式的特征
    :return:
    """
    data = [
        {'city': '北京', 'temperature': 100},
        {'city': '上海', 'temperature': 60},
        {'city': '深圳', 'temperature': 30}
    ]

    # 1.实例化一个转换器类
    # sparse=True时,返回稀疏矩阵,将非零值显示出来,按位置显示出来 可以节省内存 -》 提高加载效率
    transfer = DictVectorizer(sparse=False)
    # 2.调用fit_transform()
    data_new = transfer.fit_transform(data)
    print('data_new:\n', data_new, type(data_new))
    print('特征名字:\n', transfer.get_feature_names())

    return None

2.2 文本特征提取

文本特征提取:对文本数据进行特征值化
    单词 作为 特征
    方法1.  CountVectorizer 统计每个样本特征词出现的个数  stop_words=[] 停用词表
    sklearn.feature_extraction.text.CountVectorizer(stop_words=[])  返回词频矩阵
            CountVectorizer.fit_transform(X):文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
            CountVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
            CountVectorizer.get_feature_names() 返回值:单词列表
def text_demo():
    """
    提取文本类型的特征
    :return:
    """
    data = ["life is short,i like like python", "life is too long,i dislike python"]

    # 1.实例化一个转换器类
    transfer = CountVectorizer()
    # 2.调用fit_transform()
    data_new = transfer.fit_transform(data)
    print('data_new:\n', data_new, type(data_new))  # toarray() 将 sparse 类型转换为 ndarray
    print('data_new:\n', data_new.toarray(), type(data_new.toarray()))  # toarray() 将 sparse 类型转换为 ndarray
    print('特征名字:\n', transfer.get_feature_names())

    return None
    关键词:在某一类别的文章中,出现的次数很多,但是在其他类别的文章当中出现很少

方法2.TfidfVectorizer    TF-DEF - 重要程度
    sklearn.feature_extraction.text.TfidfVectorizer(stop_words=[None,...])  返回词频矩阵
            TfidfVectorizer.fit_transform(X):文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
            TfidfVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
            TfidfVectorizer.get_feature_names() 返回值:单词列表
def text_chines_demo():
    """
    中文文本提取
    :return:
    """
    new_data = []
    data = ["然后使用词频-逆文档频率 (TF-IDF) 计算每个操作码序列的重要性频率。TF-IDF 用于衡量文档中每个短语的重要性程度。术语频率评估每个应用程序中操作码出现的次数,",
            "而逆文档频率计算每个操作码值的重要性级别。", "在第三阶段,测试了几个机器学习分类器使用操作码序列区分恶意 "]

    for d in data:
        new_data.append(" ".join(list(jieba.cut(d))))
    print(new_data)

    transfer = CountVectorizer(stop_words=['TF', '-', 'IDF'])
    data_final = transfer.fit_transform(new_data)
    print(data_final.toarray())  # sparse -> ndarray
    print(transfer.get_feature_names())

    return None
def text_class_demo():
    """
    使用TF-IDF提取文本类型的特征
    :return:
    """
    new_data = []

    data = ["然后使用词频-逆文档频率 (TF-IDF) 计算每个操作码序列的重要性频率。TF-IDF 用于衡量文档中每个短语的重要性程度。术语频率评估每个应用程序中操作码出现的次数,",
            "而逆文档频率计算每个操作码值的重要性级别。", "在第三阶段,测试了几个机器学习分类器使用操作码序列区分恶意 "]

    for d in data:
        # print('-'*20, list(jieba.cut(d)), type(list(jieba.cut(d))))
        # print("-"*20, " ".join(list(jieba.cut(d))), type(" ".join(list(jieba.cut(d)))))
        new_data.append(" ".join(list(jieba.cut(d))))
    print(new_data)

    transfer = TfidfVectorizer()
    data_final = transfer.fit_transform(new_data)
    print(data_final.toarray())  # sparse -> ndarray
    print(transfer.get_feature_names())

    return None

 3.特征降维

特征降维:降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程。

降维的两种方式:特征选择和主成分分析
1)特征选择
    数据中包含冗余或者相关变量(或称为特征、属性、指标等),旨在从原有特征中找出主要特征

    Filter 过滤式
        a.方差选择法:
            低方差特征过滤:删除低方差的一些特征
            特征方差小:某个特征与大多样本的值比较接近
            特征方差答:某个特征与很多样本的值都有差别
sklearn.feature_selection.VarianceThreshold(threshold = 0.0)  threshold 阈值
    删除所有低方差特征
    Variance.fit_transfrom(X)
        X:numpy array 格式的数据[n_samples,n_features]
        返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有祥同志的特征
def variance():
    # 1.读取文件
    data = pandas.read_csv('data/dating.txt')
    data = data.iloc[:, :3]

    # 2.实例化一个转换器类
    var = VarianceThreshold()
    # 3.
    new_data = var.fit_transform(data)
    print('new_data:\n', new_data, new_data.shape)
    print(var.get_feature_names_out())

    return None
        b.相关系数:特征之间的相关程度
            皮尔逊相关系数:反应变量之间相关关系密切程度的统计指标
            from scipy.stats import pearsonr

            特征与特征之间相关性很高:
                1)选择其一
                2)加权求和
                3)主成分分析
def pear():
    # 1.读取文件
    data = pandas.read_csv('data/dating.txt')
    data = data.iloc[:, :3]

    # 2.实例化一个转换器类
    r = pearsonr(data['milage'], data['Liters'])
    print('相关系数:\n', r)
    r2 = pearsonr(data['milage'], data['Consumtime'])
    print('相关系数:\n', r2)
    r3 = pearsonr(data['Liters'], data['Consumtime'])
    print('相关系数:\n', r3)

    plt.figure(figsize=(20, 8), dpi=100)
    plt.scatter(data['milage'], data['Liters'])
    # plt.show()

    return None
   Embeded 嵌入式
        a.决策树
        b.正则化
        c.深度学习
2)主成分分析(PCA)
    定义:高维数据转化为低维数据的过程,在此过程中会舍弃原有数据、创造新的变量。
    作用:数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
    应用:回归分析或者聚类分析当中
sklearn.decomposition.PCA(n_components=None)
将数据分解为较低维数空间
n_components:
    小数:表示保留百分之多少的信息
    整数:减少到多少特征
PCA.fit_transform(X)
    X:numpy array格式的数据 [n_samples,n_features]
返回值:转换后指定维数的array

数值型数据的无量纲化:

数据标准化是将样本的属性缩放到某个指定的范围。
为什么需要进行归一化/标准化?
    特征的单位或者大小相差较大,或者某特征的方差相比较其它特征要大出几个数量级,容易影响目标结果,使得一些算法无法学习到其它的特征。

归一化:通过对原始数据进行变换把数据映射到(默认是[0,1])之间
sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)...)
MinMaxScalar.fit_transform(X)
    X:numpy array格式的数据 [n_samples,n_features]
返回值:转换后的形状相同的array
def minmax_demo():
    """
    归一化
    :return:
    """
    # 1.导入数据
    data = pd.read_csv('data/dating.txt')
    print(data, type(data))
    data = data.iloc[:, :3]
    # 2.实例化一个转化器
    scal = MinMaxScaler(feature_range=(2, 3))
    # 3.调用fit_transform()
    new_data = scal.fit_transform(data)
    print(new_data, type(new_data))

    return None
    注意:最大值和最小值是变化的,非常容易受到异常点的影响
    缺点:鲁棒性较差,只适合传统精确小数据场景    

标准化:通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
                                         
    如果出现异常点,由于具有一定的数据量,少量的异常点对于平均值的影响不大,从而方差改变较小。
sklearn.preprocessing.StandardScaler()  处理之后,对每列来说,所有数据都聚集在均值为0附近,标准差为1
    StandardScaler.fit_transform(X)
        X:numpy array格式的数据 [n_samples,n_features]
    返回值:转换后的形状相同的array
def standard_demo():
    """
    归一化
    :return:
    """
    # 1.导入数据
    data = pd.read_csv('data/dating.txt')
    print(type(data))
    data = data.iloc[:, :3]
    print(data)
    # 2.实例化一个转化器
    scal = StandardScaler()
    # 3.调用fit_transform()
    new_data = scal.fit_transform(data)
    print(new_data, type(new_data))

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

四、模型算法

估计器(estimator) - sklearn机器学习算法的实现
        a.实例化一个 estimator
        b.estimator.fit(x_train, y_train)  计算
            -- 调用完毕,模型生成
        c.模型评估:
            直接比对真实值和预测值
                y_predict = estimator.predict(x_test)
                y_test == y_predict
            计算准确率
                accuracy = estimator.score(x_test, y_test)

1.用于分类的算法

1.1 k-近邻算法

*** k-近邻算法(根据"邻居"推算你的类别 —— 欧氏距离) sklearn.neighbors
   如果一个样本的特征空间中的k个最相似(即特征空间中最近邻)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
   如果 k = 1,容易受到异常点的影响
   如果 k 取值较大,容易受到样本不均衡的影响

   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方法的值来决定最合适的算法

   优点:简单易于理解,易于实现,无须训练
   缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大
       必须指定k值,k值选择不当则分类精度不能保证
   使用场景:小数据
def knn_iris_gscv():
    """
    使用knn对鸢尾花数据进行分类,使用交叉验证和网格调参
    :return:
    """
    # 1.获取数据
    iris = datasets.load_iris()
    data = iris.data  # 特征
    target = iris.target  # 目标值
    # print(data, data.shape)
    # print(target, target.shape)

    # 3.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=6)

    # 2.特征工程:标准化
    scal = StandardScaler()
    x_train = scal.fit_transform(x_train)
    x_test = scal.transform(x_test)  # 这里使用的是transform,是利用train中的标准进行的
    # print(new_data, new_data.shape)

    # 4.模型训练
    estimator = KNeighborsClassifier()

    # 加入网格搜素与交叉验证
    param_dict = {"n_neighbors": [1, 3, 5, 7, 9]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)
    estimator.fit(x_train, y_train)

    # 5.模型评估
    y_predict = estimator.predict(x_test)
    print('比对真实值和预测值:\n', y_test == y_predict)

    accuracy = estimator.score(x_test, y_test)
    print('准确率:\n', accuracy)
    print(
        f"最佳参数:\n {estimator.best_params_}\n最佳结果:\n{estimator.best_score_}\n最佳估计器:\n{estimator.best_estimator_}\n交叉验证结果:\n{estimator.cv_results_}")

1.2 贝叶斯 

*** 贝叶斯 sklearn.naive_bayes
朴素贝叶斯算法:(朴素? 假设特征与特征之间相互独立)
    朴素 + 贝叶斯
    应用场景:文本分类

    sklearn.naive_bayes.MultinomialNB(alpha=0.0)
        朴素贝叶斯分类
        alpha:拉普拉斯平滑系数

    优点:
        朴素贝叶斯模型发源于古典书学理论,有稳定的分类效率
        对缺失数据不太敏感,算法简单,常用于文本分类
        分类准确度高,速度快
    缺点:由于使用了样本属性独立性的假设,所以如果特征属性有关联时其效果不好
def nb_news():
    """
    使用朴素贝叶斯算法对新闻进行分类
    :return:
    """
    # 1.获取数据
    news = datasets.fetch_20newsgroups(subset='all')

    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.2, random_state=42)

    # 3.特征工程:文本特征提取-tfidf
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4.朴素贝叶斯算法预估流程
    estimator = MultinomialNB(alpha=0.0)
    estimator.fit(x_train, y_train)

    # 5.模型评估
    y_predict = estimator.predict(x_test)
    print('比对真实值和预测值:\n', y_test == y_predict)

    accuracy = estimator.score(x_test, y_test)
    print('准确度:\n', accuracy)

    return None

 1.3 决策树

*** 决策树 sklearn.tree
ID3:信息增益 最大的准则
C4.5:信息增益比 最大的尊则
CART:
    分类树:基尼系数 最小的准则 在sklearn中可以选择划分的默认原则
    优势:划分更加细致

class sklearn.tree.DecisionTreeClassifier(criterion='gini',max_depth=None,random_state=None)
    决策树分类器
    criterion:默认是 ‘gini’系数,也可以选择信息增益的熵‘entropy’
    max_depth:树的深度大小
    random_state:随机数种子

找到最高效的决策顺序 - 信息增益
信息增益 = 信息熵 - 条件熵

* 决策树可视化
    保存树的结构到dot文件
    sklearn.tree.export_graphviz() 该函数能够导出DOT格式
        tree.export_graphviz(estimator,out_file='tree.dot',feature_names=['','']

    优点:简单理解和解释,可视化
    缺点:容易产生过拟合
    改进:
        减枝cart算法
        随机森林
def iris_decisiontree():
    """
    决策树 鸢尾花
    :return:
    """
    # 1.导入数据
    iris = datasets.load_iris()
    data = iris.data
    target = iris.target
    print(iris.feature_names)

    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=42)

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

    # 4.训练模型
    estimator = DecisionTreeClassifier()

    # 5.网格搜索和交叉验证
    param_dict = {'max_depth': [1, 3, 5, 7, 9]}
    estimator2 = GridSearchCV(estimator, param_grid=param_dict, cv=5)
    estimator.fit(x_train, y_train)

    # 6.模型评估
    y_predict = estimator.predict(x_test)
    print('真实值与预测值:\n', y_test == y_predict)

    accuracy = estimator.score(x_test, y_test)
    print('精确度:\n', accuracy)

    # print('最好的参数:\n', estimator2.best_params_)
    # print('最好的精确度:\n', estimator2.best_score_)

    # 可视化tree
    export_graphviz(estimator, out_file='resources/tree.dot', feature_names=iris.feature_names)

    return None

1.4 随机森林 

*** 随机森林
    随机:两个随机
        a.训练集随机:boostrap 随机有放回抽样
        b.特征随机:从M个特征中随机抽取m个特征 M>>m
            降维
    森林:包含多个决策树的分类器

    为什么进行随机抽样训练集?
        答:如果不随机抽样训练集,每棵树的训练集都是一样的,那么最终训练出来树分类结果也是完全一样的
    为什么要有放回的抽样?
        答:如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都没有交集,这样每棵树都是“有偏的”,也就是每棵树训练出来都是有很大的差异的

    sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion='gini',max_depth=None,
        bootstrap=True,random_state=None,min_samples_split=2
        * n_estimators 森林里的树的个数
        * criterion 分割特征的测量方法
        * max_depth 树的最大深度
        * bootstrap 是否在构建树时使用放回抽样
        * min_samples_split 节点划分最少样本数
        * min_samples_leaf 叶子节点的最小样本数

   优点:能够有效的运行在大数据集上,处理具有高维特征的输入样本,能够评估各个特征在分类问题上的重要性
def titanic_randomforest():
    """
    使用决策树预测泰坦尼克号乘客生存预测
    :return:
    """
    # 1.导入数据
    data = pd.read_csv('resources/titanic/titanic.csv')
    # print(data.head())

    target = data['survived']
    train = data.drop(['survived', 'row.names', 'name', "embarked", "home.dest", "room", "ticket", "boat"], axis=1)

    print(train.head(), type(train))

    # 2.特征处理
    # 2.1 缺失值处理
    train['age'].fillna(train['age'].mean(), inplace=True)

    # 2.2 对类别特征
    # 转换成字典 ---> 将字符型特征转换成数值型
    train = train.to_dict(orient='records')

    # 3.拆分数据
    x_train, x_test, y_train, y_test = train_test_split(train, target, test_size=0.2, random_state=42)

    # 字典特征抽取
    transfer = DictVectorizer()
    x_train = transfer.fit_transform(x_train).toarray()
    x_test = transfer.transform(x_test).toarray()
    print(x_train, type(x_train))

    # 4.特征工程 标准化
    transfer2 = StandardScaler()
    x_train = transfer2.fit_transform(x_train)
    x_test = transfer2.transform(x_test)

    # 5.模型训练
    estimator = RandomForestClassifier()
    estimator.fit(x_train, y_train)

    # 6.网格搜索和交叉验证
    param_dict = {'n_estimators': [120, 200, 300, 500, 800, 1200], 'max_depth': [1, 3, 5, 7, 9]}
    estimator2 = GridSearchCV(estimator, param_grid=param_dict, cv=5)

    estimator2.fit(x_train, y_train)

    # 7.模型评估
    y_predict = estimator2.predict(x_test)
    print('预测值与真实值:\n', y_test == y_predict)

    accuracy = estimator2.score(x_test, y_test)
    print('精确度:\n', accuracy)

    print('最好的参数:\n', estimator2.best_params_)
    print('最好的精确度:\n', estimator2.best_score_)
    print(estimator.feature_importances_)

    return None

2.用于回归的算法

2.1 线性回归

*** 线性回归 sklearn.linear_model.LinearRegression
定义:线性回归(Linear regression)是利用回归方程对一个或多个特征值和目标值之间关系进行建模的一种分析方式。
    y = wTx + b
特点:只有一个自变量的情况成为单变量回归,过各自变量的情况叫做多元回归。

线性回归中线性模型有两种,一种是线性关系,另一种是非线性关系。
注意:线性关系一定是线性模型,线性模型不一定是线性关系
def linear():
    """
    波士顿房价预测 - 线性回归
    :return:
    """
    # 1.获取数据集
    boston = datasets.load_boston()
    data = boston.data
    target = boston.target

    # 2.划分数据集
    x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=42)

    # 3.特征工程:无量纲化 - 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4.模型训练
    # estimator = LinearRegression(fit_intercept=True)  # 正规方程优化损失
    # estimator = SGDRegressor(learning_rate="invscaling", eta0=0.01)  # 梯度下降优化损失
    estimator = Ridge()  # 带有L2正则化的回归 解决过拟合问题
    estimator.fit(x_train, y_train)
    print('权重系数为:\n', estimator.coef_)
    print('偏置为:\n', estimator.intercept_)

    # 5.模型评估
    y_predict = estimator.predict(x_test)
    me = mean_squared_error(y_test, y_predict)  # 均方误差
    print('均方误差:\n', me)

    accuracy = estimator.score(x_test, y_test)
    print('accuracy:\n', accuracy)

    return None

2.2 损失函数 

损失函数/cost:真实值与预测
    最小二乘法

    优化损失:目的是找到最小损失对应的 W 值
        a.正规方程:需要计算方程,时间复杂度高O(n3)
        sklearn.linear_model.LinearRegression(fit_intercept=True)  不能解决拟合问题
            fit_intercept:是否计算偏置
            LinearRegression.coef_:回归系数
            LinearRegression.intercept_:偏置

        b.梯度下降:需要选择学习率,迭代求解,特征数量较大时可以使用
            sklearn.linear_model.SGDRegression(loss="squared_loss", fit_intercept=True, learning_rate="invscaling",eta0=0.01)
            loss:损失类型
                loss="squared_loss":普通最小二乘法
            SGDrRegression.coef_:回归系数
            SGDRegression.intercept_:偏置

 2.3 岭回归

*** 岭回归 sklearn.linear_model.Ridge
    岭回归 - 带 L2 正则化的线性回归
    sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True,solver="auto",normalize=False)
        alpha:正则化力度,也叫Y 取值 0~1 1~10
        solver:会根据数据自动选择优化方法
        normalize:是否进行标准化
        Ridge.coef_:回归系数
        Ridge.intercept_:回归偏置 

2.4 逻辑回归 

*** 逻辑回归 sklearn.linear_model.LogisticRegression(solver='liblinear',penalty='l2',C=1.0)  
                                              
    线性回归的输出就是逻辑回归的输入
    回归的结果输入到 sigmoid 激活函数中,映射到 [0, 1] 区间中的一个概率值,默认阈值为0.5

    逻辑回归的损失函数称为对数似然损失
    solver:优化求解方式
    penalty:正则化种类
    C:正则化力度

    注意:默认将类别数量少的作为正例
应用场景:广告点击率、是否为垃圾邮箱、是否患病、金融诈骗、虚假账号
def logistic():
    """
    使用逻辑回归对癌症进行分类
    :return:
    """
    # 1.导入数据 ,加上names
    names = ['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']
    data = pd.read_csv('resources/cancer/breast-cancer-wisconsin.data', names=names)
    print(data.head())
    # 2.数据处理 缺失值
    # 将数据中出现的 ? 替换为 np.nan
    print(data.isnull().sum())
    data = data.replace(to_replace='?', value=np.nan)
    # 删除缺失值所在的行
    data.dropna(inplace=True)  # inplace=True 表示就地删除
    print(data.isnull().sum())

    # 3.数据集划分
    y = data['Class']
    # x = data.drop(['Class'], axis=1)
    x = data.iloc[:, 1:-1]
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

    # 4.特征工程 - 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 5.模型训练
    estimator = LogisticRegression()
    estimator.fit(x_train, y_train)

    print('回归系数:\n', estimator.coef_)
    print('偏置:\n', estimator.intercept_)

    # 6.模型评估
    y_predict = estimator.predict(x_test)
    print('y_test == y_predict:\n', y_test == y_predict)

    accuracy = estimator.score(x_test, y_test)
    print('精确度:\n', accuracy)

    print('精确和召回率为:\n', 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)  # np.where(condition,x,y) 当where内有三个参数时,第一个参数表示条件,当条件成立时where方法返回x,当条件不成立时where返回y

    print('roc_auc_score:\n', roc_auc_score(y_true, y_predict))

    # 7.模型保存
    joblib.dump(estimator, 'resources/logistic.pkl')

    return None

 2.5 欠拟合与过拟合

欠拟合与过拟合
    训练集上表现好,测试集表现不好 - 过拟合
        解决方法:正则化:
            L1正则化:可以是其中一些 W 的值直接为0,删除这个特征的影响
                损失函数 + Y惩罚项(w的绝对值之和)
                LASSO 回归
            L2正则化(常用):可以使其中一些参数 W 变得很小,接近于0,削弱某个特征的影响
                损失函数 + Y惩罚项(w的平方和)
                Ridge 岭回归
    训练集上表现不好,测试集表现也不好 - 欠拟合
        解决方法:增加特征

3.无监督学习

*** 聚类 sklearn.cluster.KMeans K - 超参数

        1)看需求

        2)调节超参数 Kmeans性能评估指标:(高内聚,低耦合)

                轮廓系数

sklearn.metrics.silhouette_score(X,labels)  计算所有样本的平均轮廓系数

        X:特征值

        labels:被聚类标记的目标值

优点:采用迭代式算法,直观易懂并且非常实用

缺点:容易收敛到局部最优(解决方法:多次聚类)

应用场景:聚类一般用在分类之前

import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score



def Kmeans_demo():
    # 1.获取数据
    order_products = pd.read_csv("./instacart/order_products__prior.csv")
    products = pd.read_csv("./instacart/products.csv")
    orders = pd.read_csv("./instacart/orders.csv")
    aisles = pd.read_csv("./instacart/aisles.csv")

    # 2.合并表
    # 合并aisles和products
    tab1 = pd.merge(aisles, products, on=['aisle_id', 'aisle_id'])  # merge 用于合并表
    tab2 = pd.merge(tab1, order_products, on=['product_id', 'product_id']) 
    tab3 = pd.merge(tab2, orders, on=['order_id', 'order_id']) 
    
    # 3.找到user_id和aisle之间的关系
    table = pd.crosstab(tab3['user_id'], tab3['aisle'])  # 交叉表

    # 4.pca降维

    transfer = PCA(n_components=0.95)
    data_new = transfer.fit_transform(table)
    
    estimator = KMeans(n_clusters=3)
    estimator.fit(data_new)
    
    y_predict = estimator.predict(data_new)
    silhouette_score(data_new, y_predict)  # 特征和聚类标记的标签

4.模型选择和调优

1) 什么是交叉验证(cross valication)

        交叉验证:将拿到的训练数据分为训练集和验证集。

        例:将训练集分成4份,其中一份作为验证集,然后经过四次测试,每次都更换不同的验证集,即得到4组模型的结果,取平均值作为最终结果。--- 4折交叉验证。 作用:为了被评估的模型更加准确可信,防止过拟合。

2)超参数搜索-网格搜索(Grid Search)

        通常情况下,有很多参数时需要手动指定的(如k-近邻算法中的k值),这种叫做超参数。

3)模型选择与调优API

sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)

        * 对估计器指定参数进行详尽搜索

        * estimator:估计器对象

        * param_grid:估计器参数(dict){"n_neighbors":[1, 3, 5]}

        * cv:指定交验验证的次数

        * fit():输入训练数据

        * score():准确率

        * 结果分析: 最佳参数:best_params_ 最佳结果:best_score_ 最佳估计器:best_estimator_ 交叉验证结果:cv_results_

4) 模型保存和加载 import joblib

        保存:joblib.dump(rf,'test.pkl')

        加载:estimator = joblib.load('test.pkl')

5.评价指标

回归性能评估:
    均方误差 (yi - y`)^2 / m

    sklearn.metrics.mean_squared_error(y_true, y_pred)  返回浮点数结果
精确率与召回率
sklearn.metric.classification_report(y_true,y_pred,labels[],target_names=None) 返回值为每个类别的精确率和召回率
    1.混淆矩阵:在分类任务中,预测结果和正确标记之间存在四种不同组合,构成混淆矩阵(适用于多分类)

    2.精确率:预测结果为正例样本中真实为正例的比例

    3.召回率:真实为正例的样本中预测结果为正例的比例

    4.F1-score:反映了模型的稳健性
        F1-score = 2*准确率*召回率 / 准确率+召回率
ROC曲线和AUC指标:
    TPR和FPR
        TPR = TP / (TP + FN) - 正例的召回率
            所有真实类别为1的样本中,预测类别为1的比例
        FPR = FP / (FP + TN) - 反例的召回率
            所有真实类别为0的样本中,预测类别为1的比例

    sklearn.metrics.roc_auc_score(y_true, y_score)
        y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
        y_score:预测得分,可以是正例的估计概率、置信值或者分类器方法的返回值

总结

        随机科学技术的快速发展,人工智能和大数据对人们的影响越来越大,机器学习是实现人工智能的途径,因此学好机器学习十分重要。这里主要对机器学习的基础知识进行总结,这些知识是我从黑马程序员人工智能课上所总结的,这个老师讲得很好,对刚入门的小白十分友好,基础 + 实战,网址:人工智能基础 | 机器学习入门:Python机器学习算法基础(B站最全完整版)AI|机器学习实战|经典算法|深度学习|数学基础|计算机视觉|决策树算法_哔哩哔哩_bilibi​​​​​​i

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值