机器学习 --- 线性回归

简介: 机器学习 --- 线性回归

今天我们来开始入门机器学习,简单介绍一下线性回归模型


image.png

image.png

这几天一直有人问我拟合数据的问题,还有预测模型等问题,所以就想来开始一下这个我一直在准备的专栏--机器学习


线性回归是线性模型,例如,假设输入变量(x)和单个输出变量(y)之间存在线性关系的模型。


更具体地,可以根据输入变量(x)的线性组合来计算输出变量(y)。

所以我们希望算法学习假设的参数,以便能够建立方程进行预测 该方程以特征和参数作为输入,并预测其值作为输出。


要弄明白线性回归就要从背后的数学原理开始讲起


1.数学原理


从初中我们就开始接触方程,一开始是简单的y=kx+b,到后来越来越复杂。初中时有没有碰到这样一类问题呢?题目给出了一大堆商场每天的销售数量和利润让你从中得到函数去估计未来某个销售数量的利润。又或者是大学做大物实验画图的时候,老师总会说描点画线的要求是画一条直线,使每个点均匀的分布在这条直线的两边,且到直线的距离最短。那什么样的直线才是最适合的来预测这些数据特征(属性的)曲线呢?这就需要讲讲线性模型了。


首先是最基本的表达形式

image.png


其中X是自变量的各个属性,θ是参数

image.png

 然后就是最重要的就是怎么才能使参数最优,也就是损失率降到最小。 这就需要谈谈损失率和损失函数了,在这里我们选择的损失函数是均方误差


image.png


有了损失函数那我们还要想办法使误差最小。怎么求一个函数的最小值呢,就需要另外一个很重要的算法,叫梯度下降。

梯度下降:梯度下降是一种用来寻找最小损失函数的迭代优化算法。查找局部最小损失函数使用梯度下降算法,以当前点函数的负梯度的一定比例的步数进行逼近。

下图表示我们从函数高点出发找到局部最小值的步骤。


image.png


函数的负梯度理解起来就是损失函数求导的负方向


image.png


然后每次更新的步长就是我们说的学习率,这样就可以通过迭代求出损失函数的最小值了,从而就得到了最优参数解。


这里有个问题,就是梯度下降容易陷入局部最小值而不是全局最小值,这就涉及到随机梯度下降等优化算法了,而且还有过拟合从而失去泛化能力


代码实现部分


首先是最基本的线性拟合方法

image.png


就拿帮别人做的个作业来举例子


import pandas as pd
import numpy as np
import math
from scipy.optimize import leastsq
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False 
#导入数据
#平方英尺
x=[150,200,250,300,350,400,600]
#房价
y=[6450,7450,8450,9450,11450,15450,18450]
#训练集和测试集
x_train=np.array(x[0:5])
y_train=np.array(y[0:5])
x_test=np.array(x[5:7])
y_test=np.array(y[5:7])
def fun(p,x):
    k,b=p
    return k*x+b
# 误差函数
def error(p,x,y):
    return np.sqrt((fun(p,x)-y)**2)
#只用前五个数据进行预测
p0=[100,2]
para=leastsq(error,p0,args=(x_train,y_train))
k,b=para[0]
print("拟合的方程为:y={}x+{}".format(k,b))
#绘制拟合直线
plt.figure(figsize=(8,6))
plt.scatter(x,y,color="red",label="Point",linewidth=3)
X=np.linspace(100,700,1000)
Y=k*X+b
plt.plot(X,Y,color="orange",label="拟合直线",linewidth=2)
plt.xlabel('平方英尺')
plt.ylabel('房价')
plt.legend()
plt.show()
复制代码


image.png


#画误差图
err1=[]
for i in range(len(x_train)):
    err1.append(k*x_train[i]+b-y_train[i])
plt.figure(figsize=(10, 7))
plt.title('误差图')
plt.plot(x_train,err1,'r',label='error', linewidth=3)
plt.xlabel('x')
plt.ylabel('error')
plt.show()

image.png


然后自己仿着sklearn的线性模型写段代码,构建属于自己的线性模型训练器这里用到的数据集是2017年世界幸福指数和GPD的数据,可以在kaggle上下载,链接如下www.kaggle.com/unsdsn/worl…然后我们通过GDP指数去预测人们的幸福指数


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#导入数据
data = pd.read_csv('2017.csv')
#查看数据集
data.info()
data.head(10)
复制代码


image.png


image.png

#画出每一个属性的分布直方图
histohrams = data.hist(grid=False, figsize=(10, 10))

image.png

