zoukankan      html  css  js  c++  java
  • 怎样用Python的Scikit-Learn库实现线性回归?

    来源商业新知号网,原标题:用Python的Scikit-Learn库实现线性回归

    回归和分类是两种 监督 机器 学习算法, 前者预测连续值输出,而后者预测离散输出。 例如,用美元预测房屋的价格是回归问题,而预测肿瘤是恶性的还是良性的则是分类问题。

    在本文中,我们将简要研究线性回归是什么,以及如何使用Scikit-Learn(最流行的Python机器学习库之一)在两个变量和多个变量的情况下实现线性回归。

    知识图谱,用Python的Scikit-Learn库实现线性回归

    线性回归理论

    代数学中,术语“线性”是指两个或多个变量之间的线性关系。 如果在二维空间中绘制两个变量之间的关系,可以得到一条直线。

    线性回归可以根据给定的自变量(x)预测因变量值(y),而这种回归技术可以确定x(输入)和y(输出)之间的线性关系,因此称之为线性回归。 如果在x轴上绘制自变量(x),又在y轴上绘制因变量(y),线性回归给出了一条最符合数据点的直线,如下图所示。

    得出线性方程大概是:

    知识图谱,用Python的Scikit-Learn库实现线性回归

    上述等式应为: Y= mx + b

    其中b是截距,m是直线的斜率。 线性回归算法大体上提供了截距和斜率的最优值。 因为x和y是数据特征,因此这两个变量保持不变。 可以控制的值是截距(b)和斜率(m)。 根据截距和斜率的值,图上可以有多条直线。 线性回归算法的可以找到符合数据点的多条线,并确认导致最小误差的其中一条线。

    两个以上的变量的情况也适合使用线性回归,这可称为多元线性回归。 比方说,假设这样一个场景,你必须根据房屋面积、卧室数量、住房人口的平均收入、屋龄等来预测房屋的价格。 在这种情况下,因变量(目标变量)取决于几个不同的独立变量。 而这种涉及多个变量的回归模型可表示为:

    y = b0 + m1b1 +m2b2 + m3b3 + ... mnbn

    这是超平面的等式。 请牢记,二维线性回归模型是一条直线; 而三维线性回归模型则是一个平面,并且三维以上是超平面。

    本节内容将介绍Python中用于机器学习的Scikit-Learn库如何实现回归函数。 我们将从涉及两个变量的简单线性回归开始,然后逐步转向涉及多个变量的线性回归。

    知识图谱,用Python的Scikit-Learn库实现线性回归

    简单线性回归

    知识图谱,用Python的Scikit-Learn库实现线性回归

    线性回归

    在查看第二次世界大战数据集中空中轰炸行动的记录时,我发现恶劣天气几乎要推迟当时的诺曼底登陆,下载了当时的天气报告,以便与轰炸行动数据集的任务进行比较。

    该数据集包含世界各地气象站每天记录的天气状况信息,内容包括降水、降雪、气温和风速,同时也记录了当天是否出现雷暴或其他恶劣天气情况。

    将这些输入特征值看成是最低温度,从而以预测最高温。

    开始编码

    导入所需的库:

    import pandas as pd

    import numpy as np

    import matplotlib.pyplot as plt

    import seaborn as seabornInstance

    from sklearn.model_selection import train_test_split

    from sklearn.linear_model import LinearRegression

    from sklearn import metrics

    %matplotlib inline

    以下命令使用pandas导入CSV数据集:

    dataset =pd.read_csv('/Users/nageshsinghchauhan/Documents/projects/ML/ML_BLOG_LInearRegression/Weather.csv')

    通过检查数据集内的行数和列数,大概对数据有了一点认识。

    dataset.shape

    如果输出值写着 (119040, 31),这意味着这个数据集含有119040行和31列。

    可以使用describe()以查看数据集的统计详细信息:

    dataset.describe()

    知识图谱,用Python的Scikit-Learn库实现线性回归

    数据集的统计视图

    最后,在二维图上绘制我们的数据点并观察我们的数据集,看看是否可以使用以下脚本手动查找数据之间的关系:

    dataset.plot(x='MinTemp', y='MaxTemp',)

    plt.title('MinTemp vs MaxTemp')

    plt.xlabel('MinTemp')

    plt.ylabel('MaxTemp')

    plt.show()

    我们采用了MinTemp和MaxTemp进行分析。 下面是MinTemp和MaxTemp之间的二维图。

    知识图谱,用Python的Scikit-Learn库实现线性回归

    查找一下平均最高温度——二维图绘制完成后,可以观察到平均最高温度在25(摄氏度)和35(摄氏度)之间。

    plt.figure(figsize=(15,10))

    plt.tight_layout()

    seabornInstance.distplot(dataset['MaxTemp'])

    知识图谱,用Python的Scikit-Learn库实现线性回归平均最高温在20到35之间

    下一步,把这些数据分为“属性”和“标签”两类。

    属性是自变量,而标签是因变量,其值有待预测。 在我们的数据集中,我们只有两列数据。 我们想根据记录的MinTemp来预测MaxTemp,因此属性集将包含存储在X变量中的“MinTemp”列,而标签则存储在y变量中的“MaxTemp”列。

    X = dataset['MinTemp'].values.reshape(-1,1)

    y = dataset['MaxTemp'].values.reshape(-1,1)

    接下来,80%的数据将作为训练样本集,而另外的20%则用于测试以下编码。

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=0)

    在将数据分成训练集和测试集后,便开始训练算法。 为此,需要导入LinearRegression类,并将之实例化,并采用fit()方法已验证这些训练数据。

    regressor = LinearRegression()

    regressor.fit(X_train, y_train) #training the algorithm

    我们前面曾讨论过,线性回归模型可以大致找到截距和斜率的最佳值,从而确定最符合相关数据的线的位置。如要查看线性回归算法为我们的数据集计算的截距和斜率的值,请执行以下代码。

    #To retrieve the intercept:

    print(regressor.intercept_)

    #For retrieving the slope:

    print(regressor.coef_)

    结果分别约为10.66185201与0.92033997。

    这意味着——若最低温度发生变化,那么最高温度有0.92%的可能性也发生变化。

    既然已经训练了这算法,现在是时候进行一些预测了。 为需要测试数据,并检验算法预测百分比得分的准确程度。 要对测试数据进行预测,请执行以下脚本:

    y_pred = regressor.predict(X_test)

    现在将X_test的实际输出值与预测值进行比较,请执行以下脚本:

    df = pd.DataFrame({'Actual': y_test.flatten(), 'Predicted':y_pred.flatten()})

    df

    知识图谱,用Python的Scikit-Learn库实现线性回归

    实际值与预测值的比较

    还可以使用以下脚本,用条形图的方式展示这些比较:

    注意: 由于记录数量庞大,为了更好的展示效果,我们只使用了其中25条记录。

    df1 = df.head(25)

    df1.plot(kind='bar',figsize=(16,10))

    plt.grid(which='major', linestyle='-', linewidth='0.5', color='green')

    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')

    plt.show()

    知识图谱,用Python的Scikit-Learn库实现线性回归

    实际值与预测值比较的条形图

    尽管这个模型不尽准确,但预测的百分比依然接近实际数值。

    根据这些测试数据可以画出一条直线:

    plt.scatter(X_test, y_test, color='gray')

    plt.plot(X_test, y_pred, color='red', linewidth=2)

    plt.show()

    知识图谱,用Python的Scikit-Learn库实现线性回归

    预测值和测试数据

    图上直线显示我们的算法无误。

    最后一步是评估算法的性能。 此步骤对于比较不同算法在特定数据集上的实现情况尤为重要。 对于回归算法,通常使用三种评估指标:

    1.平均绝对误差(MAE)指的是误差绝对值的平均值。 计算方法如下:

    知识图谱,用Python的Scikit-Learn库实现线性回归

    2.均方误差(MSE)是平方误差的平均值,计算公式如下:

    知识图谱,用Python的Scikit-Learn库实现线性回归

    3.均方根误差 (RMSE)为平方误差均值的平方根:

    知识图谱,用Python的Scikit-Learn库实现线性回归

    幸运的是,我们无需手动计算,Scikit-Learn库的预建功能可以计算这些值。

    使用测试数据找到这些指标的值。

    print('MeanAbsolute Error:', metrics.mean_absolute_error(y_test, y_pred))

    print('MeanSquared Error:', metrics.mean_squared_error(y_test, y_pred))

    print('RootMean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred))

    你会得到这样的输出结果(结果可能略有不同):

    ('MeanAbsolute Error:', 3.19932917837853)

    ('MeanSquared Error:', 17.631568097568447)

    ('RootMean Squared Error:', 4.198996082109204)

    由上可见,均方根误差的值是4.19,这个数值超过了所有温度百分比平均值的10%,即22.41。 这意味着我们的算法不是很准确,但预测能力良好。

    知识图谱,用Python的Scikit-Learn库实现线性回归

    多元线性回归

    知识图谱,用Python的Scikit-Learn库实现线性回归

    来源

    上面部分主要针对两个变量进行线性回归,但你遇到的所有实际问题中变量可不止两个。 涉及多个变量的线性回归则称为“多元线性回归”。 执行多元线性回归的步骤与简单线性回归的步骤相似。 不同之处在于评估过程。 利用多元线性回归可以找出哪个因素对预测输出的影响最大,以及不同变量之间的相互关系。

    在本节中,我们下载了红葡萄酒质量数据集,该数据集与葡萄牙的“Vinho Verde”(绿酒)葡萄酒的红色变体有关。 由于隐私和后勤问题,我们只掌握物理化学(输入)变量和感官(输出)变量的数据(例如,关于葡萄类型,葡萄酒品牌,葡萄酒销售价格等的数据暂缺)。

    将考虑各种输入特征,如固定酸度,挥发性酸度,柠檬酸,残糖,氯化物,游离二氧化硫,总二氧化硫,密度,pH,硫酸盐,酒精。 我们将利用这些特征来预测葡萄酒的质量。

    开始编码

    输入所需的库:

    importpandas as pd

    importnumpy as np

    importmatplotlib.pyplot as plt

    importseaborn as seabornInstance

    fromsklearn.model_selection import train_test_split

    fromsklearn.linear_model import LinearRegression

    fromsklearn import metrics

    %matplotlibinline

    以下指令将通过上面的链接从下载的文件中导入数据集:

    dataset =pd.read_csv('/Users/nageshsinghchauhan/Documents/projects/ML/ML_BLOG_LInearRegression/winequality.csv')

    通过检查数据集内的行数和列数,我们大概对以上数据有了一点认识。

    dataset.shape

    若输出值为(1599,12),则表明数据集中行数为1599,列数为12.

    我们可以使用describe()以查看数据集的统计详细信息:

    dataset.describe()

    知识图谱,用Python的Scikit-Learn库实现线性回归

    我们还需对数据进行筛选,首先查找哪些列含有NaN值:

    dataset.isnull().any()

    执行上面的代码后,所有列都会显示最后的结果False,如果有一列出现了True,则使用下面的代码从该列中删除所有空值。

    dataset= dataset.fillna(method='ffill')

    下一步是将数据划分为“属性”和“标签”。 X变量包含所有属性/特征,y变量包含标签。

    X = dataset[['fixed acidity', 'volatileacidity', 'citric acid', 'residual sugar', 'chlorides', 'free sulfur dioxide','total sulfur dioxide', 'density', 'pH', 'sulphates','alcohol']].values

    y = dataset['quality'].values

    计算“质量”一行的平均值。

    plt.figure(figsize=(15,10))

    plt.tight_layout()

    seabornInstance.distplot(dataset['quality'])

    知识图谱,用Python的Scikit-Learn库实现线性回归

    葡萄酒质量的平均值

    从上图可得,大部分葡萄酒的质量平均值为5或6。

    接下来,80%的数据将作为训练样本集,而另外的20%则用于测试以下编码。

    X_train,X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

    现在开始测试模型。

    regressor= LinearRegression()

    regressor.fit(X_train,y_train)

    如前所述,在多变量线性回归中,回归模型必须找到所有属性的最佳系数。 如要查看该回归模型选择了哪些系数,请执行以下脚本:

    coeff_df= pd.DataFrame(regressor.coef_, X.columns, columns=['Coefficient'])

    coeff_df

    最后的输出值大致如下:

    知识图谱,用Python的Scikit-Learn库实现线性回归

    这意味着,随着“密度”的单位增加,葡萄酒的质量减少了31.51个单位。 同理,“氯化物”的单位的减少也会使得葡萄酒质量增加1.87个单位。 同时我们还可以可以看到其余的特征对葡萄酒的质量影响很小。

    现在对测试数据进行预测。

    y_pred= regressor.predict(X_test)

    检验实际值和预测值之间的差异。

    df =pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})

    df1= df.head(25)

    知识图谱,用Python的Scikit-Learn库实现线性回归

    实际值与预测值的对比

    对实际值和预测值之间对比进行描点:

    df1.plot(kind='bar',figsize=(10,8))

    plt.grid(which='major',linestyle='-', linewidth='0.5', color='green')

    plt.grid(which='minor',linestyle=':', linewidth='0.5', color='black')

    plt.show()

    知识图谱,用Python的Scikit-Learn库实现线性回归

    以上条形图可用于展示预测值和实际值之间的差异

    可以看到,这个模型的预测结果比较准确。

    最后一步是评估算法的性能。 我们将通过计算MAE,MSE和RMSE的值来完成此操作。 请执行以下脚本:

    print('MeanAbsolute Error:', metrics.mean_absolute_error(y_test, y_pred))

    print('MeanSquared Error:', metrics.mean_squared_error(y_test, y_pred))

    print('RootMean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))

    输出值为:

    ('MeanAbsolute Error:', 0.46963309286611077)

    ('MeanSquared Error:', 0.38447119782012446)

    ('RootMean Squared Error:', 0.6200574149384268)

    可以看到,均方根误差值为0.62,略大于所有状态下的气体消耗平均值的10%,即5.63。 这意味着算法还不够精准,但其预测能力依然让人认同。

    导致这种不准确的有多种因素,如:

    · 数 据量不足 : 需要大量数据才能获得最准确的预测。

    · 假设失误 : 假设这些数据具有线性关系,但实际可能并非如此。 可以将数据可视化来确定结果。

    · 属性关联度低 : 参与计算的属性与我们的预测值关联度不大。

  • 相关阅读:
    Java 泛型,你了解类型擦除吗?
    终于有人把 Nginx 说清楚了,图文详解!
    给你一份超详细 Spring Boot 知识清单
    Java 中的 SPI 机制是什么鬼?
    用 Git 和 Github 提高效率的 10 个技巧!
    聊聊微服务架构及分布式事务解决方案!
    python多线程同步机制Lock
    python多线程同步机制Semaphore
    mysql 慢查询时间
    mysql row模式查看原始sql
  • 原文地址:https://www.cnblogs.com/xinzhihao/p/10770070.html
Copyright © 2011-2022 走看看