python學習筆記39:sklearn


from sklearn import datasets
from sklearn.model_selection import train_test_split  # 訓練集和測試集
from sklearn.neighbors import KNeighborsClassifier # k-means分類

iris = datasets.load_iris() # 加載數據集
# iris 查看iris數據信息
iris_X = iris.data  # iris出來是一個字典,可以用.的方式獲取對應的values
# iris_X
iris_y = iris.target # 目標變量
# iris_y
# 將數據集拆分為訓練集和測試集,測試集占30%
X_train,X_test,y_train,y_test = train_test_split(iris_X,iris_y,test_size=0.3)
print(y_test)
[1 0 0 0 2 0 1 1 0 0 1 1 2 1 2 2 0 1 2 1 2 2 0 0 1 1 2 1 2 1 0 0 2 0 1 1 0
 0 1 2 2 0 1 2 2]
knn = KNeighborsClassifier() # 引入實例
knn.fit(X_train,y_train)     # 訓練模型
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=None, n_neighbors=5, p=2,
           weights='uniform')
# 測試模型
y_pred = knn.predict(X_test)
y_pred
array([1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 2, 1, 1, 2, 0, 1, 2, 1, 2, 2,
       0, 0, 1, 1, 2, 1, 2, 1, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 2, 0, 1, 2,
       2])
# 把測試結果寫會csv
# 生成id
ind = []
for i in range(len(y_pred)):
    ind.append(i+1)
    
import pandas as pd
dic = {'id':ind,'pred':y_pred}
test_pred = pd.DataFrame(dic)
test_pred.to_csv('knn_test_pred.csv',index=False)
%matplotlib inline

sklean 進行數據展示

from sklearn import datasets
X,y = datasets.make_regression(n_samples=100,n_features=1,n_targets=1,noise=1)

import matplotlib.pyplot as plt
plt.figure()
plt.scatter(X,y,marker='.')
plt.show()

sklearn model中的屬性

from sklearn import datasets
from sklearn.linear_model import LinearRegression

load_data = datasets.load_boston()
data_X = load_data.data
data_y = load_data.target
print(data_X.shape)
(506, 13)
lr_model = LinearRegression()
lr_model.fit(data_X,data_y)
lr_model.predict(data_X[:4,:])
array([30.00384338, 25.02556238, 30.56759672, 28.60703649])
print(lr_model.coef_) # 擬合直線的系數
print(lr_model.intercept_) # 截距
print(lr_model.get_params) # 參數

[-1.08011358e-01  4.64204584e-02  2.05586264e-02  2.68673382e+00
 -1.77666112e+01  3.80986521e+00  6.92224640e-04 -1.47556685e+00
  3.06049479e-01 -1.23345939e-02 -9.52747232e-01  9.31168327e-03
 -5.24758378e-01]
36.459488385089855
<bound method BaseEstimator.get_params of LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
         normalize=False)>

數據標准化

許多學習算法中目標函數的基礎都是假設所有的特征都是零均值並且具有同一階數上的方差(比如徑向基函數,支持向量機以及L1L2正則化項等)。如果某個特征的方差比其他特征大幾個數量級,那么他就會在學習算法中占據主導位置,導致學習器對其他特征有所忽略。
標准化先對數據進行中心化,再除以特征的標准差進行縮放。
在sklearn中,我們可以通過Scale將數據縮放,達到標准化的目的。

from sklearn import preprocessing
import numpy as np

data = np.array([[12,92,3],[2,3,4],[3,4,5]],dtype=np.float64)
print('標准化前:',data)
print('標准化后:',preprocessing.scale(data))
標准化前: [[12. 92.  3.]
 [ 2.  3.  4.]
 [ 3.  4.  5.]]
標准化后: [[ 1.4083737   1.41414586 -1.22474487]
 [-0.81537425 -0.71905721  0.        ]
 [-0.59299945 -0.69508864  1.22474487]]
from sklearn import datasets
from sklearn.model_selection import train_test_split 
from sklearn.datasets.samples_generator import make_classification 
from sklearn.svm import SVC
import matplotlib.pyplot as plt

# 生成數據並進行可視化
plt.figure()
X,y = make_classification(n_samples=300,n_features=2,n_redundant=0,n_informative=2,random_state=22,n_clusters_per_class=1,scale=100)
plt.scatter(X[:,0],X[:,1],c=y) # X的第0列和第1列畫散點圖,用y做顏色區分
plt.show()

# 未標准化
X_pre = X
y_pre = y
X_train_pre,X_test_pre,y_train_pre,y_test_pre = train_test_split(X_pre,y_pre,test_size=0.3)
clf = SVC()
clf.fit(X_train_pre,y_train_pre)
clf.score(X_test_pre,y_test_pre)
/Users/zxx/anaconda3/lib/python3.7/site-packages/sklearn/svm/base.py:196: FutureWarning: The default value of gamma will change from 'auto' to 'scale' in version 0.22 to account better for unscaled features. Set gamma explicitly to 'auto' or 'scale' to avoid this warning.
  "avoid this warning.", FutureWarning)





