sklearn学习(一)
學習網站
http://scikit-learn.org/stable/tutorial/basic/tutorial.html#machine-learning-the-problem-setting
內容
一般來說,學習問題可以被分為幾大類:
- 監督學習(supervised learing)。數據包括一些我們可以預測的屬性。
- 非監督學習(unsupervised learning)。數據有一堆輸入向量,但是沒有給輸出的目標值。
監督學習分為:
- 分類(classification):當樣本屬于兩個或者更多的數據的時候,我們可以通過學習一些貼好標簽的數據,然后去預測一些沒有給出標簽的數據。(離散問題(discrete))
- 回歸(regression):當希望預測的結果是一個或者多個連續的變量的時候,這就是回歸。
非監督學習分為:
- 聚類(clustering):目標去發現一些有相似特征的類。
- 密度估計(Density estimation):描述一些輸入數據的特征信息
- 數據降維:將高維數據降維到低維數據
一般將數據集分為訓練集和測試集
sklearn內有一些標準數據,例如:iris(鳶尾花),手寫數字數據為了分類,然后,還有波斯頓房價數據為了回歸。
以導入iris數據為例
導入數據:
from sklearn import datasets iris = datasets.load_iris()數據集是有點像字典的類。包括一些數據,還有元數據。這些數據被存在.data中。內容是一個n個例子,還有n個特征的array。在監督學習的問題中,一個或者是更多的響應數據被存.target中。
關于數據的操作具體的可以在下面的網址中找到。
http://scikit-learn.org/stable/datasets/index.html#datasets
關于上面的.data和.target是什么意思:
例如:
print(iris.data)輸出:(數據較多,就截取一部分)
[[5.1 3.5 1.4 0.2][4.9 3. 1.4 0.2][4.7 3.2 1.3 0.2][4.6 3.1 1.5 0.2]...[6.3 2.5 5. 1.9][6.5 3. 5.2 2. ][6.2 3.4 5.4 2.3][5.9 3. 5.1 1.8]] print(iris.target)輸出:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 22 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 22 2]學習和預測
在數字數據集中,任務是預測一個圖片,然后給出預測的數字。數字集合包括有0到9。
在sklearn中,對于分類器的估計是一個python類。實現了兩個方法fit(X,y)和predict(T)
一個估計類的例子的sklearn.svm.SVC是實現了支持向量機的分類器。分類器的構造函數會需要一些參數(我們稱之為超參數)。從現在起,我們認為這個評估器,就是一個黑盒子。
from sklearn import svm clf = svm.SVC(gamma=0.001, C=100.)這里,我們給的時候是給了固定的參數,但是還有兩種設置參數的方式。
grid-search http://scikit-learn.org/stable/modules/grid_search.html#grid-search
cross-validation http://scikit-learn.org/stable/modules/cross_validation.html#cross-validation
我們稱評估器為clf,因為它是一個分類器。它必須要從模型中學習。這項被完成是通過fit方法。
數字預測代碼
from sklearn import svm from sklearn import datasetsdigits = datasets.load_digits() clf = svm.SVC(gamma=0.001, C=100.) clf.fit(digits.data[:-1], digits.target[:-1]) print("pridict:", clf.predict(digits.data[-1:])) print("actually:", digits.target[-1:])輸出:
pridict: [8] actually: [8]注意:
選最后一個數據的時候要 digits.data[-1:] 這樣方式。主要是為了使得在外面包一層,因為測試數據可能不止一個。所以,當必須要以集合的形式傳進去。否者就會報下面的錯誤。
可以來看下到底最后一個數據是怎么樣的:
其實確實有點像是8。
plt語句的最后一個參數含義是為了將這個變成灰色。否則顏色有點奇怪。
代碼:
from sklearn import svm from sklearn import datasets import matplotlib.pyplot as pltdigits = datasets.load_digits() clf = svm.SVC(gamma=0.001, C=100.) clf.fit(digits.data[:-1], digits.target[:-1]) print("pridict:", clf.predict(digits.data[-1:])) print("actually:", digits.target[-1:])plt.imshow(digits.images[-1], cmap=plt.cm.gray_r) # 變灰色plt.show()模型可持續性
相信很多哥們都遇到這樣的問題,訓練一個模型需要很久的時間,但是如果,一開始就已經有了這樣的模型之后,以后就直接調用,豈不是美滋滋?所以,python原生的這樣的操作。
pickle庫
from sklearn import svm from sklearn import datasets import pickledigits = datasets.load_digits() clf = svm.SVC(gamma=0.001, C=100.) clf.fit(digits.data[:-1], digits.target[:-1]) print("pridict:", clf.predict(digits.data[-1:])) print("actually:", digits.target[-1:])s = pickle.dumps(clf)clf2 = pickle.loads(s)print(clf2.predict(digits.data[-1:]))輸出為;
pridict: [8] actually: [8] [8]當然是可以保存為文件類型:
with open('clf', 'wb') as f:pickle.dump(clf, f)with open('clf', 'rb') as f:clf2 = pickle.load(f)print(clf2.predict(digits.data[-1:]))用上面的代碼來替換掉之前的 dumps還有loads也是可以。
當然,這樣就在代碼上多出一個這樣的文件。不過可以被移植了,算是一個優點。
其實文件取什么名字都沒有什么多大意義的。當然啦,選什么類型這種東西,對于程序員來說也是這樣的,因為本質上都是二進制文件。
在sklearn中,除了python原生的pickle可以使用,還可以使用sklearn自帶的joblib
joblib.dump(clf, 'clf2') clf2 = joblib.load('clf2') print(clf2.predict(digits.data[-1:]))用這個代碼代替之前的那段代碼也是可以的。
而且, joblib對于處理大數據的時候會比pickle更有效(不過我還沒有試過)。不過至少,我覺得寫起來效率會比pickle更高。但是,就是沒有在代碼間的那種先放著,然后之后再做處理的操作。(雖然我目前還沒意識到,為什么需要有這種操作。。。)
但是學好pickle也是很重要的,因為基本所有的數據都是可以用這個來做。在python上的課擴展性會更強點。
sklearn使用公約
類型轉變:
除非特殊情況,否則,輸入轉變到float64
重新fit和更新超參數(Hyper-parameters)
- 超參數可以被更新,通過sklearn.pipeline.Pipeline.set_params方法。
- 只需要再調用一次fit之后,就會覆蓋掉之前學習的效果。
比如下面的代碼:
import numpy as np from sklearn.svm import SVCrng = np.random.RandomState(0) X = rng.rand(100, 10) y = rng.binomial(1, 0.5, 100) X_test = rng.rand(5, 10) clf = SVC() clf.set_params(kernel='linear').fit(X, y) print(clf.predict(X_test)) clf.set_params(kernel='rbf').fit(X, y) print(clf.predict(X_test))輸出是:
[1 0 1 1 0] [0 0 0 1 0]注意到,分類器這里重新設置了SVC的核函數。當然,設置了不同的核函數之后,最后的預測效果也不一樣了。
不過考慮到,這是因為數據本身就是隨機出來的效果。所以,在這里本身蘊含的信息就是一個混亂的。所以,根據不同的核函數的時候,就導致了很大的誤差。實際應用中的效果應該是,就算是有效果,但是效果也不應該是這么明顯的。
Multiclass vs. multilabel fitting
采用multiclass 中的分類器,學習和預測任務,是依賴于fit的時候的目標類型。
例如下面的這個代碼:
from sklearn.svm import SVC from sklearn.multiclass import OneVsRestClassifier from sklearn.preprocessing import LabelBinarizerX = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]] y = [0, 0, 1, 1, 2]classif = OneVsRestClassifier(estimator=SVC(random_state=0)) print(classif.fit(X, y).predict(X))# 數據二進制化 y = LabelBinarizer().fit_transform(y) print(classif.fit(X, y).predict(X))輸出:
[0 0 1 1 2] [[1 0 0][1 0 0][0 1 0][0 0 0][0 0 0]]但是y的被轉變之后的數據是
[[1 0 0][1 0 0][0 1 0][0 1 0][0 0 1]]注意到后面兩行的數據是不一樣的,都是全0,表示的是,沒有一個匹配到。
但是,如果是多個標簽的情況下:
比如說,下面的這個y就是一個多標簽的問題。
后面的輸出矩陣,其實就轉換成了一個bool值問題。即表示某個元素存在與否。
from sklearn.svm import SVC from sklearn.multiclass import OneVsRestClassifier from sklearn.preprocessing import MultiLabelBinarizer X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]] y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]classif = OneVsRestClassifier(estimator=SVC(random_state=0)) # 數據二進制化 y = MultiLabelBinarizer().fit_transform(y) print(classif.fit(X, y).predict(X))輸出為:
[[1 1 0 0 0][1 0 1 0 0][0 1 0 1 0][1 0 1 0 0][1 0 1 0 0]]然后,我們看原來的y值為
[[1 1 0 0 0][1 0 1 0 0][0 1 0 1 0][1 0 1 1 0][0 0 1 0 1]]總結
以上是生活随笔為你收集整理的sklearn学习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: asyncio简单入门(二)
- 下一篇: sklearn学习(二)