【Python数据挖掘课程】五.线性回归知识及预测糖尿病实例

今天主要讲述的内容是关于一元线性回归的知识,Python实现,包括以下内容:
        1.机器学习常用数据集介绍
        2.什么是线性回顾
        3.LinearRegression使用方法
        
4.线性回归判断糖尿病
        前文推荐:
       【Python数据挖掘课程】一.安装Python及爬虫入门介绍
       【Python数据挖掘课程】二.Kmeans聚类数据分析及Anaconda介绍
       【Python数据挖掘课程】三.Kmeans聚类代码实现、作业及优化
       【Python数据挖掘课程】四.决策树DTC数据分析及鸢尾数据集分析

        希望这篇文章对你有所帮助,尤其是刚刚接触数据挖掘以及大数据的同学,同时准备尝试以案例为主的方式进行讲解。如果文章中存在不足或错误的地方,还请海涵~
        同时这篇文章是我上课的内容,所以参考了一些知识,强烈推荐大家学习斯坦福的机器学习Ng教授课程和Scikit-Learn中的内容。由于自己数学不是很好,自己也还在学习中,所以文章以代码和一元线性回归为主,数学方面的当自己学到一定的程度,才能进行深入的分享及介绍。抱歉~


一. 数据集介绍

        1.diabetes dataset数据集
        数据集参考:http://scikit-learn.org/stable/datasets/
        这是一个糖尿病的数据集,主要包括442行数据,10个属性值,分别是:Age(年龄)、性别(Sex)、Body mass index(体质指数)、Average Blood Pressure(平均血压)、S1~S6一年后疾病级数指标。Target为一年后患疾病的定量指标。


        输出如下所示:

[python]  view plain  copy
  1. # -*- coding: utf-8 -*-  
  2. """ 
  3. Created on Thu Oct 27 02:37:05 2016 
  4.  
  5. @author: yxz15 
  6. """  
  7.   
  8. from sklearn import datasets  
  9. diabetes = datasets.load_diabetes()                         #载入数据  
  10. print diabetes.data                                         #数据  
  11. print diabetes.target                                       #类标  
  12. print u'总行数: ', len(diabetes.data), len(diabetes.target) #数据总行数  
  13. print u'特征数: ', len(diabetes.data[0])                    #每行数据集维数  
  14. print u'数据类型: ', diabetes.data.shape                    #类型  
  15. print type(diabetes.data), type(diabetes.target)            #数据集类型  
  16.   
  17. """ 
  18. [[ 0.03807591  0.05068012  0.06169621 ..., -0.00259226  0.01990842 
  19.   -0.01764613] 
  20.  [-0.00188202 -0.04464164 -0.05147406 ..., -0.03949338 -0.06832974 
  21.   -0.09220405] 
  22.   ... 
  23.  [-0.04547248 -0.04464164 -0.0730303  ..., -0.03949338 -0.00421986 
  24.    0.00306441]] 
  25.  
  26. [ 151.   75.  141.  206.  135.   97.  138.   63.  110.  310.  101. 
  27.   ... 
  28. 64.   48.  178.  104.  132.  220.   57.] 
  29.  
  30. 总行数:  442 442 
  31. 特征数:  10 
  32. 数据类型:  (442L, 10L) 
  33. <type 'numpy.ndarray'> <type 'numpy.ndarray'> 
  34. """  

        2.sklearn常见数据集
        常见的sklearn数据集包括,强烈推荐下面这篇文章:
        http://blog.csdn.net/sa14023053/article/details/52086695
        
sklearn包含一些不许要下载的toy数据集,见下表,包括波士顿房屋数据集、鸢尾花数据集、糖尿病数据集、手写字数据集和健身数据集等。

        3.UCI数据集
        常用数据集包括:http://archive.ics.uci.edu/ml/datasets.html




