美文网首页玩转大数据互联网科技数据分析
一元(多元)线性回归分析之Python语言实现

一元(多元)线性回归分析之Python语言实现

作者: 天善智能 | 来源:发表于2018-06-12 11:04 被阅读14次

    欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

    对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tsaiedu,并注明消息来源,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

    618狂欢,天善学院全场课程6.18折等你来! 投资知识,赋能自我,蝶变在即! https://www.hellobi.com/618

    本文来自天善智能社区专栏作者:okajun
    相关文章链接:《一元(多元)线性回归分析之Excel实现
    一元(多元)线性回归分析之R语言实现

    写《一元(多元)线性回归分析之Excel实现》的时候就说还要写《一元(多元)线性回归分析之R语言实现》和在Python中的实现,其实本篇的文档早就准备好,但是一直没有找到关于模型的检验方法,所以一直迟迟没有发布,今天先把我知道的分享出来,希望看到的各位多多指导,不吝赐教。

    本文案例依然使用women数据集和salary数据集,请查阅上篇博文下载。

    1.一元线性回归

    1.1 使用sklearn,全部样本数据

    先导入要使用的库和模块

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from sklearn import datasets, linear_model
    from sklearn.metrics import mean_squared_error, r2_score
    from sklearn.model_selection import train_test_split
    

    导入数据集

    women = pd.read_csv('C:\\Users\\HuZhanPeng\\Desktop\\Regression\\women.csv')
    women.head()
    
    Clipboard Image.png

    先做数据探索,做散点图

    X = women[['height']] # 注意这种写法,得到的X仍然是dataframe类型
    y = women['weight'].values # 得到的y是numpy.ndarray类型
    
    # 数据探索:画散点图查看分布情况
    %pylab inline
    plt.scatter(X, y, color='black')
    plt.xlabel('height')
    plt.ylabel('weight')
    
    Clipboard Image.png

    可以看到有weight和height有很明显的线性正相关关系,下面我们来建立线性模型。

    regr = linear_model.LinearRegression()
    regr.fit(X, y)
    

    查看模型结果:

    print('Intercept:{}'.format(regr.intercept_))
    print('Coefficient:{}'.format(regr.coef_))
    

    得到一元线性方程:weight=-87.52+3.45height

    查看预测值(直线) vs. 真实值(散点)

    plt.scatter(X, y, color='black')
    plt.plot(X, regr.predict(X), linewidth=3, color='blue')
    plt.xlabel('height')
    plt.ylabel('weight')
    
    Clipboard Image.png

    1.2使用sklearn,训练集测试集

    上文1.1我们使用了全部样本数据建模,得到了回归方程,通过上面的散点图来看模型效果不错,但是如何精确评估方程的效果呢?我并没有找到合适的方法。

    下面我们使用sklearn官网上的案例,将women数据集拆分成训练集和测试集,并查看模型的效果如何。

    建立模型:

    # 使用测试集、训练集
    trian_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.2, random_state=123)
    regr1 = linear_model.LinearRegression()
    regr1.fit(trian_X, train_y)
    

    输出模型结果:

    print('Intercept:{}'.format(regr1.intercept_))
    print('Coefficient:{}'.format(regr1.coef_))
    

    得到一元线性方程:weight=-87.77+3.46height,和1.1中的模型结果稍有区别,因为我们只用了80%的数据建模。

    使用测试集来验证模型效果:

    # 使用test_X预测y,得到y_pred1
    y_pred1 = regr1.predict(test_X)
    # Variance score越接近1越好
    print("Mean squared error: %.2f"      % mean_squared_error(test_y, y_pred1))
    print('Variance score: %.2f' % r2_score(test_y, y_pred1))
    

    得到:Variance score: 0.97,说明模型效果很好。

    1.3改进模型(增加二次项)

    引入一个二次项x²进入模型:

    from sklearn.preprocessing import PolynomialFeatures
    ploy_reg = PolynomialFeatures(degree=2)
    X_ = ploy_reg.fit_transform(X)
    regr2 = linear_model.LinearRegression()
    regr2.fit(X_, y)
    
    X2 = X.sort_values(['height'])
    X2_ = ploy_reg.fit_transform(X2)
    

    作图查看模型拟合效果:

    plt.scatter(X, y, color='black')
    plt.plot(X2, regr2.predict(X2_), color='blue', linewidth=3)
    
    Clipboard Image.png

    查看模型检验结果:

    y_pred2 = regr2.predict(ploy_reg.fit_transform(test_X))
    
    print("Mean squared error: %.2f"      % mean_squared_error(test_y, y_pred2))
    print('Variance score: %.2f' % r2_score(test_y, y_pred2))
    

    得到:Variance score: 1.00,模型效果进一步提升。

    1.4使用statsmodels

    以上1.1-1.3都是使用的sklearn建模,下面我们使用statsmodels建模,使用此module建模的输出结果跟R类似。

    import statsmodels.api as sm
    X3 = sm.add_constant(X)
    est = sm.OLS(y, X3)
    est2 =est.fit()
    print(est2.summary())
    
    Clipboard Image.png

    可以看到输出结果非常类似于R,结果不再解读,参见上一篇在R中实现的博文。

    同样:将sm.add_constant(X)中的X,换成变换后的X_,可以得到加入二项式的回归方程,不再展示。

    2.多元线性回归

    同样适用salary数据集,导入数据并查看:

    salary = pd.read_csv('C:\\Users\\HuZhanPeng\\Desktop\\Regression\\salary.csv')
    salary.head()
    
    Clipboard Image.png

    哑变量处理,将gend转化为数值型:

    salary = pd.concat([salary, pd.get_dummies(salary['gend'])], axis=1)del 
    salary['gend']del 
    salary['female']
    salary.head()
    
    Clipboard Image.png

    在R中我们直接主观地把gend这边变量剔除了,现在Python中我们先保留,让模型选择是否留下此变量。

    y = salary['salary'].values
    X = salary[['age', 'company_age', 'education', 'male']]
    
    X2 = sm.add_constant(X)
    est = sm.OLS(y, X2)
    est2 = est.fit()
    print(est2.summary())
    
    Clipboard Image.png

    可以看到male没有通过t检验。

    我们使用AIC法则,来选择最优的模型:

    predictorcols = ['age', 'company_age', 'education', 'male']
    import itertools
    AICs = {}
    for k in range(1, len(predictorcols)+1):    
        for variables in itertools.combinations(predictorcols, k):        
            predictors = X[list(variables)]
            predictors2 = sm.add_constant(predictors)
            est = sm.OLS(y, predictors2)
            res = est.fit()
            AICs[variables] = res.aic
    

    按照AIC值有小到大输出前10种模型组合:

    from collections import Counter
    c = Counter(AICs)
    c.most_common()[::-10]
    

    输出如下:

    Clipboard Image.png

    可以看到:最优的模型是将'age', 'company_age', 'education'这3个变量引入模型。

    重新建模:

    X_new = salary[['age', 'company_age', 'education']]
    X3 = sm.add_constant(X_new)
    est = sm.OLS(y, X3)
    est2 = est.fit()
    print(est2.summary())
    
    Clipboard Image.png

    可以看到新方程通过了F检验,系数都通过了t检验。

    得到回归方程: salary = -4.463e+04 + 2303.8365age + 1952.7198company_age + 8052.9691*education

    如果想使用岭回归,可以查看sklearn官网中岭回归的介绍。

    补充:Python中如何进行正太分布检验、齐方差检验、共线性检验等我暂时还没有找到很好的方法。如果哪位知道,还请不吝赐教,谢谢~

    相关文章

      网友评论

        本文标题:一元(多元)线性回归分析之Python语言实现

        本文链接:https://www.haomeiwen.com/subject/gvrleftx.html