
來源頭條作者:天文學原畫多元回歸與非線性回歸多元回歸:自變量有不止一個,最后來預測一個結果非線性回歸:函數就不是簡單的都是一次項,引入了高階項使函數更能完美擬合得到準確率更高的預測值首先引入一個學生的身高體重數據集來回顧昨天的一元線性回歸訓練集序號身高(m)體重(kg)10.861220.961531.122041.353551.554861.635171.715981.7866測試集序號身高(m)體重(kg)10.751021.081731.262741.514151.65061.676471.8575#先查看身高體重是否存在線性關系
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from sklearn.preprocessing import PolynomialFeatures
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
def runplt():
plt.figure()
plt.title('身高與體重一元關系')
plt.xlabel('身高')
plt.ylabel('體重')
plt.axis([0,2,0,85])
plt.grid
return plt
X=[[0.86],[0.96],[1.12],[1.35],[1.55],[1.63],[1.71],[1.78]]
y=[[12],[15],[20],[35],[48],[51],[59],[66]]
plt=runplt()
plt.plot(X,y,'k.')
plt.show()
復制代碼# 用sklearn的線性模型去擬合
from sklearn.linear_model import LinearRegression
model=LinearRegression()
model.fit(X,y)
#使用身高1.67來進行模型預測
print('預測身高為1.67米的體重為:',model.predict(np.array([1.67]).reshape(-1,1)))
復制代碼預測身高為1.67米的體重為: [[55.75685871]]#用測試集對模型整體預測
X_test=[[0.75],[1.08],[1.26],[1.51],[1.6],[1.85]]
y_predict=model.predict(X_test)
plt.plot(X,y,'k.')
plt.plot(X_test,y_predict,'g-')
#殘差
yr=model.predict(X)
for idx,x in enumerate(X):
plt.plot([x,x],[y[idx],yr[idx]],'r-')
plt.show()
復制代碼#對模型評估
y_test=[[10],[17],[27],[41],[50],[75]]
r2=model.score(X_test,y_test)
print("模型的確定系數為:",r2)
復制代碼模型的確定系數為: 0.9252812815771203進行二元回歸分析使用身高,年齡,體重數據集訓練集序號身高(cm)年齡(歲)體重(kg)114793421297233141925414511475142112661511346測試集序號身高(cm)年齡(歲)體重(kg)1149114121521237314082841381027513272161471038x_train=[[147,9],[129,7],[141,9],[145,11],[142,11],[151,13]]
y_train=[[34],[23],[25],[47],[26],[46]]
model2=LinearRegression()
model2.fit(x_train,y_train)
x_test=[[149,11],[152,12],[140,8],[138,10],[132,7],[147,10]]
Y_test=[[41],[37],[28],[27],[21],[38]]
predictions=model2.predict(x_test)
print("模型2的確定系數為:",model2.score(x_test,Y_test))
for i,prediction in enumerate(predictions):
print("預測值:{},真實值為{}".format(prediction,Y_test[i]))
復制代碼plt.title('多元回歸實際值與預測值')
plt.plot(Y_test,label='y_test')
plt.plot(predictions,label='predictions')
plt.legend()
plt.show()
復制代碼對第一個數據集增加二次項實現非線性回歸x1_train=[[0.86],[0.96],[1.12],[1.35],[1.55],[1.63],[1.71],[1.78]]
y1_train=[[12],[15],[20],[35],[48],[51],[59],[66]]
x1_test=[[0.75],[1.08],[1.26],[1.51],[1.6],[1.85]]
y1_test=[[10],[17],[27],[41],[50],[75]]
#顯示
plt = runplt()
regressor = LinearRegression()
regressor.fit(x1_train,y1_train)
xx = np.linspace(0,26,100)
yy = regressor.predict(xx.reshape(xx.shape[0],1))
plt.plot(x1_train,y1_train,'k.')
plt.plot(xx,yy)
#構建回歸函數,添加二次項
quadratic_fearurizer = PolynomialFeatures(degree=2)
X_train_quadratic = quadratic_fearurizer.fit_transform(x1_train)
X_test_quadratic = quadratic_fearurizer.transform(x1_test)
regressor_quadratic = LinearRegression()
regressor_quadratic.fit(X_train_quadratic,y1_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(x1_test,y1_test))
print('二元線性回歸r^2:%.2f'%regressor_quadratic.score(X_test_quadratic,y1_test))
復制代碼可以看出引入二次項函數擬合的更好,確定系數也增大了下面我們做個測試,看看引入更高階的項看能不能效果更好k_range = range(2,10)
k_scores = []
regressor = LinearRegression()
regressor.fit(x1_train,y1_train)
k_scores.append(regressor.score(x1_test,y1_test))
for k in k_range:
k_featurizer = PolynomialFeatures(degree=k)
x1_train_k = k_featurizer.fit_transform(x1_train)
x1_test_k = k_featurizer.transform(x1_test)
regressor_k = LinearRegression()
regressor_k.fit(x1_train_k,y1_train)
k_scores.append(regressor_k.score(x1_test_k,y1_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.廣告和銷量的多元分析
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
#導入數據
data=pd.read_csv('./Advertising.csv')
#查看數據
data.info()
data.head()
復制代碼這是一個廣告和產品銷量的數據集,TV,radio,newspaper分別代表電視,收音機,報紙三種廣告消費,sales代表產品銷售量# 切分訓練集和測試集
X=data[['TV','radio','newspaper']]
y=data['sales']
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.4,random_state=1)#訓練集測試集6,4分
linreg=LinearRegression()
model=linreg.fit(X_train,y_train)
print("參數為:",model.intercept_)
print("系數為:",model.coef_)
復制代碼#預測
y_pred=model.predict(X_test)
print("預測值為:",y_pred)
復制代碼plt.figure()
plt.plot(range(len(y_pred)),y_pred,'r',label='預測值')
plt.plot(range(len(y_pred)),y_test,'g',label='測試集真實值')
plt.legend(loc="upper right")
plt.xlabel('序號')
plt.ylabel('產品銷售')
plt.show()
復制代碼#計算擬合的均方誤差,評估模型
sum_mean=0
for i in range(len(y_pred)):
sum_mean+=(y_pred[i]-y_test.values[i])**2
sum_err=np.sqrt(sum_mean/len(y_pred))
print("模型的均方根誤差為",sum_err)
復制代碼模型的均方根誤差為 1.5635772207961516總結其實這兩次的回歸問題都是很簡單的入門問題,基本用自己寫的簡單函數就能實現,關鍵是要有從多變量轉到向量計算的思想,以及對梯度下降的理解。在機器學習,特別是深度學習中,最重要的一種思想就是向量化計算的思想,用向量計算代替傳統的循環,可以大大降低計算時間。比如代碼中最后計算均方誤差就可以用向量計算代替循環計算,只要把y_test用numpy變成ndarray形式就可以接著用向量計算。對于這個思想我昨天看到一個大佬寫的博客超贊,大家都可以去看看blog.csdn.net/TeFuirnever…我最后用到的數據集下載方式:關注、私信“111”
作者:shelgi鏈接:https://juejin.cn/post/7029231409545871391
暫時沒有評論,來搶沙發吧~