#切分训练集和测试集
#分出80%训练集,20%测试集
#这里没有用到sklearn的train_test_split
train_data = data.sample(frac=0.8)
test_data = data.drop(train_data.index)
x_train = train_data[['Economy..GDP.per.Capita.']].values
y_train = train_data[['Happiness.Score']].values
x_test = test_data[['Economy..GDP.per.Capita.']].values
y_test = test_data[['Happiness.Score']].values
#绘制出散点图
plt.scatter(x_train, y_train, label='Training Dataset')
plt.scatter(x_test, y_test, label='Test Dataset')
plt.xlabel('Economy..GDP.per.Capita.')
plt.ylabel('Happiness.Score')
plt.title('Countries Happines')
plt.legend()
plt.show()

image.png

然后就是一些正则化防止过拟合的函数和归一化的函数了,这里就不贴了


#开始自己动手写一个线性回归模型
class self_LinearRegression:
    def __init__(self, data, labels, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):
        (data_processed,features_mean,features_deviation)=prepare_for_training(data, polynomial_degree, sinusoid_degree, normalize_data)
        self.data = data_processed
        self.labels = labels
        self.features_mean = features_mean
        self.features_deviation = features_deviation
        self.polynomial_degree = polynomial_degree
        self.sinusoid_degree = sinusoid_degree
        self.normalize_data = normalize_data
        num_features = self.data.shape[1]
        self.theta = np.zeros((num_features, 1))
    #训练
    def train(self, alpha, lambda_param=0, num_iterations=500):
        cost_history = self.gradient_descent(alpha, lambda_param, num_iterations)
        return self.theta, cost_history
    #梯度下降
    def gradient_descent(self, alpha, lambda_param, num_iterations):
        cost_history = []
        for _ in range(num_iterations):
            self.gradient_step(alpha, lambda_param)
            cost_history.append(self.cost_function(self.data, self.labels, lambda_param))
        return cost_history
    def gradient_step(self, alpha, lambda_param):
        num_examples = self.data.shape[0]
        predictions = self_LinearRegression.hypothesis(self.data, self.theta)
        delta = predictions - self.labels
        reg_param = 1 - alpha * lambda_param / num_examples
        theta = self.theta
        theta = theta * reg_param - alpha * (1 / num_examples) * (delta.T @ self.data).T
        theta[0] = theta[0] - alpha * (1 / num_examples) * (self.data[:, 0].T @ delta).T
        self.theta = theta
    #损失率
    def get_cost(self, data, labels, lambda_param):
        data_processed = prepare_for_training(
            data,
            self.polynomial_degree,
            self.sinusoid_degree,
            self.normalize_data,
        )[0]
        return self.cost_function(data_processed, labels, lambda_param)
    def cost_function(self, data, labels, lambda_param):
        num_examples = data.shape[0]
        delta = self_LinearRegression.hypothesis(data, self.theta) - labels
        theta_cut = self.theta[1:, 0]
        reg_param = lambda_param * (theta_cut.T @ theta_cut)
        cost = (1 / 2 * num_examples) * (delta.T @ delta + reg_param)
        return cost[0][0]
    #预测
    def predict(self, data):
        data_processed = prepare_for_training(
            data,
            self.polynomial_degree,
            self.sinusoid_degree,
            self.normalize_data,
        )[0]
        predictions = self_LinearRegression.hypothesis(data_processed, self.theta)
        return predictions
    @staticmethod
    def hypothesis(data, theta):
        predictions = data @ theta
        return predictions
复制代码
#现在开始训练自己做的线性回归模型
num_iterations = 500  #设置迭代次数
learning_rate = 0.01   #学习率
regularization_param = 0 #正则化参数
polynomial_degree = 0
sinusoid_degree = 0 
linear_regression = self_LinearRegression(x_train, y_train, polynomial_degree, sinusoid_degree)
(theta, cost_history) = linear_regression.train(learning_rate,regularization_param,num_iterations)
#输出训练的损失率
print('最初损失率: {:.2f}'.format(cost_history[0]))
print('最优损失率: {:.2f}'.format(cost_history[-1]))
#输出模型参数
theta_table = pd.DataFrame({'自己的线性模型参数': theta.flatten()})
theta_table.head()


image.png

用自己写的模型训练得到的线性回归方程为:y=5.383319*x+0.892002


#画出梯度下降
plt.plot(range(num_iterations), cost_history)
plt.xlabel('迭代次数')
plt.ylabel('损失率')
plt.title('损失率梯度下降图')
plt.show()


image.png

#用自己构建的模型去进行预测,绘制出模型预测直线
predictions_num = 100
x_predictions = np.linspace(x_train.min(), x_train.max(), predictions_num).reshape(predictions_num, 1)
y_predictions = linear_regression.predict(x_predictions)
plt.scatter(x_train, y_train, label='训练数据')
plt.scatter(x_test, y_test, label='测试数据')
plt.plot(x_predictions, y_predictions, 'r', label='预测直线')
plt.xlabel('Economy..GDP.per.Capita.')
plt.ylabel('Happiness.Score')
plt.title('Countries Happines')
plt.legend()
plt.show()