二. 什么是线性回归

        1.机器学习简述
        机器学习(Machine Learning )包括:
        a.监督学习(Supervised Learning):回归(Regression)、分类(Classification)
        例:训练过程中知道结果。小孩给水果分类,给他苹果告诉他是苹果,反复训练学习。在给他说过,问他是什么?他回答准确,如果是桃子,他不能回答为苹果。

        b.无监督学习(Unsupervised Learning):聚类(Clustering)
        例:训练过程中不知道结果。给小孩一堆水果,如苹果、橘子、桃子,小孩开始不知道需要分类的水果是什么,让小孩对水果进行分类。分类完成后,给他一个苹果,小孩应该把它放到苹果堆中。

        c.增强学习(Reinforcement Learning)
        例:ML过程中,对行为做出评价,评价有正面的和负面两种。通过学习评价,程序应做出更好评价的行为。

        d.推荐系统(Recommender System)

        

        2.斯坦福公开课:第二课 单变量线性回归
        这是NG教授的很著名的课程,这里主要引用52nlp的文章,真的太完美了。推荐阅读该作者的更多文章:
        Coursera公开课笔记: 斯坦福大学机器学习第二课"单变量线性回归(Linear regression with one variable)"

        <1>模型表示(Model Representation)
        房屋价格预测问题,有监督学习问题。每个样本的输入都有正确输出或答案,它也是一个回归问题,预测一个真实值的输出。
        训练集表示如下:


        对于房价预测问题,讯息过程如下所示:

        其中x代表房屋的大小,y代表预测的价格,h(hypothesis)将输入变量映射到输出变量y中,如何表示h呢? 可以表示如下公式,简写为h(x),即带一个变量的线性回归或单变量线性回归问题。


       <2>成本函数(Cost Function)
        对于上面的公式函数h(x),如何求theta0和theta1参数呢? 
        构想: 对于训练集(x, y),选取参数 0 1 使得 hθ(x) 尽可能的接近y。如何做呢?一种做法就是求训练集的平方误差函数(squared error function)。
        Cost Function可表示为:
        并且选取合适的参数使其最小化,数学表示如下:


        总的来说,线性回归主要包括一下四个部分,分别是Hypothesis、Parameters、Cost Function、Goal。右图位简化版,theta0赋值为0。

  

        然后令 θ1 分别取1、0.5、-0.5等值,同步对比 hθ(x) J(θ0,θ1) 在二维坐标系中的变化情况,具体可参考原PPT中的对比图,很直观。

 

        <3>梯度下降(Gradient descent)

        应用的场景之一最小值问题:

        对于一些函数,例如 J(θ0,θ1)

        目标:   minθ0,θ1J(θ0,θ1)

        方法的框架:

        a. 给 θ0 θ1 一个初始值,例如都等于0;

        b. 每次改变 θ0 θ1 的时候都保持 J(θ0,θ1) 递减,直到达到一个我们满意的最小值;

        对于任一 J(θ0,θ1)  , 初始位置不同,最终达到的极小值点也不同,例如以下例子:



        3.一元回归模型
        转自文章:http://blog.sina.com.cn/s/blog_68c81f3901019hhp.html

        <1>什么是线性回归?
        回归函数的具体解释和定义,可查看任何一本“概率论与数理统计”的书。我看的是“陈希孺”的。
        这里我讲几点:
        1)统计回归分析的任务,就在于根据 x1,x2,...,xp 线性回归和Y的观察值,去估计函数f,寻求变量之间近似的函数关系。
        2)我们常用的是,假定f函数的数学形式已知,其中若干个参数未知,要通过自变量和因变量的观察值去估计未知的参数值。这叫“参数回归”。其中应用最广泛的是f为线性函数的假设:

         这种情况叫做“线性回归”。
        3)自变量只有一个时,叫做一元线性回归。
                                            f(x) = b0+b1x
               自变量有多个时,叫做多元线性回归。  
                                            f(x1,x2,...,xp) = b0 + b1x1 + b2x2 + ... + bpxp
        4)分类(Classification)与回归(Regression)都属于监督学习,他们的区别在于:
               分类:用于预测有限的离散值,如是否得了癌症(0,1),或手写数字的判断,是0,1,2,3,4,5,6,7,8还是9等。分类中,预测的可能的结果是有限的,且提前给定的。
               回归:用于预测实数值,如给定了房子的面积,地段,和房间数,预测房子的价格。

        <2>一元线性回归
        假设:我们要预测房价。当前自变量(输入特征)是房子面积x,因变量是房价y.给定了一批训练集数据。 我们要做的是利用手上的训练集数据,得出x与y之间的函数f关系,并用f函数来预测任意面积x对应的房价。
        假设x与y是线性关系,则我们可以接着假设一元线性回归函数如下来代表y的预测值:



        我们有训练集了,那么问题就成了如何利用现有的训练集来判定未知参数 (θ0,θ1) 的值,使其让h的值更接近实际值y? 训练集指的是已知x,y值的数据集合!

        一种方法是计算它的成本函数(Cost function),即预测出来的h的值与实际值y之间的方差的大小来决定当前的(θ0,θ1)值是否是最优的!
        常用的成本函数是最小二乘法:



        <3>模型总结
        整个一元线性回归通过下面这张图总结即可:


        参考文章:斯坦福大学机器学习——线性回归(Linear Regression)

        最后,梯度下降和多元回归模型将继续学习,当我学到一定程度,再进行分享。
         http://www.52nlp.cn/coursera公开课笔记-斯坦福大学机器学习第四课多变量



