项目目的:熟悉数据分析项目流程,完成焦虑症数据GAD7数据分析
项目材料:数据表GAD7.xlsx、数据说明GAD7.json
我们选取两个特征变量:受教育程度及年薪。目标变量:焦虑症程度。
受教育程度可选选项0-6依次为小学,中学,高中,大学专科,大学本科,硕士研究生,博士研究生。
年薪可选选项0-5依次为0-4万,5-10万,11-20万,21-40万,41-80万,超过80万。
焦虑症程度0-21逐渐增强。
1.导入包
#导入包
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
2.导入数据
#变量初始化
X=[]
Y=[]
#导入数据
def get_data(file_name):
datafile = u'C:\\Users\\HP\\Desktop\\GAD7a.xlsx'#文件所在位置,u为防止路径中有中文名称,此处没有,可以省略
data = pd.read_excel(datafile,header=0)
data=np.array(data)
#数组切片对变量进行赋值
Y=data[:,2:]
X=data[:,0:data.shape[1]-1]
print(X.shape)#打印X的维度
return X,Y
X,Y=get_data('GAD7a.xlsx')
3.作图展示
#作图展示
ax = plt.figure().add_subplot(111, projection = "3d")
ax.scatter(X[:, 0], X[:, 1],Y, c = "b", marker = 'o', s = 10)
ax.set_xlabel("education")
ax.set_ylabel("income")
plt.show()
由图形展示散点的密集程度来看,教育程度在2.3.4阶段,年薪在0.1阶段的人群患有焦虑症频率较高。
4.建模与训练
# 建立模型
model = LinearRegression()
# 开始训练
model.fit(X,Y)
5.结果展示
# 斜率
print("coefficients: ", model.coef_)
w1 = model.coef_[:,0]
w2 = model.coef_[:,1]
# 截距
print("intercept: ", model.intercept_)
b = model.intercept_
# 测试
X = [[5, 5]]
predict = model.predict(X)
print("predict: ", predict)
由上述的最佳拟合线的截距和回归系数可以算出其线性回归线方程:y = 6.63 + (-0.03)×受教育程度 + (-0.2)×年薪。由此可知,对于给定了年薪,如果受教育程度增加一个点,对应焦虑症程度将减少0.03个点。对于给定了教育程度,如果年薪增加一个点,对应焦虑症程度将减少0.2个点。
接下来对数据集进行预测与模型测评。同样使用predict与score函数来获取所需要的预测值与得分。
6.回归结果作图
Y=np.mat(Y)#数组转化为矩阵
X=np.mat(X)#数组转化为矩阵
ax = plt.figure().add_subplot(111, projection = "3d")
ax.scatter(X[:, 0], X[:, 1], Y, c = "b", marker = 'o', s = 10)
x0 = X[:, 0]
x1 = X[:, 1]
x0, x1 = np.meshgrid(x0, x1)
b = model.intercept_
z = b + w1 * x0 + w2 * x1
ax.plot_surface(x0, x1, z, color = "r")
ax.set_xlabel("education")
ax.set_ylabel("income")
ax.set_zlabel("risk")
plt.show()
7.回归检验
score = model.score(X,Y)
print(score)
#对线性回归进行预测
Y_pred = model.predict(X)
print(Y_pred)
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
#显示图像
plt.show()
8.模型优化
数据归一化处理:当特征数据的范围相差比较大时,我们可以把数据进行归一化处理,即在创建模型时增加normalize=True参数:mdoel=LinearRegression(normalize=True
当然,数据归一化处理只会加快算法收敛速度,优化算法训练的效率,无法提升算法的准确性。
优化模型准确性:当数据针对训练样本的评分较低,即数据对训练数据的拟合成本比较高,这是个典型的欠拟合现象,方法一是挖掘更多输入特征,方法二是增加多项式特征。我们通过增加多项式特征,其实就是增加模型的复杂度。
#创建多项式模型的函数
def polynomial_model(degree=1):
polynomial_feature=PolynomialFeatures(degree=degree,include_bias=False)
linear_regression=LinearRegression(normalize=True)
pipeline=Pipeline([("polynomial_feature",polynomial_feature),("linear_regression",linear_regression)])
return pipeline
#使用二阶多项式来拟合数据
model=polynomial_model(degree=2)
9.总结
由于第一次使用python进行多元线性回归的代码实现,过程中出现了很多bug,使用sklearn库可以直接调用许多算法,十分方便,但重点还是要理解算法的数学内涵,具体参考笔记监督学习——多变量线性回归(梯度下降算法),从得分情况来看,第一个模型的拟合效果一般,明显需要优化模型的准确性。模型优化的更多方法后续会再写一篇。
总结一下代码过程中遇到的bug。
1.ValueError: Found input variables with inconsistent numbers of samples: [22203, 1]
出现这种错误是因为在训练的过程中,X和Y的长度必须一致。
可以采用如下代码来检查维度
print(X.shape)
print(y.shape)
2.ValueError: Input contains NaN, infinity or a value too large for dtype(‘float32’)
起初数据集中含有缺失值没有处理
3.list indices must be integers or slices, not tuple
数据集没有转化为矩阵!
总代码:
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
X=[]
Y=[]
#导入数据
def get_data(file_name):
datafile = u'C:\\Users\\HP\\Desktop\\GAD7a.xlsx'#文件所在位置,u为防止路径中有中文名称,此处没有,可以省略
data = pd.read_excel(datafile,header=0)
data=np.array(data)
#数组切片对变量进行赋值
Y=data[:,2:]
X=data[:,0:data.shape[1]-1]
print(X.shape)#打印X的维度
return X,Y
X,Y=get_data('GAD7a.xlsx')
#作图展示
ax = plt.figure().add_subplot(111, projection = "3d")
ax.scatter(X[:, 0], X[:, 1],Y, c = "b", marker = 'o', s = 10)
ax.set_xlabel("education")
ax.set_ylabel("income")
plt.show()
# 建立模型
model = LinearRegression()
# 开始训练
model.fit(X,Y)
# 斜率
print("coefficients: ", model.coef_)
w1 = model.coef_[:,0]
w2 = model.coef_[:,1]
# 截距
print("intercept: ", model.intercept_)
b = model.intercept_
# 测试
X = [[5, 5]]
predict = model.predict(X)
print("predict: ", predict)
Y=np.mat(Y)#数组转化为矩阵
X=np.mat(X)#数组转化为矩阵
ax = plt.figure().add_subplot(111, projection = "3d")
ax.scatter(X[:, 0], X[:, 1], Y, c = "b", marker = 'o', s = 10)
x0 = X[:, 0]
x1 = X[:, 1]
x0, x1 = np.meshgrid(x0, x1)
b = model.intercept_
z = b + w1 * x0 + w2 * x1
ax.plot_surface(x0, x1, z, color = "r")
ax.set_xlabel("education")
ax.set_ylabel("income")
ax.set_zlabel("risk")
plt.show()
参考资料:https://blog.csdn.net/will_zhan/article/details/83096318
未完待续