这里写目录标题
一、线性模型构建
1.初始化模型
import numpy as np
from utils.features import prepare_for_training#导入预处理
class LinearRegression:
def __init__(self,data,lables,olynomial_degree=0, sinusoid_degree=0, normalize_data=True):
"""
1.数据预处理操作
2,数据的特征参数
3.初始化参数矩阵
"""
data_processed,features_mean,features_deviation=prepare_for_training(data,polynomial_degree=0, sinusoid_degree=0, normalize_data=True)#预处理操作
self.data=data_processed
self.lables=lables
self.features_mean=features_mean
self.features_deviation=features_deviation
self.olynomial_degree=olynomial_degree
self.sinusoid_degree=sinusoid_degree
self.olynomial_degree=normalize_data
num_features=self.data.shape[1]
self.theta=np.zeros((num_features,1))
2.模型训练函数
def train(self,alpha,num_iterations=500):
"""
训练模块,执行梯度下降
:param alpha:学习率
:param num_iterations:迭代次数
:return:
"""
const_history=self.gradient_descent(alpha,num_iterations)#迭代损失
return self.theta,const_history
def gradient_descent(self,alpha,num_iterations=500):
"""
时刻i迭代模块
:param alpha:
:param num_iterations:
:return:
"""
cost_history=[]
for _ in range(num_iterations):
self.gradient_step(alpha)
cost_history.append(self.cost_function(self.data,self.lables))
return cost_history
def gradient_step(self,alpha):
"""
梯度下降参数更新方法,梯度下降,注意是矩阵运算
:return:
"""
num_examples=self.data.shape[0]
predicton=LinearnGegress.hypothesis(self.data,self.theta)
delta=predicton-self.lables
theta=self.theta
theta=theta-alpha*(1/num_examples)*(np.dot(delta.T,self.data))
self.theta=theta
@staticmethod
def hypothesis(data,theta):
"""
预测函数
:param data:
:param theta:
:return:
"""
predictions=np.dot(data,theta)#,np.dot用于计算两个数组中相应元素的乘积之和。
return predictions
def get_cost(self,data,lables):
"""
得到当前的损失
:param data:
:param lables:
:return:
"""
data_processed=prepare_for_training(data,
self.polynomial_degree,
self.sinusoid_degree,
self.normalize_data,
)[0]
return self.cost_function(data_processed,lables)
def cost_function(self,data,lables):
"""
计算损失方法
:param data:
:param lable:
:return:
"""
num_examples = data.shape[0]
delta = LinearnGegress.hypothesis(self.data, self.theta) - lables
#上一篇文章梯度损失的计算公式
cost = (1 / 2) * np.dot(delta.T, delta) / num_examples
return cost[0][0]
3.预测模型
def predict(self, data):
"""
用训练的参数模型,与预测得到回归值结果
"""
data_processed = prepare_for_training(data,
self.polynomial_degree,
self.sinusoid_degree,
self.normalize_data
)[0]
predictions = LinearRegression.hypothesis(data_processed, self.theta)
return predictions
二、单特征变量的模型
目标:通过GDP预测幸福度分值
1.加载数据集
本次模型的数据是一份不同国家根据不同特征,给出不同幸福度分数的数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
from line import LinearRegression
data=pd.read_csv('./data/world-happiness-report-2017.csv')
2.得到训练与测试数据
#得到训练和测试数据
train_data=data.sample(frac=0.8)
text_data=data.drop(train_data.index)
input_param_name='Economy..GDP.per.Capita.'
out_param_name='Happiness.Score'
x_train=train_data[[input_param_name]].values
y_train=train_data[[out_param_name]].values
x_test=text_data[input_param_name].values
y_test=text_data[out_param_name].values
一般训练数据和测试数据7:3或者8:2
3.绘制散点图观察数据集分布
plt.scatter(x_train,y_train,label='Train data')
plt.scatter(x_test,y_test,label='test data')
plt.xlabel(input_param_name)
plt.ylabel(out_param_name)
plt.title("countr happinse")
plt.legend()
plt.show()
很明显的看到呈一个线性关系,我们对数据据尽心训练
4.训练
我们设置迭代次数为500,学习率为0.01
num_iterations=500
learning_rate=0.01#学习率
linean_regress=LinearRegression(x_train,y_train)
(theta,const_history)=linean_regress.train(learning_rate,num_iterations)
运行得到训练损失结果,打印一下开始损失和结束时候损失
相比较于刚开始的时候,损失最后变小的很多,我们希望损失越小越好
对损失数据作图,会发现其损失逐步、下降,并趋于稳定
5.预测结果
随机生成100个数据,得到预测结果
predictions_num=100
x_predictions=np.linspace(x_train.min(),x_train.max(),num=predictions_num).reshape(predictions_num,1)#等间隔数据,
# print(x_predictions)
y_predictions=linean_regress.predict(x_predictions)
用散点图显示预测结果
plt.scatter(x_train,y_train,label='Train data')
plt.scatter(x_test,y_test,label='test data')
plt.plot(x_predictions,y_predictions,'r',label="Preddiction")
plt.xlabel(input_param_name)
plt.ylabel(out_param_name)
plt.title("happinses预测")
plt.legend()
plt.show()
可以发现预测结果基本在拟合线上,幸福度与GPD存在一个线性关系,GDP越高,幸福分数约高。但这个只是一个特征,我们下面会采用两个特征进行训练
三、多特征变量的模型
目标:通过GDP和自由度预测幸福度
这里我们采用plotly进行绘图
pip insyall plotly
是一个相当精美的可视化作图,感兴趣可以去了解一下
1 .加载数据
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('TkAgg')
import plotly.offline
import matplotlib.pyplot as plt
import plotly.graph_objs as go
plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
from line import LinearnGegress,LinearRegression
data=pd.read_csv('./data/world-happiness-report-2017.csv')
2.得到训练数据和测试数据
- 和上面的差不多同样操作
train_data=data.sample(frac=0.8)
text_data=data.drop(train_data.index)
input_param_name1='Economy..GDP.per.Capita.'
input_param_name2="Freedom"
input_param_name3='Health..Life.Expectancy.'
out_param_name='Happiness.Score'
x_train=train_data[[input_param_name1,input_param_name2]].values
y_train=train_data[[out_param_name]].values
x_test=text_data[[input_param_name1,input_param_name2]].values
y_test=text_data[out_param_name].values
3.绘制动态散点图
polt_traning_trace=go.Scatter3d(
x=x_train[:,0].flatten(),#这个代码段假设x_train是一个NumPy数组,它至少有两个维度,第一维度的长度大于等于1,第二维度的长度可以是任意值。具体而言,x_train[:, 0]表示取x_train的第二维中索引为0的那一列,也就是所有行的第一个元素。然后,这个一维数组被调用flatten()方法,将其展平成一个一维数组
y=x_train[:,1].flatten(),
z=y_train.flatten(),
name='traning set',
mode='markers',
marker={
'size':9,
'opacity':0.9,
'line':{
'color':'rgb(255,255,255)',
'width':1
}
}
)
polt_test_trace = go.Scatter3d(
x=x_test[:, 0].flatten(),
# 这个代码段假设x_train是一个NumPy数组,它至少有两个维度,第一维度的长度大于等于1,第二维度的长度可以是任意值。具体而言,x_train[:, 0]表示取x_train的第二维中索引为0的那一列,也就是所有行的第一个元素。然后,这个一维数组被调用flatten()方法,将其展平成一个一维数组
y=x_test[:, 1].flatten(),
z=y_test.flatten(),
name='test set',
mode='markers',
marker={
'size': 9,
'opacity': 1,
'line': {
'color': 'rgb(255,255,255)',
'width': 1
}
}
)
#布局
plot_layout=go.Layout(
title='data set',
scene={
'xaxis':{'title':input_param_name1},
'yaxis':{'title':input_param_name2},
'zaxis':{'title':out_param_name}
},margin={
'l':0,'r':0,'b':0,'t':0
}
)
plot_data=[polt_traning_trace,polt_test_trace]
plot_figure=go.Figure(data=plot_data,layout=plot_layout)
plotly.offline.iplot(plot_figure)#弹出网页iplot嵌入展示
- 蓝色点是训练数据,红色点是测试数据
- 可以从不同维度考虑数据变化情况
- 总体上看GPD和自由度越高,幸福度越高
4.数据训练
num_iterations=500
learnin_rate=0.01
liner_regress=LinearRegression(x_train,y_train)
(theta,const_history)=liner_regress.train(alpha=learnin_rate,num_iterations=num_iterations)
print('开始时候损失:',const_history[0])
print('训练后的损失',const_history[-1])
与单个特征相比,我们发现两个特征值训练后损失值越小,所以预测结果越具有可信度
绘制损失下降曲线
plt.plot(range(1,num_iterations+1),const_history)
plt.xlabel('Inter')
plt.ylabel('cost')
plt.title('损失梯度')
plt.show()
5.预测结果
对于多维度数据的处理上,可以用np.hstack()函数将两个或者多个矩阵或者数组构建成一个新的矩阵或者数组
我们生成100个范围内数据,分别构造shape为(100,1)的矩阵,再用np.hstack()构造成(100,2)的矩阵
predictions_num=100
x_min = x_train[:, 0].min()
x_max = x_train[:, 0].max()
y_min = x_train[:, 1].min()
y_max = x_train[:, 1].max()
x_axis=np.linspace(x_min,x_max,predictions_num)
y_axis=np.linspace(y_min,y_max,predictions_num)
x_predictions = np.zeros((predictions_num * predictions_num, 1))
y_predictions = np.zeros((predictions_num * predictions_num, 1))
x_y_inex=0
for x_index,a_value in enumerate(x_axis):
for y_index,y_value in enumerate(y_axis):
x_predictions[x_y_inex]=a_value
y_predictions[x_y_inex]=y_value
x_y_inex+=1
"""
np.hstack()是NumPy库中的一个函数,用于将两个或多个数组沿着水平方向(列方向)合并成一个新的数组。
"""
z_predictions=liner_regress.predict(np.hstack((x_predictions,y_predictions)))
获得预测结果后,我们绘制拟合动态散点图进行观察
plot_predictions_trace = go.Scatter3d(
x=x_predictions.flatten(),
y=y_predictions.flatten(),
z=z_predictions.flatten(),
name='Prediction Plane',
mode='markers',
marker={
'size': 1,
},
opacity=0.8,
surfaceaxis=2,
)
plot_data = [polt_traning_trace,polt_test_trace, plot_predictions_trace]
plot_figure = go.Figure(data=plot_data, layout=plot_layout)
plotly.offline.iplot(plot_figure)
通过观察我们的拟合切面,我们的预测结果基本与实际结果相同
总结
到这里大概结束了,我们比较单个特征向量和多个特征向量损失值对比,特征值数量越多、,损失值越小,对预测结果的影响越大,预测结果也就越精确。
如果上面有问题的地方欢迎指正
希望大家多多支持,一起努力学习,后续慢慢分享更多新奇有趣的东西