sklearn包含四種評價尺度python
1 均方差(mean-squared-error)git
2 平均絕對值偏差(mean_absolute_error)算法
3 可釋方差得分(explained_variance_score) app
4 中值絕對偏差(Median absolute error)dom
5 R2 決定係數(擬合優度)函數
- 模型越好:r2→1
- 模型越差:r2→0
在邏輯斯蒂迴歸中,咱們將會採用sigmoid函數做爲激勵函數,因此它被稱爲sigmoid迴歸或對數概率迴歸(logistic regression),須要注意的是,雖然帶有迴歸,但事實上它並非一種迴歸算法,而是一種分類算法。測試
優勢:fetch
1 它是直接對分類的可能性進行建模的,無需事先假設數據分佈,這樣就避免了假設分佈不許確所帶來的問題spa
2 其針對於分類的可能性進行建模的,因此它不只能預測出類別,還能夠獲得屬於該類別的機率code
3 實現簡單,易於理解和實現;計算代價不高,速度很快,存儲資源低
4 數據量大就用邏輯斯蒂 數據量小,特徵多,用SVM knn
缺點:
容易欠擬合,分類精度可能不高
線性迴歸與邏輯迴歸的區別
線性迴歸: 線性迴歸用來作迴歸預測,解決迴歸問題
根據幾組已知數據和擬合函數訓練其中未知參數,使得擬合損失達到最小。而後用所得擬合函數進行預測。
邏輯迴歸: 邏輯迴歸用於作二分類 , 解決分類問題
和擬合函數訓練其中未知參數 , 使得對數似然函數最大。而後用所得的擬合函數進行二分類。
線性迴歸 | 邏輯迴歸 | |
---|---|---|
目的 | 預測 | 分類 |
未知 | {0,1} | |
函數 | 擬合函數 | 預測函數 |
參數計算方式 | 最小二乘 | 最大似然估計 |
注意:
1 預測函數其實就是擬合函數作了一個邏輯函數的轉換
2 最大似然估計是計算使得數據出現的可能性最大的參數,依仗的天然是Probability。而最小二乘是計算偏差損失。所以二者不可混淆
邏輯迴歸就是對線性迴歸作了一個壓縮,將y 的值從y∈(+∞,−∞)壓縮到(0,1)。爲何簡單的壓縮就能將回歸問題變成分類問題?
從數聽說起,線性迴歸的樣本的輸出,都是連續值,y∈(+∞,−∞)而,邏輯迴歸中y∈{0,1},只能取0和1。對於擬合函數也有本質上的差異:
\[ 邏輯迴歸:f(x)=p(y=1∣x;θ)=g(θTX) \]
\[ 線性迴歸:f(x)=θTX=θ1x1+θ2x2+⋯+θnxn \]
線性迴歸擬合函數,的確是對f(x)的輸出變量y的擬合,而邏輯迴歸的擬合函數是對爲1類的樣本機率擬合。
爲何採用1類的樣本機率進行擬合,這裏就要談到logstic函數的本質
若要直接經過迴歸的方法去預測二分類問題, y 究竟是0類仍是1類,最好的函數是單位階躍函數。然而單位階躍函數不連續(GLM 的必要條件),而 logsitic 函數剛好接近於單位階躍函數,且單調可微。因而但願經過該複合函數去擬合分類問題,產生:
因而,θTX=0就至關因而1類和0類的決策邊界:
\[ 當θTX>0,則有y>0.5;若θTX→+∞ ,則y→1 ,即y 爲1類; \]
\[ 當θTX<0,則有y<0.5 ; 若θTX→−∞,則y→0,即 y 爲0類。 \]
這個時候就能看出區別來了,在線性迴歸中θTXθTX爲預測值的擬合函數;而在邏輯迴歸中θTX=0爲決策邊界
所以利用Logistics迴歸進行分類的主要思想是:根據現有數據對分類邊界線創建迴歸公式,以此進行分類。
實例: 手寫數字分類
import numpy as np import pandas as pd from pandas import Series,DataFrame import matplotlib.pyplot as plt %matplotlib inline # LogisticRegression雖然是線性迴歸模型,可是隻能處理分類問題 # 機率模型,使用機率進行分類 from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier # 加載手寫數字集 from sklearn import datasets digits = datasets.load_digits() # #輸出 {'data': array([[ 0., 0., 5., ..., 0., 0., 0.], [ 0., 0., 0., ..., 10., 0., 0.], [ 0., 0., 0., ..., 16., 9., 0.], ..., [ 0., 0., 1., ..., 6., 0., 0.], [ 0., 0., 2., ..., 12., 0., 0.], [ 0., 0., 10., ..., 12., 1., 0.]]), 'target': array([0, 1, 2, ..., 8, 9, 8]), 'target_names': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), 'images': array([[[ 0., 0., 5., ..., 1., 0., 0.], [ 0., 0., 13., ..., 15., 5., 0.], ....
data = digits.data #(1797, 64) 表示1797條,一維64的矩陣 images = digits.images #(1797, 8, 8) 表示1797條,8*8的二維矩陣 display(data.shape,images.shape) plt.imshow(images[0],cmap='gray') plt.imshow(data[0].reshape((8,8)),cmap='gray') #將64一維轉成8*8的二維矩陣實際都是表示一組數據
# 對數據集進行拆分,獲得訓練集和測試集 from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.2,random_state=1) #採用邏輯斯蒂迴歸模型與KNN logistic = LogisticRegression() knn = KNeighborsClassifier(n_neighbors=5) #對knn與邏輯斯蒂進行訓練 logistic.fit(X_train,y_train) y1_ = logistic.predict(X_test) knn.fit(X_train,y_train) y2_ = knn.predict(X_test)
查看模型評分
# 分類模型能夠查看準確率來對模型進行評價 # 直接用算法模型調用score方法來實現 logistic.score(X_test,y_test) knn.score(X_test,y_test) #輸出 0.9694444444444444 0.9944444444444445 # 模型在測試集上評分特別高,可是在真實環境下準確率卻很低,這叫病態 # 引發這種現象的緣由,主要是算法訓練的過分擬合
分類展現
# 展現分類的成果 # 取測試集的前100個數據 plt.figure(figsize=(12,16)) for i in range(100): axes = plt.subplot(10,10,i+1) img = X_test[i].reshape((8,8)) axes.imshow(img,cmap='gray') axes.axis('off') true = y_test[i] knn_r = y2_[i] logistic_r = y1_[i] title = 'T:'+str(true)+'\nK:'+str(knn_r) + ' L:'+str(logistic_r) axes.set_title(title)
# 對logistic函數進行調參,查看參數對結果的影響 # 超參 函數級別 knn n_neibors logistic pentily C # 模型參數 f(x) = wx+b logistic = LogisticRegression(C=0.5,penalty='l1') logistic.fit(X_train,y_train) logistic.score(X_test,y_test) #0.975
人臉的自動補全
導包
import numpy as np import pandas as pd from pandas import Series,DataFrame from sklearn.datasets import fetch_olivetti_faces import matplotlib.pyplot as plt %matplotlib inline
提取數據
faces = fetch_olivetti_faces() data = faces.data images = faces.images target = faces.target
拆分測試訓練集
from sklearn.linear_model import LinearRegression,Ridge,Lasso from sklearn.neighbors import KNeighborsRegressor # 拆分訓練集和測試集 from sklearn.model_selection import train_test_split # 每一個人拿出9張照片作訓練數據,拿出1張照片作測試數據 # 樣本特徵採用上半邊臉,樣本標籤採用下半邊臉 def train_test_split_face(data,test_size): X_train = [] X_test = [] y_train = [] y_test = [] for i in range(40): for j in range(10): face = data[i*10+j] up_face = face[:2048] bottom_face = face[2048:] if j < (1-test_size)*10: # 保存爲訓練數據 X_train.append(up_face) y_train.append(bottom_face) else: # 保存爲測試數據 X_test.append(up_face) y_test.append(bottom_face) return np.array(X_train),np.array(X_test),np.array(y_train),np.array(y_test) #訓練集與測試集 X_train,X_test,y_train,y_test = train_test_split_face(data,test_size=0.1) #拆分出的上下半邊臉 plt.imshow(X_train[0].reshape((32,64)),cmap='gray') plt.imshow(y_train[0].reshape((32,64)),cmap='gray')
訓練模型
knn = KNeighborsRegressor() linear = LinearRegression() ridge = Ridge() lasso = Lasso() knn.fit(X_train,y_train) linear.fit(X_train,y_train) ridge.fit(X_train,y_train) lasso.fit(X_train,y_train)
預測數據
# 預測全部數據 knn_y_ = knn.predict(X_test) linear_y_ = linear.predict(X_test) ridge_y_ = ridge.predict(X_test) lasso_y_ = lasso.predict(X_test) plt.figure(figsize=(10,4)) true_up_face = X_test[0] true_bottom_face = y_test[0] pre_bottom_face = knn_y_[0] axes1 = plt.subplot(1,2,1) true_face = np.concatenate((true_up_face,true_bottom_face)) axes1.imshow(true_face.reshape((64,64)),cmap='gray') axes1.set_title('True') axes2 = plt.subplot(1,2,2) pre_face = np.concatenate((true_up_face,pre_bottom_face)) axes2.imshow(pre_face.reshape((64,64)),cmap='gray') axes2.set_title('Predict') results = np.array([knn_y_,ridge_y_,lasso_y_,linear_y_]) titles = np.array(['KNN','RIDGE','LASSO','LINEAR']) plt.figure(figsize=(16,18)) for i in range(5): true_up_face = X_test[i] true_bottom_face = y_test[i] true_face = np.concatenate((true_up_face,true_bottom_face)).reshape((64,64)) axes = plt.subplot(5,5,i*5+1) axes.imshow(true_face,cmap='gray') axes.set_title('True') for index,y_ in enumerate(results): axes = plt.subplot(5,5,i*5+1+index+1) pre_bottom_face = y_[index] pre_face = np.concatenate((true_up_face,pre_bottom_face)).reshape((64,64)) axes.imshow(pre_face,cmap='gray') axes.set_title(titles[index])
數據量較少,僅爲測試使用