Python_ML-Day03: 线性回归、岭回归、逻辑回归、k-means

Python_ML-Day03: 线性回归、岭回归、逻辑回归、k-means

1. 回归问题的判定
    - 目标值是一个连续的值
    - 寻找一种能预测的趋势
    - 线性关系的函数:  y = kx + b
    - b 偏置

2. 线性关系模型
    - 一个通过属性xn 的线性组合来进行预测的函数
    - 线性回归通过一个或者多个 特征值x1,x2 与 目标值f(x) 之间进行建模的回归分析
    - f(x) = w0 + w1*x1 + w2*x2 + w3*x3
    - f(x) = W * X
    - W:[w0,w1,w2,w3] 矩阵
    - X:[1,x1,x2,x3] 矩阵

3. 损失函数[误差大小] - 误差的平方和
    - 最小二乘法
    - f(&) = (h(x1) - y1)^2 + (h(x2) - y2)^2 + ... + (h(xn) - yn)^2
    - h(xn): 第n个样本预测值
    - yn: 第n个样本的真实值,目标值

4. 求解W权重矩阵的方式
    - 最小二乘法之正规方程
        1. w = (X`t * X)^-1 * X`t * Y
            - X: 特征值矩阵
            - X`t: 特征值矩阵的逆矩阵
            - Y:目标值矩阵
        2. 直接能求出最小损失下的w权重矩阵
        3. 缺点
            - 当特征值过于复杂,求解速度太慢,甚至无法求解
        4. sklearn.linear_model.LinearRegression()
        5. 返回 coef_: 回归系数w
    - 最小二乘法的梯度下降
        0. 公式
            w1 = -w1 - & * k
            w2 = -w2 - & * k
        1. 学习速率 &
        2. 梯度下降方向k,根据公式计算
            k = cos(w0 + w1x1) / w1
        3. 理解: 随机一个w初始值,然后沿着这个函数下降的方向去查找最小值,每次迭代都更新W的值,直到W最小
        4. 适用 训练数据规模非常庞大的场景
        5. sklearn.linear_model.SGDRegerssion()
        6. 返回 coef_: 回归系数w

5. 房价预测案列分析
    - 获取 房价数据
    - 房价数据 分割
    - 数据标准化 - 公式中涉及到 不同特征值之间相加,相减等操作,就需要标准化。比如一个是10000,一个是0.0001,怎么相加?
    - 使用正规方程和梯度下降进行线性回归模型预测

6. 回归性能评估
    - 均方误差
        1. 均方误差评价机制
            - MSE = [(y1 - `y1)^2 + (y2 - `y2)^2 + ... +(ym - `ym)^2] / m
            - y1,y2,y3: 预测值
            - `y1, `y2, `y3 真实值
        2. 均方误差回归损失 metrics.mean_squard_error(y_true, y_pred)
            - y_true 真实值
            - y_pred 预测值
            - 返回: 浮点数的结果
            - 注意: 此处的预测值和真实值均为 标准化之前的值。如果数据已经标注化,要进行inverse_transform
    - 对数似然损失函数 - 逻辑回归评估
        1. 对数似然损失函数
           - 如果预测结果为1 if y = 1, cos(h) = -log(h(x))
           - 如果预测结果为0 if y = 0, cos(h) = -log(1 - h(x))
           - cos(h) 越小,那么预测的准确度越高
           - h(x): 预测概率值 - 目标值是1 类,预测为1 类的概率
        2. 使用梯度下降,去更新权重,从而降低损失函数的值
           - 怎么保证梯度下降最低点的最低?
               - 多次随机初始化,选择多个起始点,去执行梯度下降,每个起始点都应一个最低点,在这些最低点中选择一个最最低的
               - 求解过程中,调整学习率
               - 注意: 上面两种解决办法,不能100% 找到全局最低点,但是效果也很好

7. 正规方程和梯度下降的对比
    梯度下降                                正规方程
    需要选择学习率 &                         不需要
    需要多次迭代                             一次运算得出结果
    特征数量很大,适用                        特征数量很大,运算代价大,大于10000不建议
    适用各种类型的预测                        只适用线性模型

8. 欠拟合 和 过拟合
    - 欠拟合
        1. 学习的不足,模型不能很好的表述特征值
        2. 数学表现为 训练误差大,并且测试误差也大
        3. 特点: 模型过于简单
        4. 原因: 学习到的特征过少
        5. 解决: 增加数据的特征数量
    - 过拟合
        0. 普通线性回归很容易过拟合
        1. 学习的太充足了,以至于有一些本属于类别的也被排除了
        2. 数学表现为 训练误差小,但是测试误差大
        3. 特点是: 模型过于复杂,比如决策树
        4. 原因: 原始特征过于多。存在一些嘈杂特征。 模型要尝试去兼顾所有的测试点,往往导致模型复杂
        5. 解决:
            - 特征选择: 消除关联性很大的特征(很难做)
            - 交叉验证: 让所有的数据都能训练到
            - 正则化:L2正则化:岭回归

9.正则化
    - px = w1 * x1 + w2 * x2^2 + w3 * x3^3 + w4 * x4^4 ...
    - 随机去减小 特征值x的权重系数 w1,w2,w3,w4 的值, 直到其慢慢为0
    - 然后去查找 变化最大的那些系数,然后去掉这些系数对应的特征值
    - 如公式的 w3, w4 对用的4次方,肯定影响很大,拟合的是一个锯齿曲线,
      而让w3,w4 = 0 , 则锯齿消失,变成平滑的曲线

10.Ridge 岭回归: 带有正则化的线性回归
    - sklearn.linear_model.Ridge(alpha = 1.0)
    - 具有L2正则化的线性最小二乘法回归
    - alpha:正则化力度,超参数
    - coef_: 回归系数
    - alpha 正则化力度越大,权重越趋近于0,模型越简单,取值 0-1, 1-10
    - 优点
        0.解决过拟合
        1.回归得到的回归系数更符合实际,更加可靠
        2.能让估计参数的波动范围变小,变得更稳定。模型稳定且简单
        3.在存在病态数据,嘈杂数据较多的数据中,有较大的实用价值

11.模型的保存与加载
    - 保存与加载模型
        1. from sklearn.externals import joblib
        2. joblib.dump(estimator, 'D:/model.pkl')
        3. estimator = joblib.load('D:/model.pkl')

12.分类算法 - 逻辑回归 - 用回归的算法去解决分类问题
    - 将回归的问题转换成分类的算法去求解
    - 解决二分类问题的利器
        1.广告点击率
        2.是否为垃圾邮件
        3.是否患病
        4.金融诈骗
        5.虚假账号
    - sigmoid 函数
        1.将连续性的函数,转换成离散的点,并且点的y值介于[0-1]
        2.[0-1] 恰恰符合了概率的范围
        3.这个函数就将线性回归的输入转换成分类问题的概率值
        4.g(z) = 1/[1 + e ^(-z)]
        5.g(z): 作为函数的输出,表现为[0-1]之间的概率值
        6.e的(-z)次幂: 中的z 表示回归算法的结果,作为函数的输入
        7.如果z=0,g(z) = 0.5 作为阈值,比如,大于0.5 = 1,小于0.5 = 0,就输出了二分类
    - 逻辑回归的评估 - 对数似然损失函数
        1. 对数似然损失函数
           - 如果预测结果为1 if y = 1, cos(h) = -log(h(x))
           - 如果预测结果为0 if y = 0, cos(h) = -log(1 - h(x))
           - cos(h) 越小,那么预测的准确度越高
           - h(x): 预测概率值 - 目标值是1 类,预测为1 类的概率
    - LogisticRegression 回归分类器
        1. sklearn.linear_model.LogisticRegression(penalty='l2',C=1.0)
        2. penalty: 正则化 默认l2 正则化
        3. C:正则化力度,超参数
        4. coef_: 回归系数
    - 解决过拟合
    - 案例分析:
        1.原始数据的下载地址:
            - https://archive.ics.uci.edu/ml/machine-learning-databases/
        2.数据描述
            - 699条样本,共11列数据,第一列用语检索的id,后9列分别是与肿瘤
            相关的医学特征,最后一列表示肿瘤类型的数值。
            - 包含16个缺失值,用”?”标出。
        3.正例: 哪个类别少,判断概率值 (= 1) 的就是哪个
        4.pd.read_csv(’’,names=column_names)
            column_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']
            return:数据
            replace(to_replace=’’,value=):返回数据
            dropna():返回数据
        5.流程
            - 网上获取数据(工具pandas)
            - 数据缺失值处理、标准化
            - LogisticRegression估计器
    - 应用场景
        广告点击率预测、电商购物搭配推荐
    - 优点
        适合需要得到一个分类概率的场景
    - 缺点
        当特征空间很大时,逻辑回归的性能不是很好(看硬件能力)
        只能解决二分类

13.判别模型与生成模型
    - 看是否有先验概率P(c)
        1.有,生成模型: K近邻,决策树,随机森林,神经网络等
        2.五,判别模型: 朴素贝叶斯
    - 先验概率P(c)
        1. 需要通过历史数据去统计计算出来的一些概率值

14.非监督学习
    - 聚类 k-means, 在预测分类之前
    - k: 把数据划分成多少个类别
    - 划分步骤 k=3
        1.在数据中,随机抽取三个样本,当做三个类别的中心点k1,k2,k3
        2.分别计算其余的点到 k1,k2,k3的距离,得到其余的每个点到三个点的距离(a,b,c)
        3.距离哪个中心点(k1,k2,k3)近(a,b,c中值最小),就将这个点划分到哪个类中。
        4.从而形成三个族群
        5.分别计算三个族群的平均值(中心点),作为新的中心点k1,k2,k3
        6.然后与旧的中心点进行比较
        7.如果新的中心点与旧的中心点全部重合,则聚类结束
          如果不同,那么使用新的中心点,继续重复以上步骤
          直到新旧中心点全部重合
    - sklearn.cluster.KMeans(n_cluster=8,init='k-means++')
        1. n_cluster: 开始聚类中心的数量 k
        2. init: 初始化方法。默认为k-means++
    - 案例分析Instacart Market
    - k-means 的评估指标
        1. 轮廓系数[-1,1],越靠近1 聚类效果越好,一般 0, 0.1 就还可以了
            - 计算公式:sc = bi - ai / max(bi,ai)
            - 点i:数据集中的每一个点
            - bi: 点i 到其他族群所有样本点的距离的最小值
            - ai: 点i 到自身族群所有样本点的距离的平均值
            - 最好:外部距离最大化,内部距离最小化(bi 远远大于ai, sc = 1)
            - 最差的情况: ai 远远大于bi, sc = -1
            - 计算所有样本的平均轮廓系数: sklearn.metrics.silhouette_score(X, labels)
                - X:样本集
                - labels:目标值[预测的结果]
    - 源码
        def kmains():
        # 读取四张表的数据
        prior = pd.read_csv("./KaggleData/order_products__prior.csv")

        products = pd.read_csv("./KaggleData/products.csv")

        orders = pd.read_csv("./KaggleData/orders.csv")

        aisles = pd.read_csv("./KaggleData/aisles.csv")

        # 合并4张表到一张表
        _mg = pd.merge(prior, products, on=['product_id', 'product_id'])
        _mg = pd.merge(_mg, orders, on=['order_id', 'order_id'])
        mt = pd.merge(_mg, aisles, on=['aisle_id', 'aisle_id'])

        mt.head(10)

        # 交叉表 -- 特殊的分组工具
        cross = pd.crosstab(mt['user_id'], mt['aisle'])

        # 进行主成分分析,进行降维操作
        pca = PCA(n_components=0.9)
        data = pca.fit_transform(cross)
        # k-means k=4 假设分为4个类别
        from sklearn.cluster import KMeans
        # 把样本数量减少
        x = data[:500]
        x.shape
        km = KMeans(n_clusters=4)
        km.fit(x)
        pre = km.predict(x)
        print(pre)
        import matplotlib.pyplot as plt
        plt.figure(figsize=(10, 10))
        # 建立4个颜色的列表
        colord = ['orange', 'green', 'blue', 'red']
        colr = [colord[i] for i in pre]
        plt.scatter(x[:, 1], x[:, 20], color=colr)
        plt.show()
        # 评判聚类效果 - 轮廓系数
        sc = silhouette_score(x, pre)
        print(sc)

15.源码
    from sklearn.datasets import load_boston
    from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, LogisticRegression
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.metrics import mean_squared_error, classification_report
    from sklearn.externals import joblib
    import pandas as pd
    import numpy as np


    def linear(lr):
        """
        线性回归
        :param lr: 回归器
        :return:
        """
        # 加载数据
        dt = load_boston()
        x = dt.data
        y = dt.target
        # 分割数据
        x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
        # 标准化 - 注意,特征值和目标值都要标准化,而且 特征值和目标值的StandScalar 不能是同一个
        # 因为 两个的数据不同
        sd = StandardScaler()
        x_train = sd.fit_transform(x_train)
        x_test = sd.transform(x_test)
        sd = StandardScaler()
        y_train = sd.fit_transform(y_train.reshape(-1, 1))
        y_test = sd.transform(y_test.reshape(-1, 1))
        # 使用线性回归算法
        lr.fit(x_train, y_train)
        y_pre = lr.predict(x_test)
        y_pre = sd.inverse_transform(y_pre)
        # 使用 均方误差回归损失 评估模型
        y_pre_true = sd.inverse_transform(y_test)
        mean = mean_squared_error(y_pre_true, y_pre)
        # print("回归系数:", lr.coef_)
        print("预测房价1:", y_pre)
        # print("均方误差", mean)
        # 模型的保存与加载
        joblib.dump(lr, 'D:/model.pkl')
        model = joblib.load('D:/model.pkl')
        y_pre = model.predict(x_test)
        print("预测房价2:", sd.inverse_transform(y_pre))


    def logisticRegression():
        """
        逻辑回归做二分类预测
        :return:
        """
        # 读取数据
        column = ['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']
        dt = pd.read_csv(
            "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",
            names=column)
        print(dt)
        # 缺失值替换以及删除
        dt = dt.replace(to_replace='?', value=np.nan)
        dt = dt.dropna()
        # 数据分割
        x_train, x_test, y_train, y_test = train_test_split(dt[column[1:10]], dt[column[10]], test_size=0.25)
        # 标准化
        std = StandardScaler()
        x_train = std.fit_transform(x_train)
        x_test = std.transform(x_test)
        # 逻辑回归预测
        lg = LogisticRegression(C=1.0, penalty='l2')
        lg.fit(x_train, y_train)
        pre = lg.predict(x_test)
        print("w权重系数:", lg.coef_)
        print("准确率:", lg.score(x_test, y_test))
        print("召回率:", classification_report(y_test, pre, labels=[2, 4], target_names=["良性", "恶性"]))


    if __name__ == '__main__':
        # # 普通线性回归
        # linear(LinearRegression())
        # # 梯度下降线性回归
        # linear(SGDRegressor())
        # l2正则化的线性回归-岭回归
        # linear(Ridge(alpha=1.0))
        logisticRegression()




你可能感兴趣的:(机器学习,Python)