python sklearn-02:线性回归简单例子1 pythonsklearn机器学习线性回归例子
程序员文章站
2024-03-20 11:46:34
...
原文链接:https://muxuezi.github.io/posts/2-linear-regression.html
1.一元线性回归:
#一元线性回归:
预测披萨的价格:数据如下:
import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties #这个属性设置是让matplot画图时显示中文的标签 font = FontProperties(fname=r"C:\Windows\Fonts\msyh.ttc",size=15) #定义画图函数 def runplt(): plt.figure() plt.title('披萨价格与直径数据',fontproperties=font) plt.xlabel('直径(英寸)',fontproperties=font) plt.ylabel('价格(美元)',fontproperties=font) plt.axis([0,25,0,25],fontproperties=font) plt.grid(True) return plt #训练集数据 X = [[6], [8], [10], [14], [18]] y = [[7], [9], [13], [17.5], [18]] #导入一元线性回归函数:y = α + βx from sklearn.linear_model import LinearRegression model = LinearRegression() model.fit(X,y) #训练集数据放入模型中 print ('预测一张12英寸披萨价格:$%.2f' % model.predict([12])) plt = runplt() X2 = [[0],[10],[14],[25]] y2 = model.predict(X2) #预测数据 plt.plot(X,y,'k.') plt.plot(X2,y2,'g-') #残差预测值 yr = model.predict(X) for idx,x in enumerate(X): plt.plot([x,x], [y[idx], yr[idx]],'r-') plt.show()
图如下:
解一元线性方程:
#解一元线性回归:这里用最小二乘法 #LinearRegression类的fit()方法学习下面的一元线性回归模型:y = α + βx #β =cov(x, y)/var(x) (协方差/方程) α = y¯ − βx¯ import numpy as np var =np.var([6, 8, 10, 14, 18], ddof=1) print ('方差为%.2f'%var) cov = np.cov([6, 8, 10, 14, 18], [7, 9, 13, 17.5, 18])[0][1] print ('协方差为%.2f'%cov) b = cov/var a = np.mean(y)-b*np.mean(X) print ('方程为 y = %.2f x - %.2f'%(a,b)) #输出结果 方差为23.20 协方差为22.65 方程为 y = 1.97 x - 0.98
评估这个模型的预测准确度,这里引入测试集:
#模型评估:R方也叫确定系数,表示模型对现实数据的拟合程度。一定是介于0~1间的数 #引入测试集 X_test = [[8], [9], [11], [16], [12]] y_test = [[11], [8.5], [15], [18], [11]] r2 = model.score(X_test,y_test) print ('R^2 = %.2f'%r2) #输出结果 R^2 = 0.66
看起来确定系数不高,那我们来试下多元回归,看看效果如何。
2.多元线性回归:
现实中披萨价格的影响因素应该不止直径一个,这里引入了辅料的因素,数据更新如下:
训练集数据:
测试集数据:
#多元回归
#y = α + β1x1 + β2x2 + ⋯ + βnxn,写成矩阵形式 Y = Xβ,其中, 是训练集的响应变量列向量,是模型
#参数列向量。 称为设计矩阵,是 维训练集的解释变量矩阵。 是训练集样本数量, 是解释变量个数
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
font = FontProperties(fname=r"C:\Windows\Fonts\msyh.ttc",size=15)
def runplt():
plt.figure()
plt.title('披萨价格与直径数据',fontproperties=font)
plt.xlabel('直径(英寸)',fontproperties=font)
plt.ylabel('价格(美元)',fontproperties=font)
plt.axis([0,25,0,25],fontproperties=font)
plt.grid(True)
return plt
#训练集,一元线性回归模型训练
X = [[6, 2], [8, 1], [10, 0], [14, 2], [18, 0]]
y = [[7], [9], [13], [17.5], [18]]
model = LinearRegression()
model.fit(X,y)
#测试集,及预测
X_test = [[8, 2], [9, 0], [11, 2], [16, 2], [12, 0]]
y_test = [[11], [8.5], [15], [18], [11]]
predictions = model.predict(X_test)
#确定性系数计算
print ('R^2 为 %.2f' %model.score(X_test, y_test))
#画图
plt.title('多元回归实际值与预测值',fontproperties=font)
plt.plot(y_test,label='y_test')
plt.plot(predictions,label='predictions')
plt.legend()
#结果输出:
R^2 为 0.77
图如下:
看到确定性系数比只有直径一个因素时高,拟合效果比较好。
3.多项式回归:二次回归:
从训练集原始数据的散点图来看:其实也有可能是一个曲线模型,这里试下二次回归的效果
还是用只有直径一个因素的训练集数据,二次回归(Quadratic Regression),y = α + β1x + β2x^2,我们有一个解释变量,但是模型有三项,通过第三项(二次项)来实现曲线关系,PolynomialFeatures转换器可以用来解决这个问题。
#多项式回归 #二次回归(Quadratic Regression),y = α + β1x + β2x2,我们有一个解释变量,但是模型有三项,通过第三项(二次项)来实现曲线关系 import numpy as np from sklearn.linear_model import LinearRegression from sklearn.preprocessing import PolynomialFeatures font = FontProperties(fname=r"C:\Windows\Fonts\msyh.ttc",size=15) def runplt(): plt.figure() plt.title('披萨价格与直径数据',fontproperties=font) plt.xlabel('直径(英寸)',fontproperties=font) plt.ylabel('价格(美元)',fontproperties=font) plt.axis([0,25,0,25],fontproperties=font) plt.grid(True) return plt X_train = [[6], [8], [10], [14], [18]] y_train = [[7], [9], [13], [17.5], [18]] X_test = [[6], [8], [11], [16]] y_test = [[8], [12], [15], [18]] plt = runplt() regressor = LinearRegression() regressor.fit(X_train,y_train) xx = np.linspace(0, 26, 100) yy = regressor.predict(xx.reshape(xx.shape[0], 1)) plt.plot(X_train, y_train, 'k.') plt.plot(xx, yy) #构造第三项 quadratic_fearurizer = PolynomialFeatures(degree=2) X_train_quadratic = quadratic_fearurizer.fit_transform(X_train) X_test_quadratic = quadratic_fearurizer.transform(X_test) regressor_quadratic = LinearRegression() regressor_quadratic.fit(X_train_quadratic, y_train) xx_quadratic = quadratic_fearurizer.transform(xx.reshape(xx.shape[0],1)) plt.plot(xx,regressor_quadratic.predict(xx_quadratic),'r-') plt.show() print ('一元线性回归 r^2: %.2f'%regressor.score(X_test,y_test)) print('二次回归 r^2: %.2f'%regressor_quadratic.score(X_test_quadratic, y_test))
结果如下:
从r^2 看起来二次回归效果比线性回归好。那么三次回归,四次回归效果会不会更好呢?我们来试下:
#多项式回归 from sklearn.linear_model import LinearRegression from sklearn.preprocessing import PolynomialFeatures import matplotlib.pyplot as plt X_train = [[6], [8], [10], [14], [18]] y_train = [[7], [9], [13], [17.5], [18]] X_test = [[6], [8], [11], [16]] y_test = [[8], [12], [15], [18]] k_range = range(2,10) k_scores = [] regressor = LinearRegression() regressor.fit(X_train,y_train) k_scores.append (regressor.score(X_test,y_test)) for k in k_range: k_featurizer = PolynomialFeatures(degree=k) X_train_k = k_featurizer.fit_transform(X_train) X_test_k = k_featurizer.transform(X_test) regression_k = LinearRegression() regression_k.fit(X_train_k,y_train) k_scores.append(regression_k.score(X_test_k,y_test)) for i in range(0,8): print('%d 项式 r^2 是 %.2f'%(i+1,k_scores[i])) plt.plot([1,2,3,4,5,6,7,8,9],k_scores) plt.show()
结果如下:
1项式就是线性回归啦,从r^2的图来看,并不是项式越多效果越好,在二项式时拟合效果最高。后面的那些情况较多过度拟合,这种模型并没有从输入和输出中推导出一般的规律,而是记忆训练集的结果,这样
在测试集的测试效果就不好了。是有一些方式可以避免这种情况的。后面再慢慢学习。