【机器学习】快速入门简单线性回归 (SLR)
簡單線性回歸圖(青色散點為實際值,紅線為預測值)
statsmodels.api、statsmodels.formula.api 和 scikit-learn 的 Python 中的 SLR
今天云朵君將和大家一起學習回歸算法的基礎知識。并取一個樣本數據集,進行探索性數據分析(EDA)并使用 statsmodels.api、statsmodels.formula.api 和 scikit-learn 實現 簡單線性回歸(SLR)。
什么是回歸算法
回歸是一種用于預測連續特征的"監督機器學習"算法。
線性回歸是最簡單的回歸算法,它試圖通過將線性方程/最佳擬合線擬合到觀察數據,來模擬因變量與一個或多個自變量之間的關系。
根據輸入特征的數量,線性回歸可以有兩種類型:
簡單線性回歸 (SLR)
多元線性回歸 (MLR)
在簡單線性回歸 (SLR) 中,根據單一的輸入變量預測輸出變量。在多元線性回歸 (MLR) 中,根據多個輸入變量預測輸出。
輸入變量也可以稱為獨立/預測變量,輸出變量稱為因變量。
SLR 的方程為,其中, 是因變量, 是預測變量, 是模型的系數/參數,Epsilon(?) 是一個稱為誤差項的隨機變量。
普通最小二乘法(OLS)和梯度下降是兩種常見的算法,用于為最小平方誤差總和找到正確的系數。
如何實現回歸算法
目標:建立一個簡單的線性回歸模型,使用多年的經驗來預測加薪。
首先導入必要的庫
這里必要的庫是 Pandas、用于處理數據框的 NumPy、用于可視化的 matplotlib、seaborn,以及用于構建回歸模型的 sklearn、statsmodels。
import?pandas?as?pd? import?numpy?as?np import?matplotlib.pyplot?as?plt %matplotlib?inline import?seaborn?as?sns from?scipy?import?stats from?scipy.stats?import?probplot import?statsmodels.api?as?sm? import?statsmodels.formula.api?as?smf? from?sklearn?import?preprocessing from?sklearn.linear_model?import?LinearRegression from?sklearn.model_selection?import?train_test_split from?sklearn.metrics?import?mean_squared_error,?r2_score從 CSV 文件創建 Pandas 數據框。數據獲取:在公眾號『數據STUDIO』后臺聯系云朵君獲取!
df?=?pd.read_csv("Salary_Data.csv")探索性數據分析(EDA)
EDA的基本步驟
了解數據集
確定數據集的大小
確定特征的數量
識別特征及特征的數據類型
檢查數據集是否有缺失值、異常值
通過特征的缺失值、異常值的數量
處理缺失值和異常值
編碼分類變量
圖形單變量分析,雙變量
規范化和縮放
數據集有兩列:YearsExperience、Salary。并且兩者都是浮點數據類型。數據集中有 30 條記錄,沒有空值或異常值。
描述性統計包括那些總結數據集分布的集中趨勢、分散和形狀的統計,不包括NaN值
df.describe()圖形單變量分析
對于單變量分析,可以使用直方圖、密度圖、箱線圖或小提琴圖,以及正態 QQ 圖來幫助我們了解數據點的分布和異常值的存在。
小提琴圖是一種繪制數字數據的方法。它類似于箱線圖,但在每一側都添加了一個旋轉的核密度圖。
Python代碼:
#?Histogram #?We?can?use?either?plt.hist?or?sns.histplot plt.figure(figsize=(20,10)) plt.subplot(2,4,1) plt.hist(df['YearsExperience'],?density=False) plt.title("Histogram?of?'YearsExperience'") plt.subplot(2,4,5) plt.hist(df['Salary'],?density=False) plt.title("Histogram?of?'Salary'")#?Density?plot plt.subplot(2,4,2) sns.distplot(df['YearsExperience'],?kde=True) plt.title("Density?distribution?of?'YearsExperience'") plt.subplot(2,4,6) sns.distplot(df['Salary'],?kde=True) plt.title("Density?distribution?of?'Salary'")#?boxplot?or?violin?plot #?小提琴圖是一種繪制數字數據的方法。 #?它類似于箱形圖,在每一邊添加了一個旋轉的核密度圖 plt.subplot(2,4,3) #?plt.boxplot(df['YearsExperience']) sns.violinplot(df['YearsExperience']) #?plt.title("Boxlpot?of?'YearsExperience'") plt.title("Violin?plot?of?'YearsExperience'") plt.subplot(2,4,7) #?plt.boxplot(df['Salary']) sns.violinplot(df['Salary']) #?plt.title("Boxlpot?of?'Salary'") plt.title("Violin?plot?of?'Salary'")#?Normal?Q-Q?plot plt.subplot(2,4,4) probplot(df['YearsExperience'],?plot=plt) plt.title("Q-Q?plot?of?'YearsExperience'") plt.subplot(2,4,8) probplot(df['Salary'],?plot=plt) plt.title("Q-Q?plot?of?'Salary'")單變量圖形表示從上面的圖形表示,我們可以說我們的數據中沒有異常值,并且 YearsExperience looks like normally distributed, and Salary doesn't look normal。我們可以使用Shapiro Test。
Python代碼:
#?定義一個函數進行?Shapiro?test#?定義零備擇假設 Ho?=?'Data?is?Normal' Ha?=?'Data?is?not?Normal'#?定義重要度值 alpha?=?0.05 def?normality_check(df):for?columnName,?columnData?in?df.iteritems():print("Shapiro?test?for?{columnName}".format(columnName=columnName))res?=?stats.shapiro(columnData)#?print(res)pValue?=?round(res[1],?2)#?Writing?conditionif?pValue?>?alpha:print("pvalue?=?{pValue}?>?{alpha}.?不能拒絕零假設.?{Ho}".format(pValue=pValue,?alpha=alpha,?Ho=Ho))else:print("pvalue?=?{pValue}?<=?{alpha}.?拒絕零假設.?{Ha}".format(pValue=pValue,?alpha=alpha,?Ha=Ha))#?Drive?code normality_check(df)Shapiro test for YearsExperience pvalue = 0.1 > 0.05. 不能拒絕零假設. Data is Normal Shapiro test for Salary pvalue = 0.02 <= 0.05. 拒絕零假設. Data is not NormalYearsExperience 是正態分布的,Salary 不是正態分布的。
雙變量可視化
對于數值與數值數據,我們繪制:散點圖、線圖、相關性熱圖、聯合圖來進行數據探索。
Python 代碼:
#?Scatterplot?&?Line?plots plt.figure(figsize=(20,10)) plt.subplot(1,3,1) sns.scatterplot(data=df,?x="YearsExperience",?y="Salary",?hue="YearsExperience",alpha=0.6) plt.title("Scatter?plot") plt.subplot(1,3,2) sns.lineplot(data=df,?x="YearsExperience",?y="Salary") plt.title("Line?plot?of?YearsExperience,?Salary") plt.subplot(1,3,3) sns.lineplot(data=df) plt.title('Line?Plot')雙變量可視化散點圖和線圖
#?heatmap plt.figure(figsize=(10,?10)) plt.subplot(1,?2,?1) sns.heatmap(data=df,?cmap="YlGnBu",?annot?=?True) plt.title("Heatmap?using?seaborn") plt.subplot(1,?2,?2) plt.imshow(df,?cmap?="YlGnBu") plt.title("Heatmap?using?matplotlib")熱圖#?Joint?plot sns.jointplot(x?=?"YearsExperience",?y?=?"Salary",?kind?=?"reg",?data?=?df) plt.title("Joint?plot?using?sns") #?類型可以是hex, kde, scatter, reg, hist。當kind='reg'時,它顯示最佳擬合線。使用 df.corr() 檢查變量之間是否存在相關性。
print("Correlation:?"+?'n',?df.corr())? #?0.978,高度正相關 #?繪制相關矩陣的熱圖 plt.subplot(1,1,1) sns.heatmap(df.corr(),?annot=True)Correlation: YearsExperience Salary YearsExperience 1.000000 0.978242 Salary 0.978242 1.000000相關矩陣的熱圖相關性=0.98,這是一個高正相關性。這意味著因變量隨著自變量的增加而增加。
數據標準化
YearsExperience 和 Salary 列的值之間存在巨大差異??梢允褂肗ormalization更改數據集中數字列的值以使用通用比例,而不會扭曲值范圍的差異或丟失信息。
我們使用sklearn.preprocessing.Normalize用來規范化我們的數據。它返回 0 到 1 之間的值。
#?創建新列來存儲規范化值 df['Norm_YearsExp']?=?preprocessing.normalize(df[['YearsExperience']],?axis=0) df['Norm_Salary']?=?preprocessing.normalize(df[['Salary']],?axis=0) df.head()使用 sklearn 進行線性回歸
LinearRegression() 擬合一個系數為的線性模型,以最小化數據集中觀察到的目標與線性近似預測的目標之間的殘差平方和。
def?regression(df):#?定義獨立和依賴的特性x?=?df.iloc[:,?1:2]y?=?df.iloc[:,?0:1]?#?print(x,y)#?實例化線性回歸對象regressor?=?LinearRegression()#?訓練模型regressor.fit(x,y)#?檢查每個預測模型的系數print('n'+"Coeff?of?the?predictor:?",regressor.coef_)#?檢查截距項print("Intercept:?",regressor.intercept_)#?預測輸出值y_pred?=?regressor.predict(x) #?????print(y_pred)#?檢查?MSEprint("Mean?squared?error(MSE):?%.2f"?%?mean_squared_error(y,?y_pred))#?Checking?the?R2?valueprint("Coefficient?of?determination:?%.3f"?%?r2_score(y,?y_pred))?#?評估模型的性能,表示大部分數據點落在最佳擬合線上#?可視化結果plt.figure(figsize=(18,?10))#?輸入和輸出值的散點圖plt.scatter(x,?y,?color='teal')#?輸入和預測輸出值的繪圖plt.plot(x,?regressor.predict(x),?color='Red',?linewidth=2?)plt.title('Simple?Linear?Regression')plt.xlabel('YearExperience')plt.ylabel('Salary')#?Driver?code regression(df[['Salary',?'YearsExperience']])?#?0.957?accuracy regression(df[['Norm_Salary',?'Norm_YearsExp']])?#?0.957?accuracyCoeff of the predictor: [[9449.96232146]] Intercept: [25792.20019867] Mean squared error(MSE): 31270951.72 Coefficient of determination: 0.957Coeff of the predictor: [[0.70327706]] Intercept: [0.05839456] Mean squared error(MSE): 0.00 Coefficient of determination: 0.957使用 scikit-learn 中線性回歸模型實現了 95.7% 的準確率,但在深入了解該模型中特征的相關性方面并沒有太多空間。接下來使用 statsmodels.api, statsmodels.formula.api 構建一個模型。
使用 smf 的線性回歸
statsmodels.formula.api 中的預測變量必須單獨枚舉。該方法中,一個常量會自動添加到數據中。
def?smf_ols(df):#?定義獨立和依賴的特性x?=?df.iloc[:,?1:2]y?=?df.iloc[:,?0:1]? #?????print(x)#?訓練模型model?=?smf.ols('y~x',?data=df).fit()#?print?model?summaryprint(model.summary())#?預測?yy_pred?=?model.predict(x) #?????print(type(y),?type(y_pred)) #?????print(y,?y_pred)y_lst?=?y.Salary.values.tolist() #?????y_lst?=?y.iloc[:,?-1:].values.tolist()y_pred_lst?=?y_pred.tolist()???? #?????print(y_lst)data?=?[y_lst,?y_pred_lst] #?????print(data)res?=?pd.DataFrame({'Actuals':data[0],?'Predicted':data[1]}) #?????print(res)plt.scatter(x=res['Actuals'],?y=res['Predicted'])plt.ylabel('Predicted')plt.xlabel('Actuals')res.plot(kind='bar',figsize=(10,6))#?Driver?code smf_ols(df[['Salary',?'YearsExperience']])?#?0.957?accuracy #?smf_ols(df[['Norm_Salary',?'Norm_YearsExp']])?#?0.957?accuracy實際值與預測值的條形圖使用 statsmodels.api 進行回歸
不再需要單獨枚舉預測變量。
statsmodels.regression.linear_model.OLS(endog, exog)
endog 是因變量
exog是自變量。默認情況下不包含截距項,應由用戶使用 add_constant添加。
該模型達到了 95.7% 的準確率,這是相當不錯的。
如何讀懂 model summary
理解回歸模型model summary表中的某些術語總是很重要的,這樣我們才能了解模型的性能和輸入變量的相關性。
應考慮的一些重要參數是 Adj. R-squared。R-squared,F-statistic,Prob(F-statistic),Intercept和輸入變量的coef,P>|t|。
R-Squared是決定系數。一種統計方法,它表示有很大百分比的數據點落在最佳擬合線上。為使模型擬合良好,r2值接近1是預期的。
Adj. R-squared 如果我們不斷添加對模型預測沒有貢獻的新特征,R-squared 會懲罰 R-squared 值。如果Adj. R-squared<R-Squared,則表明模型中存在無關預測因子。
F-statistic 或者 F-test 幫助我們接受或拒絕零假設。它將僅截取模型與我們的具有特征的模型進行比較。零假設是"所有回歸系數都等于 0,這意味著兩個模型都相等"。替代假設是“攔截唯一比我們的模型差的模型,這意味著我們添加的系數提高了模型性能。如果 prob(F-statistic) < 0.05 并且 F-statistic 是一個高值,我們拒絕零假設。它表示輸入變量和輸出變量之間存在良好的關系。
coef 系數表示相應輸入特征的估計系數
T-test單獨討論輸出與每個輸入變量之間的關系。零假設是“輸入特征的系數為 0”。替代假設是“輸入特征的系數不為 0”。如果 pvalue < 0.05,我們拒絕原假設,這表明輸入變量和輸出變量之間存在良好的關系。我們可以消除 pvalue > 0.05 的變量。
到這里,我們應該知道如何從model summary表中得出重要的推論了,那么現在看看模型參數并評估我們的模型。
在本例子中
R-Squared(0.957) 接近 Adj. R-squared ?(0.955) 是輸入特征對預測模型有貢獻的好兆頭。
F-statistic 是一個很大的數字,P(F-statistic) 幾乎為 0,這意味著我們的模型比唯一的截距模型要好。
輸入變量t-test的pvalue小于0.05,所以輸入變量和輸出變量有很好的關系。
因此,我們得出結論說該模型效果良好!
到這里,本文就結束啦。今天和作者一起學習了簡單線性回歸 (SLR) 的基礎知識,使用不同的 Python 庫構建線性模型,并從 OLS statsmodels 的model summary表中得出重要推論。
往期精彩回顧適合初學者入門人工智能的路線及資料下載(圖文+視頻)機器學習入門系列下載中國大學慕課《機器學習》(黃海廣主講)機器學習及深度學習筆記等資料打印《統計學習方法》的代碼復現專輯 AI基礎下載機器學習交流qq群955171419,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【机器学习】快速入门简单线性回归 (SLR)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 伪类::selection自定义文本选中
- 下一篇: IP 基础知识“全家桶”,45 张图一套