三. LinearRegression使用方法


        LinearRegression模型在Sklearn.linear_model下,它主要是通过fit(x,y)的方法来训练模型,其中x为数据的属性,y为所属类型。
        sklearn中引用回归模型的代码如下:

[python]  view plain  copy
  1. from sklearn import linear_model       #导入线性模型  
  2. regr = linear_model.LinearRegression() #使用线性回归  
  3. print regr  

        输出的函数原型如下所示:

[python]  view plain  copy
  1. LinearRegression(copy_X=True,   
  2.                  fit_intercept=True,   
  3.                  n_jobs=1,   
  4.                  normalize=False)  
        fit(x, y): 训练。分析模型参数,填充数据集。其中x为特征,y位标记或类属性。
        predict(): 预测。它通过fit()算出的模型参数构成的模型,对解释变量进行预测其类属性。预测方法将返回预测值y_pred。

        这里推荐"搬砖小工053"大神的文章,非常不错,强烈推荐。
        引用他文章的例子,参考:scikit-learn : 线性回归,多元回归,多项式回归

[python]  view plain  copy
  1. # -*- coding: utf-8 -*-  
  2. """ 
  3. Created on Fri Oct 28 00:44:55 2016 
  4.  
  5. @author: yxz15 
  6. """  
  7.   
  8. from sklearn import linear_model       #导入线性模型  
  9. import matplotlib.pyplot as plt        #绘图  
  10. import numpy as np  
  11.   
  12. #X表示匹萨尺寸 Y表示匹萨价格  
  13. X = [[6], [8], [10], [14], [18]]  
  14. Y = [[7], [9], [13], [17.5], [18]]  
  15.   
  16. print u'数据集X: ', X  
  17. print u'数据集Y: ', Y  
  18.   
  19. #回归训练  
  20. clf = linear_model.LinearRegression() #使用线性回归  
  21. clf.fit(X, Y)                         #导入数据集  
  22. res = clf.predict(np.array([12]).reshape(-11))[0#预测结果  
  23. print(u'预测一张12英寸匹萨价格:$%.2f' % res)  
  24.   
  25. #预测结果  
  26. X2 = [[0], [10], [14], [25]]  
  27. Y2 = clf.predict(X2)  
  28.   
  29. #绘制线性回归图形  
  30. plt.figure()  
  31. plt.title(u'diameter-cost curver')   #标题  
  32. plt.xlabel(u'diameter')              #x轴坐标  
  33. plt.ylabel(u'cost')                  #y轴坐标  
  34. plt.axis([025025])             #区间  
  35. plt.grid(True)                       #显示网格  
  36. plt.plot(X, Y, 'k.')                 #绘制训练数据集散点图  
  37. plt.plot(X2, Y2, 'g-')               #绘制预测数据集直线  
  38. plt.show()  
        运行结果如下所示,首先输出数据集,同时调用sklearn包中的LinearRegression()回归函数,fit(X, Y)载入数据集进行训练,然后通过predict()预测数据12尺寸的匹萨价格,最后定义X2数组,预测它的价格。
[python]  view plain  copy
  1. 数据集X:  [[6], [8], [10], [14], [18]]  
  2. 数据集Y:  [[7], [9], [13], [17.5], [18]]  
  3. 预测一张12英寸匹萨价格:$13.68  
        输出的图形如下所示:

        线性模型的回归系数W会保存在他的coef_方法中,截距保存在intercept_中。score(X,y,sample_weight=None) 评分函数,返回一个小于1的得分,可能会小于0。

[python]  view plain  copy
  1. print u'系数', clf.coef_  
  2. print u'截距', clf.intercept_  
  3. print u'评分函数', clf.score(X, Y)  
  4. ''''' 
  5. 系数 [[ 0.9762931]] 
  6. 截距 [ 1.96551743] 
  7. 评分函数 0.910001596424 
  8. '''  
        其中具体的系数介绍推荐如下资料: sklearn学习笔记之简单线性回归 - Magle



四. 线性回归判断糖尿病


        1.Diabetes数据集(糖尿病数据集)
        糖尿病数据集包含442个患者的10个生理特征(年龄,性别、体重、血压)和一年以后疾病级数指标。
        然后载入数据,同时将diabetes糖尿病数据集分为测试数据和训练数据,其中测试数据为最后20行,训练数据从0到-20行(不包含最后20行),即diabetes.data[:-20]。

[python]  view plain  copy
  1. from sklearn import datasets  
  2.   
  3. #数据集  
  4. diabetes = datasets.load_diabetes() #载入数据  
  5.   
  6. diabetes_x = diabetes.data[:, np.newaxis]  #获取一个特征  
  7. diabetes_x_temp = diabetes_x[:, :, 2]  
  8.   
  9. diabetes_x_train = diabetes_x_temp[:-20]   #训练样本  
  10. diabetes_x_test = diabetes_x_temp[-20:]    #测试样本 后20行  
  11. diabetes_y_train = diabetes.target[:-20]   #训练标记  
  12. diabetes_y_test = diabetes.target[-20:]    #预测对比标记  
  13.   
  14. print u'划分行数:', len(diabetes_x_temp), len(diabetes_x_train), len(diabetes_x_test)  
  15. print diabetes_x_test  
        输出结果如下所示,可以看到442个数据划分为422行进行训练回归模型,20行数据用于预测。输出的diabetes_x_test共20行数据,每行仅一个特征。
[python]  view plain  copy
  1. 划分行数: 442 422 20  
  2. [[ 0.07786339]  
  3.  [-0.03961813]  
  4.  [ 0.01103904]  
  5.  [-0.04069594]  
  6.  [-0.03422907]  
  7.  [ 0.00564998]  
  8.  [ 0.08864151]  
  9.  [-0.03315126]  
  10.  [-0.05686312]  
  11.  [-0.03099563]  
  12.  [ 0.05522933]  
  13.  [-0.06009656]  
  14.  [ 0.00133873]  
  15.  [-0.02345095]  
  16.  [-0.07410811]  
  17.  [ 0.01966154]  
  18.  [-0.01590626]  
  19.  [-0.01590626]  
  20.  [ 0.03906215]  
  21.  [-0.0730303 ]]  

        2.完整代码
        改代码的任务是从生理特征预测疾病级数,但仅获取了一维特征,即一元线性回归。【线性回归】的最简单形式给数据集拟合一个线性模型,主要是通过调整一系列的参以使得模型的残差平方和尽量小。
        线性模型:y = βX+b 
        X:数据 y:目标变量 β:回归系数 b:观测噪声(bias,偏差)
        参考文章:Linear Regression Example - Scikit-Learn 

[python]  view plain  copy
  1. # -*- coding: utf-8 -*-  
  2. """ 
  3. Created on Fri Oct 28 01:21:30 2016 
  4.  
  5. @author: yxz15 
  6. """  
  7.   
  8. from sklearn import datasets  
  9. import matplotlib.pyplot as plt  
  10. import numpy as np  
  11.   
  12. #数据集  
  13. diabetes = datasets.load_diabetes() #载入数据  
  14.   
  15. #获取一个特征  
  16. diabetes_x_temp = diabetes.data[:, np.newaxis, 2]   
  17.   
  18. diabetes_x_train = diabetes_x_temp[:-20]   #训练样本  
  19. diabetes_x_test = diabetes_x_temp[-20:]    #测试样本 后20行  
  20. diabetes_y_train = diabetes.target[:-20]   #训练标记  
  21. diabetes_y_test = diabetes.target[-20:]    #预测对比标记  
  22.   
  23. #回归训练及预测  
  24. clf = linear_model.LinearRegression()  
  25. clf.fit(diabetes_x_train, diabetes_y_train)  #注: 训练数据集  
  26.   
  27. #系数 残差平法和 方差得分  
  28. print 'Coefficients :\n', clf.coef_  
  29. print ("Residual sum of square: %.2f" %np.mean((clf.predict(diabetes_x_test) - diabetes_y_test) ** 2))  
  30. print ("variance score: %.2f" % clf.score(diabetes_x_test, diabetes_y_test))  
  31.   
  32. #绘图  
  33. plt.title(u'LinearRegression Diabetes')   #标题  
  34. plt.xlabel(u'Attributes')                 #x轴坐标  
  35. plt.ylabel(u'Measure of disease')         #y轴坐标  
  36. #点的准确位置  
  37. plt.scatter(diabetes_x_test, diabetes_y_test, color = 'black')  
  38. #预测结果 直线表示  
  39. plt.plot(diabetes_x_test, clf.predict(diabetes_x_test), color='blue', linewidth = 3)  
  40. plt.show()  

        运行结果如下所示,包括系数、残差平方和、方差分数。

[python]  view plain  copy
  1. Coefficients :[ 938.23786125]  
  2. Residual sum of square: 2548.07  
  3. variance score: 0.47  
        绘制图形如下所示,每个点表示真实的值,而直线表示预测的结果,比较接近吧。


        同时绘制图形时,想去掉坐标具体的值,可增加如下代码:

[python]  view plain  copy
  1. plt.xticks(())  
  2. plt.yticks(())  



五. 优化代码

        下面是优化后的代码,增加了斜率、 截距的计算,同时增加了点图到线性方程的距离,保存图片设置像素。

[python]  view plain  copy
  1. # -*- coding: utf-8 -*-  
  2. """ 
  3. Created on Thu Dec 29 12:47:58 2011 
  4.  
  5. @author: Administrator 
  6. """  
  7. #第一步 数据集划分  
  8. from sklearn import datasets  
  9. import numpy as np  
  10.   
  11. #获取数据 10*442  
  12. d = datasets.load_diabetes()  
  13. x = d.data  
  14. print u'获取x特征'  
  15. print len(x), x.shape  
  16. print x[:4]  
  17.   
  18. #获取一个特征 第3列数据  
  19. x_one = x[:,np.newaxis, 2]  
  20. print x_one[:4]  
  21.   
  22. #获取的正确结果  
  23. y = d.target  
  24. print u'获取的结果'  
  25. print y[:4]  
  26.   
  27. #x特征划分  
  28. x_train = x_one[:-42]  
  29. x_test = x_one[-42:]  
  30. print len(x_train), len(x_test)  
  31. y_train = y[:-42]  
  32. y_test = y[-42:]  
  33. print len(y_train), len(y_test)  
  34.   
  35.   
  36. #第二步 线性回归实现  
  37. from sklearn import linear_model  
  38. clf = linear_model.LinearRegression()  
  39. print clf  
  40. clf.fit(x_train, y_train)  
  41. pre = clf.predict(x_test)  
  42. print u'预测结果'  
  43. print pre  
  44. print u'真实结果'  
  45. print y_test    
  46.      
  47.      
  48. #第三步 评价结果  
  49. cost = np.mean(y_test-pre)**2  
  50. print u'次方'2**5  
  51. print u'平方和计算:', cost  
  52. print u'系数', clf.coef_   
  53. print u'截距', clf.intercept_    
  54. print u'方差', clf.score(x_test, y_test)  
  55.   
  56.   
  57. #第四步 绘图  
  58. import matplotlib.pyplot as plt  
  59. plt.title("diabetes")  
  60. plt.xlabel("x")  
  61. plt.ylabel("y")  
  62. plt.plot(x_test, y_test, 'k.')  
  63. plt.plot(x_test, pre, 'g-')  
  64.   
  65. for idx, m in enumerate(x_test):  
  66.     plt.plot([m, m],[y_test[idx],   
  67.               pre[idx]], 'r-')  
  68.   
  69. plt.savefig('power.png', dpi=300)  
  70.   
  71. plt.show()  
        运行结果如下所示:
[python]  view plain  copy
  1. 获取x特征  
  2. 442 (442L10L)  
  3. [[ 0.03807591  0.05068012  0.06169621  0.02187235 -0.0442235  -0.03482076  
  4.   -0.04340085 -0.00259226  0.01990842 -0.01764613]  
  5.  [-0.00188202 -0.04464164 -0.05147406 -0.02632783 -0.00844872 -0.01916334  
  6.    0.07441156 -0.03949338 -0.06832974 -0.09220405]  
  7.  [ 0.08529891  0.05068012  0.04445121 -0.00567061 -0.04559945 -0.03419447  
  8.   -0.03235593 -0.00259226  0.00286377 -0.02593034]  
  9.  [-0.08906294 -0.04464164 -0.01159501 -0.03665645  0.01219057  0.02499059  
  10.   -0.03603757  0.03430886  0.02269202 -0.00936191]]  
  11. [[ 0.06169621]  
  12.  [-0.05147406]  
  13.  [ 0.04445121]  
  14.  [-0.01159501]]  
  15. 获取的结果  
  16. 151.   75.  141.  206.]  
  17. 400 42  
  18. 400 42  
  19. LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)  
  20. 预测结果  
  21. 196.51241167  109.98667708  121.31742804  245.95568858  204.75295782  
  22.   270.67732703   75.99442421  241.8354155   104.83633574  141.91879342  
  23.   126.46776938  208.8732309   234.62493762  152.21947611  159.42995399  
  24.   161.49009053  229.47459628  221.23405012  129.55797419  100.71606266  
  25.   118.22722323  168.70056841  227.41445974  115.13701842  163.55022706  
  26.   114.10695016  120.28735977  158.39988572  237.71514243  121.31742804  
  27.    98.65592612  123.37756458  205.78302609   95.56572131  154.27961264  
  28.   130.58804246   82.17483382  171.79077322  137.79852034  137.79852034  
  29.   190.33200206   83.20490209]  
  30. 真实结果  
  31. 175.   93.  168.  275.  293.  281.   72.  140.  189.  181.  209.  136.  
  32.   261.  113.  131.  174.  257.   55.   84.   42.  146.  212.  233.   91.  
  33.   111.  152.  120.   67.  310.   94.  183.   66.  173.   72.   49.   64.  
  34.    48.  178.  104.  132.  220.   57.]  
  35. 次方 32  
  36. 平方和计算: 83.192340827  
  37. 系数 [ 955.70303385]  
  38. 截距 153.000183957  
  39. 方差 0.427204267067  
        绘制图形如下所示:



        强烈推荐下面线性回归相关的文章,希望读者自行阅读:
            [译]针对科学数据处理的统计学习教程(scikit-learn教程2)Tacey Wong (重点)
            scikit-learn : 线性回归 - 搬砖小工053      
            结合Scikit-learn介绍几种常用的特征选择方法 - Bryan
            用Python开始机器学习(3:数据拟合与广义线性回归) - lsldd
            Scikit Learn: 在python中机器学习 - yyliu
            Python机器学习——线性模型 - 郝智恒
            sklearn 数据加载工具(1) - 搬砖小工053
            sklearn系列之----线性回归 - Gavin__Zhou

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值