《HCIA-AI》实验1 回归算法的实现

《HCIA-AI》实验报告

  1. 实验名称:
    回归算法的实现

  2. 实验目的:
     了解机器学习算法的使用流程和功能。
     掌握通过Python基础工具包numpy等从零实现线性回归、梯度下降等算法
     掌握一些关于机器学习库sklearn的基本用法和一些基本的数据处理方法。

  3. 实验内容
     实验一线性回归,通过Python工具包scikit-learn实现简单线性回归算法的使用。
     实验二为线性回归拓展实验,通过Python基础工具包numpy等从零实现线性回归、梯度下降等算法,加深理解。
     实验三所使用的数据集样本量较小,数据来自于scikit-learn自带的开源波士顿房价数据。波士顿房价预测项目是一个回归模型,通过该项目的学习可以学会一些关于机器学习库sklearn的基本用法和一些基本的数据处理方法。

  4. 实验程序和测试结果:
    4.1线性回归
    本实验包主要是回归算法的使用,通过从零开始构建线性回归算法和基于scikit-learn调用实现,帮助您更加了解机器学习算法的使用流程和功能。
    步骤 1 引入相关依赖的包
    from sklearn.linear_model import LinearRegression#导入线性回归模型
    import matplotlib.pyplot as plt#绘图库
    import numpy as np
    步骤 2 构建房价数据集并可视化
    x = np.array([121, 125, 131, 141, 152, 161]).reshape(-1,1)#x是房屋面积,作为特征
    y = np.array([300, 350, 425, 405,496,517])#y是房屋的价格
    plt.scatter(x,y)
    plt.xlabel(“area”)#添加横坐标面积
    plt.ylabel(“price”)#添加纵坐标价格
    plt.show()
    输出:

步骤 3 模型训练
lr = LinearRegression()#将线性回归模型封装为对象
lr.fit(x,y)#模型在数据上训练
步骤 4 模型的可视化
w = lr.coef_#存储模型的斜率
b = lr.intercept_#存储模型的截距
print(‘斜率:’,w)
print(‘截距:’,b)
输出: 斜率: [4.98467124]
截距: -274.87696651875774

plt.scatter(x,y)
plt.xlabel(“area”)#添加横坐标面积
plt.ylabel(“price”)#添加纵坐标价格
plt.plot([x[0],x[-1]],[x[0]*w+b,x[-1]*w+b])
输出:

步骤 5 模型预测
testX = np.array([[130]])#测试样本,面积为130
lr.predict(testX)
输出:array([373.13029447])

4.2线性回归算法实现(扩展)
在“线性回归算法实现”部分,使用的数据集为lr2_data.txt,主要是自行模拟的房屋面积与房屋价格数据。该数据集可在实验环境搭建中获取。
步骤 1 导入依赖
import numpy as np
import matplotlib.pyplot as plt
步骤 2 定义函数,计算梯度
def generate_gradient(X, theta, y):
sample_count = X.shape[0]
# 计算梯度,采用矩阵计算 1/m ∑(((h(xi)-yi)) x_j^i)
return (1./sample_count)*X.T.dot(X.dot(theta)-y)
步骤 3 定义函数,用于读取数据集
def get_training_data(file_path):
orig_data = np.loadtxt(file_path,skiprows=1) #忽略第一行的标题
cols = orig_data.shape[1]
return (orig_data, orig_data[:, :cols - 1], orig_data[:, cols-1:])
步骤 4 定义函数,初始化参数

初始化θ数组

def init_theta(feature_count):
return np.ones(feature_count).reshape(feature_count, 1)
步骤 5 定义函数,实现梯度下降法
def gradient_descending(X, y, theta, alpha):
Jthetas= [] # 记录代价函数J(θ)的变化趋势,验证梯度下降是否运行正确
# 计算损失函数,等于真实值与预测值差的平方。(yi-h(xi))^2
Jtheta = (X.dot(theta)-y).T.dot(X.dot(theta)-y)
index = 0
gradient = generate_gradient(X, theta, y) #计算梯度
while not np.all(np.absolute(gradient) <= 1e-5): #梯度小于0.00001时计算结束
theta = theta - alpha * gradient
gradient = generate_gradient(X, theta, y) #计算新梯度
# 计算损失函数,等于真实值与预测值差的平方(yi-h(xi))^2
Jtheta = (X.dot(theta)-y).T.dot(X.dot(theta)-y)
if (index+1) % 10 == 0:
Jthetas.append((index, Jtheta[0])) #每10次计算记录一次结果
index += 1
return theta,Jthetas
步骤 6 定义函数,可视化损失函数变化曲线
#展示损失函数变化曲线图
def showJTheta(diff_value):
p_x = []
p_y = []
for (index, sum) in diff_value:
p_x.append(index)
p_y.append(sum)
plt.plot(p_x, p_y, color=‘b’)
plt.xlabel(‘steps’)
plt.ylabel(‘loss funtion’)
plt.title(‘step - loss function curve’)
plt.show()
步骤 7 定义函数,可视化数据点及拟合的曲线
#展示实际数据点以及拟合出的曲线图
def showlinercurve(theta, sample_training_set):
x, y = sample_training_set[:, 1], sample_training_set[:, 2]
z = theta[0] + theta[1] * x
plt.scatter(x, y, color=‘b’, marker=‘x’,label=“sample data”)
plt.plot(x, z, ‘r’, color=“r”,label=“regression curve”)
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.title(‘liner regression curve’)
plt.legend()
plt.show()
步骤 8 最终展示

