实验一:线性模型应用实践
如果以下图片失效可以尝试运行代码,图片会加载出来了,代码是完整的,因为当初交报告是也是用markdown写的转载上来就不行了
一、实验目的
1.了解线性模型的相关概念;
2.理解并掌握线性回归算法原理;
3.理解并掌握对数几率回归算法原理;
4.进一步熟悉Pandas对文件操作;
5.初步掌握线性模型中线性回归和对数几率回归在生活中的应用;
二、 实验内容
1、运用线性回归算法给出波士顿房价预测。
2、运用对数几率回归给出鸢尾花类分类,要求其精度为0.90以上。
三、 实现过程分析
1)、 波士顿房价:
总体思维导图:
主要步骤:
第一步:导入所需要的python包并导入数据
import pandas as pd#导入数据文件
import numpy as np#科学计算计算库
import seaborn as sns
import matplotlib.pyplot as plt#数据可视化库
import pandas_profiling as ppf#eda
from sklearn import metrics
from sklearn.preprocessing import LabelEncoder#标签编码
from sklearn.preprocessing import MinMaxScaler#归一化
from sklearn.model_selection import train_test_split#数据集的划分
from sklearn.linear_model import LinearRegression#算法
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_absolute_error#评估函数
第二步:查看数据是否有空值,由于得到数据较为完全,所以不需要缺省值处理
# 1:获取数据
# 载入波士顿房屋的数据集
data = np.genfromtxt('housing1.txt')
df = pd.DataFrame(data,
columns=['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B',
'LSTAT', 'MEDV'])
df.to_csv('housing1.csv')
print("Boston housing dataset has {} data points with {} variables each.".format(*data.shape))
# 查看数据描述
print(df.describe())
print(df.head())
第三步:查看数据代表意义,并得知房价为目标函数,计算前面每一个数据的特征与房价的关系系数,此处需要进行数据处理
# 数据代表特征
# CRIM:城镇人均犯罪率。
# ZN:住宅用地超过 25000 sq.ft. 的比例。
# INDUS:城镇非零售商用土地的比例。
# CHAS:查理斯河空变量(如果边界是河流,则为1;否则为0)。
# NOX:一氧化氮浓度。
# RM:住宅平均房间数。
# AGE:1940 年之前建成的自用房屋比例。
# DIS:到波士顿五个中心区域的加权距离。
# RAD:辐射性公路的接近指数。
# TAX:每 10000 美元的全值财产税率。
# PTRATIO:城镇师生比例。
# B:1000(Bk-0.63)^ 2,其中 Bk 指代城镇中黑人的比例。
# LSTAT:人口中地位低下者的比例。
# MEDV:自住房的平均房价,以千美元计。
# 2:寻找因子
# 寻找对房价影响大的因子
# 计算每一个特征对造假的相关系数 协方差 并将大于0.5的数据集输出
corr = df.corr()['MEDV']
print(corr[abs(corr) > 0.5].sort_values())
第四步:筛选出关系系数大于0.5的特征,并选取特定特征值,减去其他无关信息。
观察LSTAT与MEDV的关系散点图:
观察RM与MEDV的关系散点图:
观察PTRATIO与MEDV的关系散点图:
# 由于得到的数据较为完全所以不需要缺省值处理
# 于是选取这三个为主要特征,其余值可以移除
df = df[['LSTAT', 'PTRATIO', 'RM', 'MEDV']] # 选取特征值,减去其他无关信息
第五步:分割训练集和测试集并对特征工程标准化
# 3:数据集划分
X = df.drop(['MEDV'], axis=1) # 划分样本特征及
X.info()
y = np.array(df['MEDV']) # 样本标签
train_X, test_X, train_Y, test_Y = train_test_split(X, y, test_size=0.3, random_state=0) # 分割训练集和测试集
# 4:特征工程-标准化
data = StandardScaler()
train_X = data.fit_transform(train_X)
test_X = data.fit_transform(test_X)
第六步:线性回归(正规方程、梯度下降)
# 线性回归:正规方程
def liner(train_X,train_Y,test_X,test_Y):
# 5:线性回归(正规方程)
# 加载模型
lin = LinearRegression()
# 拟合数据
lin.fit(train_X, train_Y)
def Gradient_descent(train_X,train_Y,test_X,test_Y):
# 5:线性回归(梯度下降法)
# 加载模型
lin = SGDRegressor(max_iter=1000)
lin.fit(train_X, train_Y)
第七步:对模型进行评估,预测并计算出误差
# 6:模型评估
# 进行预测
predict = lin.predict(test_X)
# 误差
print('The accuracy of the Gradient descent Regression is: ',metrics.mean_squared_error(predict,test_Y))
2)、 鸢尾花:
总体思维导图:
主要步骤:
第一步:导入所需要的python包并导入数据
import pandas as pd#导入数据文件
import numpy as np#科学计算计算库
import seaborn as sns
import matplotlib.pyplot as plt#数据可视化库
import warnings
import pandas_profiling as ppf#eda
from sklearn import metrics
from sklearn.preprocessing import LabelEncoder#标签编码
from sklearn.preprocessing import MinMaxScaler#归一化
from sklearn.model_selection import train_test_split#数据集的划分
from sklearn.linear_model import LinearRegression#算法
from sklearn.metrics import mean_absolute_error#评估函数
from sklearn.preprocessing import StandardScaler#标准化
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfVectorizer
from matplotlib.font_manager import FontProperties
第二步:查看数据是否空值与代表意义,并寻找特征与种类关系
鸢尾花缺失率为0,所以不需要增加缺省值
花萼长宽与种类的关系
花瓣长宽与种类之间的关系
# 2:寻找相关因子
# sepal_len:萼长
# sepal_width:萼宽
# petal_len:瓣长
# petal_width:瓣宽
# iris - setosa:山鸢尾
# iris - versicolour:变色鸢尾
# iris - virginica:维吉尼亚鸢
antV = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
# g = sns.lmplot(data=df, x='sepal_width', y='sepal_len', palette=antV, hue='class')
# g = sns.lmplot(data=df, x='petal_len', y='petal_width', palette=antV, hue='class')
# plt.show()
第三步:寻找特征与种类的关系
特征热力图
fig = plt.gcf()
fig.set_size_inches(12, 8)
mask=np.zeros_like(df.corr(), dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
fig = sns.heatmap(df.corr(), annot=True, cmap=antV, linewidths=1, linecolor='k', square=True, mask=mask, vmin=-1,
vmax=1, cbar_kws={"orientation": "vertical"}, cbar=True,center=0)
第四步:分割训练集和测试集并对特征工程标准化
# 4:测试集与训练集
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=90)
# 同一算法模型在不同的训练集和测试集的会得到不同的准确率导致无法调参。
# sklearn 中可以通过添加random_state,通过固定random_state的值,每次可以分割得到同样训练集和测试集。
# 因此random_state参数主要是为了保证每次都分割一样的训练集和测试机,大小可以是任意一个整数,在调参缓解,只要保证其值一致即可。
第五步:特征化工程标准化,对数几率回归
# 5:特征化工程-标准化
data = StandardScaler()
train_X = data.fit_transform(train_X)
test_X = data.fit_transform(test_X)
# 6:对数几率回归
model = LogisticRegression()
第六步:对模型进行评估,预测并计算出误差
model.fit(train_X, train_y)
prediction = model.predict(test_X)
print('The accuracy of the Logistic Regression is: {0}'.format(metrics.accuracy_score(prediction, test_y)))
四、 源代码
1):波士顿房价预测:
# -*- coding: utf-8 -*-
#开发团队:机器人学院
#开发人员:蟹老板
#开发时间:2020/9/2823:26
#文件名:hourse
#开发工具:PyCharm
import pandas as pd#导入数据文件
import numpy as np#科学计算计算库
import seaborn as sns
import matplotlib.pyplot as plt#数据可视化库
import pandas_profiling as ppf#eda
from sklearn import metrics
from sklearn.preprocessing import LabelEncoder#标签编码
from sklearn.preprocessing import MinMaxScaler#归一化
from sklearn.model_selection import train_test_split#数据集的划分
from sklearn.linear_model import LinearRegression#算法
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_absolute_error#评估函数
# 线性回归:正规方程
def liner(train_X,train_Y,test_X,test_Y):
# 5:线性回归(正规方程)
# 加载模型
lin = LinearRegression()
# 拟合数据
lin.fit(train_X, train_Y)
# 6:模型评估
# 进行预测
predict = lin.predict(test_X)
# print("预测值为:\n", y_predict)
# print("模型中的系数为:\n", lin.coef_)
# print("模型中的偏置为:\n", lin.intercept_)
# 误差
print('The accuracy of the Liner Regression is: ',metrics.mean_squared_error(predict,test_Y))
def Gradient_descent(train_X,train_Y,test_X,test_Y):
# 5:线性回归(梯度下降法)
# 加载模型
lin = SGDRegressor(max_iter=1000)
lin.fit(train_X, train_Y)
# 6:模型评估
# 进行预测
predict = lin.predict(test_X)
# print("预测值为:\n", y_predict)
# print("模型中的系数为:\n", lin.coef_)
# print("模型中的偏置为:\n", lin.intercept_)
# 误差
print('The accuracy of the Gradient descent Regression is: ',metrics.mean_squared_error(predict,test_Y))
def main():
# 1:获取数据
# 载入波士顿房屋的数据集
data = np.genfromtxt('housing1.txt')
df = pd.DataFrame(data,
columns=['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B',
'LSTAT', 'MEDV'])
df.to_csv('housing1.csv')
print("Boston housing dataset has {} data points with {} variables each.".format(*data.shape))
# 查看数据描述
# print(df.describe())
# print(df.head())
# 数据代表特征
# CRIM:城镇人均犯罪率。
# ZN:住宅用地超过 25000 sq.ft. 的比例。
# INDUS:城镇非零售商用土地的比例。
# CHAS:查理斯河空变量(如果边界是河流,则为1;否则为0)。
# NOX:一氧化氮浓度。
# RM:住宅平均房间数。
# AGE:1940 年之前建成的自用房屋比例。
# DIS:到波士顿五个中心区域的加权距离。
# RAD:辐射性公路的接近指数。
# TAX:每 10000 美元的全值财产税率。
# PTRATIO:城镇师生比例。
# B:1000(Bk-0.63)^ 2,其中 Bk 指代城镇中黑人的比例。
# LSTAT:人口中地位低下者的比例。
# MEDV:自住房的平均房价,以千美元计。
# 2:寻找因子
# 寻找对房价影响大的因子
# 计算每一个特征对造假的相关系数 协方差 并将大于0.5的数据集输出
corr = df.corr()['MEDV']
print(corr[abs(corr) > 0.5].sort_values())
# 先不展示
# 观察得到LSTAT、PTRATIO、RM对数据影响大
# LSTAT和MEDV的关系散点图
plt.scatter(df['LSTAT'], df['MEDV'])
plt.show()
# RM和MEDV的关系散点图
plt.scatter(df['RM'], df['MEDV'])
plt.show()
# PTRATIO和MEDV的关系散点图
plt.scatter(df['PTRATIO'], df['MEDV'])
plt.show()
# 可以看出有前两组数据均与造价有较强的线性关系 第三组没那么明显
# 由于得到的数据较为完全所以不需要缺省值处理
# 于是选取这三个为主要特征,其余值可以移除
df = df[['LSTAT', 'PTRATIO', 'RM', 'MEDV']] # 选取特征值,减去其他无关信息
# 3:数据集划分
X = df.drop(['MEDV'], axis=1) # 划分样本特征及
X.info()
y = np.array(df['MEDV']) # 样本标签
train_X, test_X, train_Y, test_Y = train_test_split(X, y, test_size=0.3, random_state=0) # 分割训练集和测试集
# 4:特征工程-标准化
data = StandardScaler()
train_X = data.fit_transform(train_X)
test_X = data.fit_transform(test_X)
# 正规方程
liner(train_X, train_Y, test_X, test_Y)
# 梯度下降法
Gradient_descent(train_X, train_Y, test_X, test_Y)
if __name__=='__main__':
main()
2):鸢尾花分类:
# -*- coding: utf-8 -*-
#开发团队:机器人学院
#开发人员:蟹老板
#开发时间:2020/10/17:58
#文件名:flower
#开发工具:PyCharm
import pandas as pd#导入数据文件
import numpy as np#科学计算计算库
import seaborn as sns
import matplotlib.pyplot as plt#数据可视化库
import warnings
import pandas_profiling as ppf#eda
from sklearn import metrics
from sklearn.preprocessing import LabelEncoder#标签编码
from sklearn.preprocessing import MinMaxScaler#归一化
from sklearn.model_selection import train_test_split#数据集的划分
from sklearn.linear_model import LinearRegression#算法
from sklearn.metrics import mean_absolute_error#评估函数
from sklearn.preprocessing import StandardScaler#标准化
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfVectorizer
from matplotlib.font_manager import FontProperties
def main():
# 1:获取数据
# 载入鸢尾花的数据集
df = pd.read_csv('iris.csv')
# 2:寻找相关因子
# sepal_len:萼长
# sepal_width:萼宽
# petal_len:瓣长
# petal_width:瓣宽
# iris - setosa:山鸢尾
# iris - versicolour:变色鸢尾
# iris - virginica:维吉尼亚鸢
antV = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
# g = sns.lmplot(data=df, x='sepal_width', y='sepal_len', palette=antV, hue='class')
# g = sns.lmplot(data=df, x='petal_len', y='petal_width', palette=antV, hue='class')
# plt.show()
fig = plt.gcf()
fig.set_size_inches(12, 8)
fig = sns.heatmap(df.corr(), annot=True, cmap='GnBu', linewidths=1, linecolor='k', square=True, mask=False, vmin=-1,
vmax=1, cbar_kws={"orientation": "vertical"}, cbar=True)
plt.show()
# 暂时不展示
# 观察得到花萼的宽度和长度不相关,而花瓣的宽度和长度则高度相关
# 3:添加标签
X = df[['sepal_len', 'sepal_width', 'petal_len', 'petal_width']]
y = df['class']
encoder = LabelEncoder()
y = encoder.fit_transform(y)
# 不同花的标签,此处:0为iris-setosa 1为iris-versicolour 2为:iris-virginica
# print(y)
# 4:测试集与训练集
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=90)
# 同一算法模型在不同的训练集和测试集的会得到不同的准确率导致无法调参。
# sklearn 中可以通过添加random_state,通过固定random_state的值,每次可以分割得到同样训练集和测试集。
# 因此random_state参数主要是为了保证每次都分割一样的训练集和测试机,大小可以是任意一个整数,在调参缓解,只要保证其值一致即可。
# # 输出元组,查看是否分类完成
# print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
# 5:特征化工程-标准化
data = StandardScaler()
train_X = data.fit_transform(train_X)
test_X = data.fit_transform(test_X)
# 6:对数几率回归
model = LogisticRegression()
model.fit(train_X, train_y)
prediction = model.predict(test_X)
print('The accuracy of the Logistic Regression is: {0}'.format(metrics.accuracy_score(prediction, test_y)))
if __name__=='__main__':
main()
五、 实验结果
1):波士顿房价预测:
2):鸢尾花分类:
六、 结论
波士顿房价那道题有点像之前做股票预测的题目,当时团队用的就是线性回归,不过是用matlab写的,也是按照上面的步骤一步一步处理数据,提取出特征系数大的部分进行回归,所以波士顿房价较为好写,鸢尾花则是之前没尝试过的,在逻辑回归的时候鸢尾花一开始的训练得到的模型错误率较高,无论怎么调试测试训练比正确率都无法达到90%以上,后来调整了Sklearn中的random_state才使得模型正确率高于90,也查了以下原因,原来是同一个算法模型在不同的训练集中会得到不同的调准率导致的问题,调整random_state后能保证每次分割一样的训练集和测试集,这样在固定的训练集中得到的模型就很稳定了。同时在对数几率回归的时候调整增大训练模型的正则化提高泛化能力也能得到较好的训练模型。