0.4444444444444444
# 標准化
X_pre = preprocessing.minmax_scale(X)
y_pre = y
X_train,X_test,y_train,y_test = train_test_split(X_pre,y_pre,test_size=0.3)
clf = SVC()
clf.fit(X_train,y_train)
clf.score(X_test,y_test)
/Users/zxx/anaconda3/lib/python3.7/site-packages/sklearn/svm/base.py:196: FutureWarning: The default value of gamma will change from 'auto' to 'scale' in version 0.22 to account better for unscaled features. Set gamma explicitly to 'auto' or 'scale' to avoid this warning.
  "avoid this warning.", FutureWarning)





0.9333333333333333

可以看到數據規范化之前模型分數為0.52222,數據規范化之后模型分數為0.91111

交叉驗證

交叉驗證的思想就是重復的使用數據,把得到的樣本數據進行切分,組合成為不同的訓練集和驗證集,用訓練集來訓練模型,用驗證集評估模型預測的好壞。

(1)簡單的交叉驗證:

隨機的將樣本數據分為兩部分(如70%訓練,30%測試),然后用訓練集來訓練模型,在驗證集上驗證模型及參數;接着再把樣本打亂,重新選擇訓練集和驗證集,重新訓練驗證,最后選擇損失函數評估最優的模型和參數。

(2)k折交叉驗證:

隨機將樣本數均分為K份,每次隨機選擇其中的k-1份作為訓練集,剩下的1份做驗證集。當這一輪完成后,重新隨機選擇k-1份來訓練數據,若干輪后選擇損失函數評估最優的模型和參數。

(3)留一交叉驗證:

留一交叉驗證是k折交叉驗證的一種特例,此時k=n(樣本的個數),每次選擇n-1個樣本進行訓練,留一個樣本進行驗證模型的好壞。
這種方法適合樣本量非常少的情況。

(4)Boostrapping自助采樣法:

這種方法也是隨機森林訓練樣本采用的方法。
在n個樣本中隨機有放回抽樣m個樣本作為一顆樹的一個訓練集,這種采用會大約有1/3的樣本不被采到,這些不被采到的樣本就會被作為這棵樹的驗證集。

如果只是對數據做一個初步的模型建立,不需要做深入分析的話,簡單的交叉驗證就可以了,否則使用k折交叉驗證,在樣本量很小時,可以選擇使用留一法。
總之,所有的東西不是一成不變的,大家在遇到具體問題的時候,可以所有方式都嘗試一下,看看效果,根據具體問題選擇合適的方法

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier 
from sklearn.model_selection import cross_val_score # 交叉驗證

iris = datasets.load_iris()
X = iris.data
y = iris.target

# 拆分數據集
# X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3) 使用交叉驗證不需要拆分

knn = KNeighborsClassifier(n_neighbors=5)
scores = cross_val_score(knn,X,y,cv=5,scoring='accuracy')
print(scores)
print(scores.mean())

[0.96666667 1.         0.93333333 0.96666667 1.        ]
0.9733333333333334
from sklearn import datasets
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt

iris = datasets.load_iris()
X = iris.data
y = iris.target

# 調整模型參數
k_range = range(1,31)
k_score = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn,X,y,cv=5,scoring='accuracy')  # 5折交叉驗證
    k_score.append(scores.mean())

plt.figure()
plt.plot(k_range,k_score)
plt.xlabel('value of k for knn')
plt.ylabel('cross accuracy')
plt.show()

另外我們可以選擇2-fold cross validation,leave-one-out cross validation等方法來分割數據,比較不同的方法和參數得到最優結果。

8.過擬合問題

過擬合的問題是因為模型過於復雜,對於訓練數據能很好的擬合,卻不能正確的處理測試數據,從一個角度說就是,學到了一些樣本數據一些非通用信息。使得模型的泛化效果非常不好。

#先距離如何辨別overfitting問題
#Sklearn.learning_curve中的learning curve可以直觀的看出模型學習的進度,對比發現有沒有過擬合。
from sklearn.model_selection import learning_curve # 學習曲線
from sklearn.datasets import load_digits
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

# load data
digits = load_digits()
X = digits.data
y = digits.target

# 設置記錄點
train_size,train_loss,test_loss = learning_curve(SVC(gamma=0.1),X,y,cv=10,scoring='neg_mean_squared_error',train_sizes = np.arange(0.05,1.05,0.05))
train_loss_mean = -np.mean(train_loss,axis=1)
test_loss_mean = -np.mean(test_loss,axis=1)

# 畫圖
plt.figure()
plt.plot(train_size,train_loss_mean,'go--',label='Training')
plt.plot(train_size,test_loss_mean,'ro--',label='Cross-validataion')
plt.legend(loc = 'best')
plt.show()




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM