当前位置:   article > 正文

鲍鱼数据集案例分析-预测鲍鱼年龄(线性回归/梯度下降法实操)

鲍鱼数据集案例分析-预测鲍鱼年龄(线性回归/梯度下降法实操)

数据集来源UCI Machine Learning Repository: Abalone Data Set

一、数据集探索性分析

  1. import pandas as pd
  2. import numpy as np
  3. import seaborn as sns
  4. data = pd.read_csv("abalone_dataset.csv")
  5. data.head()

  1. #查看数据集中样本数量和特征数量
  2. data.shape
  3. #查看数据信息,检查是否有缺失值
  4. data.info()

 

data.describe()

 

数据集一共有4177个样本,每个样本有9个特征。其中rings为鲍鱼环数,加上1.5等于鲍鱼年龄,是预测变量。除了sex为离散特征,其余都为连续变量。

  1. #观察sex列的取值分布情况
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. %matplotlib inline
  5. sns.countplot(x='sex',data=data)
  6. data['sex'].value_counts()

对于连续特征,可以使用seaborn的distplot函数绘制直方图观察特征取值情况。我们将8个连续特征的直方图绘制在一个4行2列的子图布局中。

  1. i=1
  2. plt.figure(figsize=(16,8))
  3. for col in data.columns[1:]:
  4. plt.subplot(4,2,i)
  5. i=i+1
  6. sns.distplot(data[col])
  7. plt.tight_layout()

 

sns.pairplot()官网 seaborn.pairplot — seaborn 0.12.2 documentation

默认情况下,此函数将创建一个轴网格,这样数据中的每个数字变量将在单行的y轴和单列的x轴上共享。对角图的处理方式不同:绘制单变量分布图以显示每列数据的边际分布。也可以显示变量的子集或在行和列上绘制不同的变量。

  1. #连续特征之间的散点图
  2. sns.pairplot(data,hue='sex')

* 1.第一行观察得出:length和diameter、height存在明显的线性关系
* 2.最后一行观察得出:rings与各个特征均存在正相关性,其中与height的线性关系最为直观
* 3.对角线观察得出:sex“I”在各个特征取值明显小于成年鲍鱼

  1. #计算特征之间的相关系数矩阵
  2. corr_df = data.corr()
  3. corr_df

  1. fig,ax =plt.subplots(figsize=(12,12))
  2. #绘制热力图
  3. ax = sns.heatmap(corr_df,linewidths=5,
  4. cmap='Greens',
  5. annot=True,
  6. xticklabels=corr_df.columns,
  7. yticklabels=corr_df.index)
  8. ax.xaxis.set_label_position('top')
  9. ax.xaxis.tick_top()

二、鲍鱼数据预处理

1.对sex特征进行OneHot编码,便于后续模型纳入哑变量

  1. #类别变量--无先后之分,使用OneHot编码
  2. #使用Pandas的get_dummies函数对sex特征做OneHot编码处理
  3. sex_onehot =pd.get_dummies(data['sex'],prefix='sex')
  4. #prefix--前缀
  5. data[sex_onehot.columns] = sex_onehot
  6. #将set_onehot加入data
  7. data.head()

2.添加取值为1的特征

  1. #截距项
  2. data['ones']=1
  3. data.head()

3. 计算鲍鱼的真实年龄

  1. data["age"] =data['rings']+1.5
  2. data.head()

4.筛选特征

多重共线性
*最小二乘的参数估计为\hat{w} =(X^{T}X)^{-1} X^{T} y如果变量之间存在较强的共线性,则$X^TX$近似奇异,对参数的估计变得不准确,造成过度拟合现象。
*解决办法:正则化、主成分回归、偏最小二乘回归

所以sex_onehot的三列,线性相关,三列取两列选入x中

  1. y=data['rings']
  2. #不使用sklearn(包含ones)
  3. features_with_ones=['length', 'diameter', 'height', 'whole weight', 'shucked weight',
  4. 'viscera weight', 'shell weight', 'sex_F', 'sex_I','ones' ]
  5. #使用sklearn(不包含ones)
  6. features_without_ones=['length', 'diameter', 'height', 'whole weight', 'shucked weight',
  7. 'viscera weight', 'shell weight', 'sex_F', 'sex_I']
  8. X=data[features_with_ones]

5. 将鲍鱼数据集划分为训练集和测试集

  1. #80%为训练集,20%为测试集
  2. from sklearn.model_selection import train_test_split
  3. X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=111)

三、实现线性回归和岭回归

1. 使用Numpy使用线性回归

  1. #判断xTx是否可逆,并计算得出w
  2. #解析解求线性回归系数
  3. def linear_regression(X,y):
  4. w = np.zeros_like(X.shape[1])
  5. if np.linalg.det(X.T.dot(X))!=0:
  6. w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
  7. return w
  1. #使用上述实现的线性回归模型在鲍鱼训练集上训练模型
  2. w1=linear_regression(X_train,y_train)
  1. w1 = pd.DataFrame(data=w1,index=X.columns,columns=['numpy_w'])
  2. w1.round(decimals=2)

所以, 求得的模型为
y=-1.12 * length + 10 * diameter + 20.74 * height + 9.61 * whole_weight - 20.05 * shucked_weight - 12.07 * viscera - weight + 6.55 * shell_weight + 0.01 * sex_F - 0.37 * sex_I + 3.70

2.使用Sklearn实现线性回归

  1. from sklearn.linear_model import LinearRegression
  2. lr = LinearRegression()
  3. lr.fit(x_train[features_without_ones],y_train)
  4. print(lr.coef_)

  1. w_lr = []
  2. w_lr.extend(lr.coef_)
  3. w_lr.append(lr.intercept_)
  4. w1['lr_sklearn_w']=w_lr
  5. w1.round(decimals=2)

3.使用numpy实现岭回归

  1. def ridge_regression(X,y,ridge_lambda):
  2. penalty_matrix = np.eye(X.shape[1])
  3. penalty_matrix[X.shape[1] - 1][X.shape[1] - 1] = 0
  4. w=np.linalg.inv(X.T.dot(X) + ridge_lambda*penalty_matrix).dot(X.T).dot(y)
  5. return w

\hat{w} =(X^{T}X+\lambda X)^{-1} X^{T} y

  1. #正则化系数设置为1
  2. w2 = ridge_regression(X_train,y_train,1.0)
  3. print(w2)

  1. w1['numpy_ridge_w']=w2
  2. w1.round(decimals=2)

 

4. 利用sklearn实现岭回归

  1. from sklearn.linear_model import Ridge
  2. ridge = Ridge(alpha=1.0)
  3. ridge.fit(X_train[features_without_ones],y_train)
  4. w_ridge = []
  5. w_ridge.extend(ridge.coef_)
  6. w_ridge.append(ridge.intercept_)
  7. w1["ridge_sklearn_w"] = w_ridge
  8. w1.round(decimals=2)

 岭迹分析

  1. alphas = np.logspace(-10,10,20)
  2. coef = pd.DataFrame()
  3. for alpha in alphas:
  4. ridge_clf = Ridge(alpha=alpha)
  5. ridge_clf.fit(X_train[features_without_ones],y_train)
  6. df = pd.DataFrame([ridge_clf.coef_],columns=X_train[features_without_ones].columns)
  7. df['alpha']=alpha
  8. coef = coef.append(df,ignore_index=True)
  9. coef.round(decimals=2)

  1. import matplotlib.pyplot as plt
  2. %matplotlib inline
  3. #绘图
  4. #显示中文和正负号
  5. plt.rcParams['font.sans-serif']=['SimHei','Times New Roman']
  6. plt.rcParams['axes.unicode_minus']=False
  7. plt.rcParams['figure.dpi']=300#分辨率
  8. plt.figure(figsize=(9,6))
  9. coef['alpha']=coef['alpha']
  10. for feature in X_train.columns[:-1]:
  11. plt.plot('alpha',feature,data=coef)
  12. ax=plt.gca()
  13. ax.set_xscale('log')
  14. plt.legend(loc='upper right')
  15. plt.xlabel(r'$\alpha$',fontsize=15)
  16. plt.ylabel('系数',fontsize=15)

四、 使用LASSO构建鲍鱼年龄预测模型

LASSO的目标函数

(Xw-y)^T(Xw-y)+\lambda \parallel w\parallel _{1}

随着

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/101391
推荐阅读
相关标签