读取数据集

training_data_include_y, training_x, y = get_training_data(“./ML/02/lr2_data.txt”)

获取数据集数量及特征数

sample_count, feature_count = training_x.shape

定义学习步长α

alpha = 0.01

初始化Ɵ

theta = init_theta(feature_count)

获取最终的参数Ɵ及代价

result_theta,Jthetas = gradient_descending(training_x, y, theta, alpha)

打印参数

print(“w:{}”.format(result_theta[0][0]),“b:{}”.format(result_theta[1][0]))
showJTheta(Jthetas)
showlinercurve(result_theta, training_data_include_y)
输出:
w:3.0076279423997594 b:1.668677412281192

4.3房价预测(回归算法的应用)
该案例主要内容是进行波士顿数据集,共有13个特征,总共506条数据,每条数据包含房屋以及房屋周围的详细信息。其中包含城镇犯罪率,一氧化氮浓度,住宅平均房间数,到中心区域的加权距离以及自住房平均房价等等。具体如下:
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:人口中地位低下者的比例。
target:自住房的平均房价,以千美元计。

框架:Sklearn,框架一方面提供波士顿房价数据,并且提供用于分割数据集,标准化,评价函数,另一方面集成了各类常规机器学习算法;另外我们使用了XGboost,是集成算法中GBDT的优化版本。
步骤 1 引入相关依赖的包

防止不必要的警告

import warnings
warnings.filterwarnings(“ignore”)

引入数据科学基础包

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import scipy.stats as st
import seaborn as sns

设置属性防止画图中文乱码

mpl.rcParams[‘font.sans-serif’] = [u’SimHei’]
mpl.rcParams[‘axes.unicode_minus’] = False

引入机器学习,预处理,模型选择,评估指标

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import r2_score

引入本次所使用的波士顿数据集(boston)

from sklearn.datasets import load_boston

引入算法

from sklearn.linear_model import RidgeCV, LassoCV, LinearRegression, ElasticNet
#从线性模型库里导出我们需要的模型
from sklearn.svm import SVR
#对比SVC,是svm的回归形式

集成算法

from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from xgboost import XGBRegressor
步骤 2 载入数据集, 查看数据属性,可视化

载入波士顿房价数据集

boston = load_boston()

x是特征,y是标签

x = boston.data #提示:数据集名字
y = boston.target

查看相关属性

print(‘特征的列名’)
print(boston.feature_names)
print(“样本数据量:%d, 特征个数:%d” % x.shape)
print(“target样本数据量:%d” % y.shape[0])
输出:
特征的列名
[‘CRIM’ ‘ZN’ ‘INDUS’ ‘CHAS’ ‘NOX’ ‘RM’ ‘AGE’ ‘DIS’ ‘RAD’ ‘TAX’ ‘PTRATIO’
‘B’ ‘LSTAT’]
样本数据量:506, 特征个数:13
target样本数据量:506

转化为dataframe形式

x = pd.DataFrame(boston.data, columns=boston.feature_names)# 提示:纵坐标是波士顿数据的特征名字
x.head()

输出:

对标签的分布进行可视化

sns.distplot(tuple(y), kde=False, fit=st.norm) # 提示:标签的可视化
输出:

步骤 3 分割数据集,并对数据集进行预处理

数据分割

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=28)

标准化数据集

ss = StandardScaler()
x_train = ss.fit_transform(x_train)#提示:对训练集的特征进行标准化
x_test = ss.transform(x_test )#提示:对测试集集进行转换
x_train[0:100]
输出:
array([[-0.35703125, -0.49503678, -0.15692398, …, -0.01188637,
0.42050162, -0.29153411],
[-0.39135992, -0.49503678, -0.02431196, …, 0.35398749,
0.37314392, -0.97290358],
[ 0.5001037 , -0.49503678, 1.03804143, …, 0.81132983,
0.4391143 , 1.18523567],
…,
[-0.34697089, -0.49503678, -0.15692398, …, -0.01188637,
0.4391143 , -1.11086682],
[-0.39762221, 2.80452783, -0.87827504, …, 0.35398749,
0.4391143 , -1.28120919],
[-0.38331362, 0.41234349, -0.74566303, …, 0.30825326,
0.19472652, -0.40978832]])
步骤 4 利用各类回归模型,对数据集进行建模

