• 机器学习十讲第二讲


    矩阵的逆

    NumPy 矩阵求逆函数

    • numpy.linalg 模块包含线性代数的函数,可计算逆矩阵、求特征值、解线性方程组以及求解行列式等
    • 行列式:np.linalg.det(A)
    • 计算逆矩阵:np.linalg.inv(A)
    import numpy as np
    # 格式化numpy输出
    np.set_printoptions(formatter={'float':'{:0.2f}'.format})
    A = np.array([[4,5,1],[0,8,3],[9,4,7]])
    
    # 求行列式
    print("行列式:" + str(np.linalg.det(A)))
    B = np.linalg.inv(A) # 求逆
    print("A的逆矩阵为B:")
    print(A_inv)
    print("BA:") # 结果验证
    print(B.dot(A))
    print("AB:")
    print(A.dot(B))

    什么是回归

    在回归模型中,需要预测的变量叫做因变量,用来解释因变量变化的变量叫做自变量

    一元线性回归

    一元线性回归的求解

    多线性回归

    多元线性回归的矩阵表示

    优化目标的矩阵表示

    模型求解:参数估计

    线性回归的问题:

    1. 实际数据可能不是线性的?

    解决方法:多项式回归:使用原始特征的二次项、三次项

    • 线性回归解决非线性问题
    • 问题:维度灾难、过度拟合

    2. 多重共线性

    3. 过度拟合问题:当模型的变量过多时,线性回归可能会出现过度拟合问题

    正则化

    岭回归

    岭迹分析

    岭回归与LASSO回归

    正则化路径分析

    回归模型的评价指标

    案例:实用回归模型预测鲍鱼年龄

     

    因为案例直接保存在“我的案例”中,里面已经有了相关代码,但有些地方设置成了“___”,需要自行填充,因此我会附上填充后的源码与运行截图,大部分代码和示例代码是相同的:

    先发个图说明一下情况,下面是的代码是我新开了一个代码块再写了一遍:

     接下来进入正题

    复制代码
    #首先将数据集引入
    import pandas as pd
    import warnings
    warnings.filterwarnings('ignore')
    data = pd.read_csv("./input/abalone_dataset.csv")
    #输出前五行
    data.head()
    复制代码

    #查看数据集中样本数量和特征数量
    data.shape

    #使用seaborn绘制sex的取值分布条形图
    import seaborn as sns
    import matplotlib.pyplot as plt
    %matplotlib inline
    sns.countplot(x = "sex", data = data)

    复制代码
    #绘制直方图观察特征取值
    i = 1 # 子图记数
    plt.figure(figsize=(16, 8))
    for col in data.columns[1:]:
        plt.subplot(4,2,i)
        i = i + 1
        sns.distplot(data[col])  
    plt.tight_layout()
    复制代码

    #根据sex画出不同特征之间的点缀图,seaborn提供了pairplot方法
    sns.pairplot(data,hue="sex")

     

    #计算特征之间的相关性
    corr_df = data.corr()
    corr_df

    #为了能够直观看出关系,可以绘制热力图
    fig, ax = plt.subplots(figsize=(12, 12))
    #原图是绿色的,这里改成蓝色
    ax = sns.heatmap(corr_df,linewidths=.5,cmap="Blues",annot=True,xticklabels=corr_df.columns, yticklabels=corr_df.index)
    ax.xaxis.set_label_position('top') 
    ax.xaxis.tick_top()

    #OneHot编码处理
    sex_onehot = pd.get_dummies(data["sex"], prefix="sex")
    #参数sex_onehot.columns
    data[sex_onehot.columns] = sex_onehot
    data.head(2)

    #添加取值为1的特征列
    data["ones"] = 1
    data.head(5)

     一般每过一年,鲍鱼就会在其壳上留下一道深深的印记,这叫生长纹,就相当于树木的年轮。在本数据集中,我们要预测的是鲍鱼的年龄,可以通过环数 rings 加上 1.5 得到。所以:

    #令age=rings+1.5
    data["age"] = data["rings"] + 1.5
    data.head(5)

     将预测目标设置为 age 列,然后构造两组特征,一组包含 ones,一组不包含 ones 。对于 sex 相关的列,我们只使用 sex_F 和 sex_M后面的模型比对中是否使用数据集的ones列会出现分歧,因此要提前分好。

    复制代码
    #构造特征集
    y = data["age"]
    features_with_ones = ["length","diameter","height","whole_weight","shucked_weight","viscera_weight","shell_weight","sex_F","sex_M","ones"]
    features_without_ones=["length","diameter","height","whole_weight","shucked_weight","viscera_weight","shell_weight","sex_F","sex_M"]
    X = data[features_with_ones]
    
    #训练集与测试集切分train_test_split
    from sklearn import model_selection
    X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size=0.2, random_state=111)
    复制代码

    首先是线性回归:

    公式及参数说明如下:

    复制代码
    #根据公式补充参数
    import numpy as np
    def linear_regression(X,y):
        w = np.zeros_like(X.shape[1])
        if np.linalg.det(X.T.dot(X)) != 0 :
            w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
        return w
    
    #根据模型获取系数
    w1 = linear_regression(X_train,y_train)
    w1 = pd.DataFrame(data = w1,index = X.columns,columns = ["numpy_w"])
    w1.round(decimals=2)
    复制代码

     这里偷个懒,直接附上案例中的说明,sklearn后面要用到多次:

    复制代码
    #使用之前介绍的sklearn作系数比对
    from sklearn import linear_model
    lr = linear_model.LinearRegression()
    #刚才处理的时候将新设置的ones放了进去,而这里使用时不能添加ones列
    lr.fit(X_train[features_without_ones],y_train)
    w_lr = []
    w_lr.extend(lr.coef_)
    w_lr.append(lr.intercept_)
    w1["lr_sklearn_w"] = w_lr
    w1.round(decimals=2)
    复制代码

     对比效果是一致的,证明模型构建成功。

    岭回归:

    公式及参数说明:

    复制代码
    def ridge_regression(X,y,ridge_lambda):
        #eye方法:生成单位矩阵
        penality_matrix = np.eye(X.shape[1])
        #令单位矩阵的最后一个元素=0
        penality_matrix[X.shape[1] - 1][X.shape[1] - 1] = 0
        #输入参数
        w = np.linalg.inv(X.T.dot(X) + ridge_lambda*penality_matrix).dot(X.T).dot(y)
        return w
    
    #使用岭回归模型,与之前两个模型进行比对
    w2 = ridge_regression(X_train,y_train,1.0)
    w1["numpy_ridge_w"] = w2
    w1.round(decimals=2)
    复制代码

    复制代码
    #再与sklearn中的岭回归进行对比
    from sklearn.linear_model import Ridge
    ridge = linear_model.Ridge(alpha=1.0)
    #这里还是使用无ones列的数据集
    ridge.fit(X_train[features_without_ones],y_train)
    w_ridge = []
    w_ridge.extend(ridge.coef_)
    w_ridge.append(ridge.intercept_)
    w1["ridge_sklearn_w"] = w_ridge
    w1.round(decimals=2)
    复制代码

    LASSO:

    LASSO的解没有公式(上面已经提到过),因此直接使用函数构建:

    复制代码
    #使用LASSO
    from sklearn.linear_model import Lasso
    #alpha设置要小一些,否则
    lasso = linear_model.Lasso(alpha=1)
    lasso.fit(X_train[features_without_ones],y_train)
    print(lasso.coef_)
    print(lasso.intercept_)
    复制代码

    上边示范一下当alpha参数设置过大时的情况

    因此设置适当的值:

    from sklearn.linear_model import Lasso
    #因此设置0.001,设置值越小压缩越小,因为这次案例使用的数据集容量本就不多
    lasso = linear_model.Lasso(alpha=0.001)
    lasso.fit(X_train[features_without_ones],y_train)
    print(lasso.coef_)
    print(lasso.intercept_)

    模型评估:

    MAE:

    复制代码
    #平均绝对误差MAE
    ##使用sklearn.metrics进行预测
    from sklearn.metrics import mean_absolute_error
    #线性回归
    y_test_pred_lr = lr.predict(X_test.iloc[:,:-1])
    print(round(mean_absolute_error(y_test,y_test_pred_lr),4))
    
    #岭回归
    y_test_pred_ridge = ridge.predict(X_test[features_without_ones])
    print(round(mean_absolute_error(y_test,y_test_pred_ridge),4))
    
    #LASSO
    y_test_pred_lasso = lasso.predict(X_test[features_without_ones])
    print(round(mean_absolute_error(y_test,y_test_pred_lasso),4))
    复制代码

    R2:

    复制代码
    #决定系数R2
    from sklearn.metrics import r2_score
    #线性回归
    print(round(r2_score(y_test,y_test_pred_lr),4))
    #岭回归
    print(round(r2_score(y_test,y_test_pred_ridge),4))
    #LASSO
    print(round(r2_score(y_test,y_test_pred_lasso),4))
    复制代码

     残差图:

    复制代码
    #构建残差图进行诊断
    ##横轴是模型的预测值,纵轴是预测值与真实值的差距
    plt.figure(figsize=(9, 6))
    y_train_pred_ridge = ridge.predict(X_train[features_without_ones])
    plt.scatter(y_train_pred_ridge, y_train_pred_ridge - y_train, c="b", alpha=0.6)
    plt.scatter(y_test_pred_ridge, y_test_pred_ridge - y_test, c="r",alpha=0.6)
    plt.hlines(y=0, xmin=0, xmax=30,color="b",alpha=0.6)
    plt.ylabel("Residuals")
    plt.xlabel("Predict")
    复制代码

     岭迹:

    复制代码
    #构建岭迹
    alphas = np.logspace(-10,10,20)
    coef = pd.DataFrame()
    for alpha in alphas:
        ridge_clf = Ridge(alpha=alpha)
        ridge_clf.fit(X_train[features_without_ones],y_train)
        df = pd.DataFrame([ridge_clf.coef_],columns=X_train[features_without_ones].columns)
        df['alpha'] = alpha
        coef = coef.append(df,ignore_index=True)
    coef.head().round(decimals=2)
    复制代码

    复制代码
    #根据刚才构建好的数据,进行绘图
    plt.rcParams['figure.dpi'] = 300 #分辨率
    plt.figure(figsize=(9, 6))
    coef['alpha'] = coef['alpha']
    
    for feature in X_train.columns[:-1]:
        plt.plot('alpha',feature,data=coef)
    ax = plt.gca()
    ax.set_xscale('log')
    plt.legend(loc='upper right')
    plt.xlabel(r'$alpha$',fontsize=15)
    plt.ylabel('系数',fontsize=15)
    
    plt.show()
    复制代码

    LASSO的正则化路径:

    复制代码
    #绘制LASSO的正则化路径
    ##数据准备
    coef = pd.DataFrame()
    for alpha in np.linspace(0.0001,0.2,20):
        lasso_clf = Lasso(alpha=alpha)
        lasso_clf.fit(X_train[features_without_ones],y_train)
        df = pd.DataFrame([lasso_clf.coef_],columns=X_train[features_without_ones].columns)
        df['alpha'] = alpha
        coef = coef.append(df,ignore_index=True)
    coef.head()
    ##绘图
    plt.figure(figsize=(9, 6))
    for feature in X_train.columns[:-1]:
        plt.plot('alpha',feature,data=coef)
    plt.legend(loc='upper right')
    plt.xlabel(r'$alpha$',fontsize=15)
    plt.ylabel('系数',fontsize=15)
    plt.show()
    复制代码

      总结:

  • 相关阅读:
    点击Notification之后收起通知栏
    Visual Studio常用的快捷键
    数据库语法二之外键
    数据引擎 创建表完整语法,字段类型,约束条件
    数据库 tcp协程实现并发 回调函数
    GIL以及协程
    进程,互斥锁,生产者消费者,线程
    udp协议,进程(同步,异步)
    单例模式,网络编程之tcp协议以及粘包问题
    网络编程
  • 原文地址:https://www.cnblogs.com/022414ls/p/14459500.html
Copyright © 2020-2023  润新知