【机器学习】线性回归2-基本实现(单个特征和多个特征案例比较)

一、线性模型构建

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)

在这里插入图片描述
通过观察我们的拟合切面,我们的预测结果基本与实际结果相同

总结

到这里大概结束了,我们比较单个特征向量和多个特征向量损失值对比,特征值数量越多、,损失值越小,对预测结果的影响越大,预测结果也就越精确。
如果上面有问题的地方欢迎指正
希望大家多多支持,一起努力学习,后续慢慢分享更多新奇有趣的东西

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泪懿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值