模型的名字

names = [‘LinerRegression’,#提示:线性回归
‘Ridge’,
‘Lasso’, #提示:加正则项的回归模型
‘Random Forrest’,
‘GBDT’,
‘Support Vector Regression’, #提示:支持向量机全称
‘ElasticNet’,
‘XgBoost’]

定义模型

cv在这里是交叉验证的思想

models = [LinearRegression(),
RidgeCV(alphas=(0.001,0.1,1),cv=3),
LassoCV(alphas=(0.001,0.1,1),cv=5),
RandomForestRegressor(n_estimators=10),
GradientBoostingRegressor(n_estimators=30),
SVR(),
ElasticNet(alpha=0.001,max_iter=10000),
XGBRegressor()]

定义R2评分的函数

def R2(model,x_train, x_test, y_train, y_test):

model_fitted = model.fit(x_train ,y_train)
y_pred = model_fitted.predict(x_test)
score = r2_score(y_test, y_pred)
return score

遍历所有模型进行评分

for name,model in zip(names,models):
score = R2(model,x_train, ????, y_train, y_test)
print(“{}: {:.6f}, {:.4f}”.format(name,score.mean(),score.std()))

输出:
LinerRegression: 0.564115, 0.0000
Ridge: 0.563673, 0.0000
Lasso: 0.564049, 0.0000
Random Forrest: 0.702915, 0.0000
GBDT: 0.722048, 0.0000
Support Vector Regression: 0.517260, 0.0000
ElasticNet: 0.563992, 0.0000
XgBoost: 0.771839, 0.0000
步骤 5 利用网格搜索对超参数进行调节

模型构建

‘’’
‘kernel’: 核函数
‘C’: SVR的正则化因子,
‘gamma’: ‘rbf’, ‘poly’ and ‘sigmoid’核函数的系数,影响模型性能
‘’’
parameters = {
‘kernel’: [‘linear’, ‘rbf’],
‘C’: [0.1, 0.5,0.9,1,5],
‘gamma’: [0.001,0.01,0.1,1]
}

使用网格搜索,以及交叉验证

model = GridSearchCV(SVR(), param_grid=parameters, cv=3)
model.fit(x_train, y_train)

获取最优参数

print (“最优参数列表:”, model.best_params_)
print (“最优模型:”, model.best_estimator_)
print (“最优R2值:”, model.best_score_)

输出:
最优参数列表: {‘C’: 5, ‘gamma’: 0.1, ‘kernel’: ‘rbf’}
最优模型: SVR(C=5, gamma=0.1)
最优R2值: 0.7965173649188232

可视化

ln_x_test = range(len(x_test))
y_predict = model.predict(x_test)#提示:房价预测值

设置画布

plt.figure(figsize=(16,8), facecolor=‘w’)

用红实线画图

plt.plot(ln_x_test, y_test, ‘r-’, lw=2, label=u’真实值’)

用绿实线画图

plt.plot(ln_x_test, y_predict, ‘g-’, lw = 3, label=u’SVR算法估计值, R 2 R^2 R2=%.3f’ % (model.best_score_))

图形显示

plt.legend(loc = ‘upper left’)
plt.grid(True)
plt.title(u"波士顿房屋价格预测(SVM)")
plt.xlim(0, 101)
plt.show()

输出:

  1. 实验总结:
    实验一首先引入了线性回归问题,通过使用Python工具包scikit-learn实现了线性回归算法。线性回归是一种用于预测连续数值输出的监督学习算法。在这个实验中,我了解了如何准备数据、训练线性回归模型并评估其性能。这为进一步探索回归算法奠定了基础。
    实验二是线性回归的深入学习,放弃了使用高级库,如scikit-learn,而是使用Python基础工具包如numpy等,从零开始实现了线性回归和梯度下降算法。通过手动实现这些算法,我深入理解了线性回归的数学原理和梯度下降的优化过程。这增强了对回归算法的理解。
    实验三使用来自scikit-learn的波士顿房价数据集,进行了一个回归项目。这个项目旨在预测波士顿地区的房价。通过这个实验,我学习了如何处理包含真实数据的数据集,如何选择特征、训练模型和评估模型性能。这个实验还向我介绍了机器学习库scikit-learn的更多用法,以及一些基本的数据处理技巧。
    通过本次实验,我深入了解了回归算法的原理和应用。从使用高级库scikit-learn解决回归问题到手动实现线性回归和梯度下降算法,提高了我对算法内部工作原理的理解。此外,通过波士顿房价预测项目,我学会了如何应用机器学习工具来解决实际问题,并掌握了一些关键的数据处理技能。这些知识和技能将为进一步研究和应用机器学习提供坚实的基础。

源码

  • 15
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值