第49单元 线性回归拟合
线性回归是一种预测统计模型,其目的是使用线性模型来解释变量的全部或部分变化规律。这是一种监督建模技术:在预测之前,必须对模型进行训练(“拟合”)。
普通最小二乘回归
普通最小二乘(OLS)回归将自变量(预测因子)和因变量(预测值)联系在一起。该模型将预测值reg(xi )视为预测因子xi 的线性组合。真实值yi 和预测值之间的差异称为残差。在最佳拟合的情况下,所有残差都为零。可能的加权(权重wi >0)残差的平方和(SSR)给出了拟合的质量。训练模型的过程就是最小化SSR的过程:
另一种拟合质量的度量是模型得分,也称为R2。得分0≤R2≤1表示拟合模型(和理想情况)的差异大小。在最佳拟合的情况下,R2=1。对于非常差的拟合,R2≈0。
sklearn.linear_model模块中的构造函数LinearRegression()可以创建一个OLS回归对象。
fit()函数使用1×n的预测因子矩阵。如果模型具有一个自变量,且预测因子是矢量的形式,则使用numpy.newaxis对象的切片操作创建另一个维度。将因变量的真值作为一维矢量传递给fit()函数。(如果想对多个属性进行预测,则必须构建和拟合多个模型。)
拟合完成后,可以使用回归对象来计算预测值(函数predict())和得出拟合分数(函数score())。属性coef_和intercept_分别包含回归系数和拟合后的截距值。
以下示例使用Yahoo! Finance1的标准普尔500收盘价记录来建立、拟合和评估线性回归模型。假定数据之前被保存为文件sapXXI.csv。
1finance.yahoo.com/q/hp?s=^GSPC+Historical+Prices
首先,导入所有必要的模块并加载标准普尔500数据:
sap-linregr.py
import numpy, pandas as pd import matplotlib, matplotlib.pyplot as plt import sklearn.linear_model as lm # 获取数据 sap = pd.read_csv("sapXXI.csv").set_index("Date")
可以看出数据的行为通常是非线性的,但是从2009年1月1日开始有一个很好的、几乎线性的片段,并延伸到数据集的结尾。下面仅使用该片段进行模型拟合。可惜的是,SciKit-Learn不直接支持日期这种数据格式。因此,必须将其转换为序数,即天数,然后才能创建、拟合和评估线性回归模型,并算出标准普尔500指数的预测值。模型得分是0.95,这个值是可以接受的!
sap-linregr.py
# 选取一段“线性变化”的数据 sap.index = pd.to_datetime(sap.index) sap_linear = sap.ix[sap.index > pd.to_datetime('2009-01-01')] # 准备模型并拟合 olm = lm.LinearRegression() X = numpy.array([x.toordinal() for x in sap_linear.index])[:, numpy.newaxis] y = sap_linear['Close'] olm.fit(X, y) # 计算预测值 yp = [olm.predict(x.toordinal())[0] for x in sap_linear.index] # 评估模型 olm_score = olm.score(X, y)
最后,代码会将原始数据集、预测直线,甚至模型分数都绘制出来。结果如下面代码后的图所示。
sap-linregr.py
# 选择一种优美的绘图样式 matplotlib.style.use("ggplot") # 绘制两个数据集 plt.plot(sap_linear.index, y) plt.plot(sap_linear.index, yp) # 加入图饰 plt.title("OLS Regression") plt.xlabel("Year") plt.ylabel("S&P 500 (closing)") plt.legend(["Actual", "Predicted"], loc="lower right") plt.annotate("Score=%.3f" % olm_score, xy=(pd.to_datetime('2010-06-01'), 1900)) plt.savefig("../images/sap-linregr.pdf")
有一个不尽如人意的地方,那就是SciKit-Learn没有计算拟合的p值,因此不能确定拟合是否有效。
如果要将一些非线性预测因子(例如平方、平方根和对数)甚至原始预测因子的组合添加到模型中,只需将这些函数和组合看作新的自变量即可。
脊回归
如果存在两个或更多个预测因子是高度相关的(所谓的共线性的情况),则拟合OLS回归可能产生非常大的系数。你可以通过施加惩罚因子来限制回归系数的这种不可控增长。脊回归就是这样一种广义线性模型,它使用复杂度参数α来实现对系数的抑制。该过程称为模型的正则化:
当α=0时,脊回归退化为OLS回归。α越大,惩罚越大;模型拟合会得出较小的系数,但这样也有可能使模型变得更糟。
函数Ridge()创建一个脊回归对象,它以α为参数。创建对象后,可以像使用OLS回归一样使用它:
regr = lm.Ridge(alpha=.5) regr.fit(X, y) «...»
逻辑回归
虽然名称中有“回归”,但逻辑回归并不是回归,实际上它是一种二元分类工具。它使用广义逻辑函数(逻辑函数的扩展,也称为s曲线或sigmoid函数,如下图所示)。广义逻辑函数的特征包括上下渐近线、sigmoid函数中点的x值和曲线的陡度。
函数LogisticRegression()创建一个逻辑回归对象的实例。它需要几个可选参数,其中最重要的是参数C。
参数C是正则化参数的倒数(即脊回归的α的倒数)。通常,为了使分类的结果有意义,其取值至少为20。默认值C=1.0在许多实际情况下是不合理的。
因变量y可以是整数、布尔值或字符串。
sklearn.linear_model通过predict()函数实现分类。与线性回归模型(OLS和脊回归)不同,逻辑回归模型的预测结果通常比模型系数coef_和截距intercept_更有价值。
下面的例子将使用43名学生的计算机科学导论课程的匿名测验成绩(可在文档grade.csv中找到)来阐述逻辑回归。通过分析,研究是否能使用前两次的测验结果(共十次测试)来预测学生的最终成绩,或至少预测出成绩是否达标(“C”或以上):
logit-example.py
import pandas as pd from sklearn.metrics import confusion_matrix import sklearn.linear_model as lm # 初始化回归工具 clf = lm.LogisticRegression(C=10.0) # 读取数据,使用字母给出成绩的量化等级 grades = pd.read_table("grades.csv") labels = ('F', 'D', 'C', 'B', 'A') grades["Letter"] = pd.cut(grades["Final score"], [0, 60, 70, 80, 90, 100], labels=labels) X = grades[["Quiz 1", "Quiz 2"]] # 拟合,并给出模型得分和混淆矩阵 clf.fit(X, grades["Letter"]) print("Score=%.3f" % clf.score(X, grades["Letter"])) cm = confusion_matrix(clf.predict(X), grades["Letter"]) print(pd.DataFrame(cm, columns=labels, index=labels)) ➾ Score=0.535 ➾ F D C B A ➾ F 0 0 0 0 0 ➾ D 2 16 6 4 1 ➾ C 0 1 6 2 2 ➾ B 0 0 0 1 2 ➾ A 0 0 0 0 0
我们使用sklearn.metrics模块中的confusion_matrix()函数来计算混淆矩阵(参见表7)。模型得分看起来不太准确:该模型能够准确预测的成绩只占所有成绩的54%左右。然而,混淆矩阵的主对角线(正确预测)及其邻域几乎包含了所有的非零条目。这意味着模型的预测要么是准确的,要么是结果具有±1个字母的偏差。对大多数实际应用而言,这种“扩展”精度(84%)实际上已经足够了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论