image.png


后用sklrean的LinearRegression也来训练预测一下


#用sklearn构建线性回归模型
from sklearn.linear_model import LinearRegression
#创建模型
liner = LinearRegression()
#拟合模型
liner.fit(x_train,y_train)
#预测
y_predictions = liner.predict(x_predictions)
plt.scatter(x_train, y_train, label='训练数据')
plt.scatter(x_test, y_test, label='测试数据')
plt.plot(x_predictions, y_predictions, 'r', label='预测直线')
plt.xlabel('Economy..GDP.per.Capita.')
plt.ylabel('Happiness.Score')
plt.title('Countries Happines')
plt.legend()
plt.show()
print("斜率为:",liner.coef_)
print("截距为:",liner.intercept_)
复制代码



image.png

目录
相关文章
|
19天前
|
机器学习/深度学习 人工智能 算法
探索机器学习:从线性回归到深度学习
本文将带领读者从基础的线性回归模型开始,逐步深入到复杂的深度学习网络。我们将通过代码示例,展示如何实现这些算法,并解释其背后的数学原理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和知识。让我们一起踏上这段激动人心的旅程吧!
|
1月前
|
机器学习/深度学习 人工智能 算法
探索机器学习中的线性回归模型
本文深入探讨了机器学习中广泛使用的线性回归模型,从其基本概念和数学原理出发,逐步引导读者理解模型的构建、训练及评估过程。通过实例分析与代码演示,本文旨在为初学者提供一个清晰的学习路径,帮助他们在实践中更好地应用线性回归模型解决实际问题。
|
1月前
|
机器学习/深度学习 自然语言处理 算法
深入理解机器学习算法:从线性回归到神经网络
深入理解机器学习算法:从线性回归到神经网络
|
7月前
|
机器学习/深度学习 算法 TensorFlow
机器学习算法简介:从线性回归到深度学习
【5月更文挑战第30天】本文概述了6种基本机器学习算法:线性回归、逻辑回归、决策树、支持向量机、随机森林和深度学习。通过Python示例代码展示了如何使用Scikit-learn、statsmodels、TensorFlow库进行实现。这些算法在不同场景下各有优势,如线性回归处理连续值,逻辑回归用于二分类,决策树适用于规则提取,支持向量机最大化类别间隔,随机森林集成多个决策树提升性能,而深度学习利用神经网络解决复杂模式识别问题。理解并选择合适算法对提升模型效果至关重要。
256 4
|
7月前
|
机器学习/深度学习 数据采集 人工智能
【机器学习】解释什么是线性回归?
【5月更文挑战第15天】【机器学习】解释什么是线性回归?
|
1月前
|
机器学习/深度学习 数据采集 算法
探索机器学习中的线性回归
【10月更文挑战第25天】本文将深入浅出地介绍线性回归模型,一个在机器学习领域中广泛使用的预测工具。我们将从理论出发,逐步引入代码示例,展示如何利用Python和scikit-learn库实现一个简单的线性回归模型。文章不仅适合初学者理解线性回归的基础概念,同时也为有一定基础的读者提供实践指导。
|
2月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
探索机器学习:从线性回归到深度学习
在这篇文章中,我们将一起踏上一场激动人心的旅程,穿越机器学习的广阔天地。我们将从最基本的线性回归开始,逐步深入到复杂的深度学习模型。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。让我们一起探索这个充满无限可能的世界吧!
|
2月前
|
机器学习/深度学习 API
机器学习入门(七):线性回归原理,损失函数和正规方程
机器学习入门(七):线性回归原理,损失函数和正规方程
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习:从线性回归到深度学习
【9月更文挑战第4天】在这篇文章中,我们将深入探讨机器学习的世界,从基础的线性回归模型开始,逐步深入到复杂的深度学习网络。我们将通过实际的代码示例,揭示这些模型背后的数学原理,以及如何在现实世界的问题中应用它们。无论你是初学者还是有经验的数据科学家,这篇文章都将为你提供新的视角和深入的理解。
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习的奥秘:从线性回归到深度学习
【8月更文挑战第26天】本文将带领读者走进机器学习的世界,从基础的线性回归模型开始,逐步深入到复杂的深度学习网络。我们将探讨各种算法的原理、应用场景以及实现方法,并通过代码示例加深理解。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的知识和技能。让我们一起揭开机器学习的神秘面纱,探索这个充满无限可能的领域吧!