scikit-learn簡介
scikit-learn是Python最為流行的一個機器學習庫。它具有如下吸引人的特點:
簡單、高效且異常豐富的數(shù)據(jù)挖掘/數(shù)據(jù)分析算法實現(xiàn);
基于NumPy,SciPy,以及matplotlib,從數(shù)據(jù)探索性分析,數(shù)據(jù)可視化到算法實現(xiàn),整個過程一體化實現(xiàn);
尤其是當我們要進行多種算法的效果對比評價,這種一體化實現(xiàn)的優(yōu)勢就更加能夠凸顯出來了。
既然scikit-learn模塊如此重要,廢話不多說,下面馬上開搞!
項目組織及文件加載
項目組織
工作路徑:`D:\my_python_workfile\Thesis\sklearn_exercise` |--data:用于存放數(shù)據(jù) |--20news-bydate:練習用數(shù)據(jù)集 |--20news-bydate-train:訓練集 |--20news-bydate-test:測試集
文件加載
假設我們需要加載的數(shù)據(jù),組織結(jié)構如下:
container_folder/ category_1_folder/ file_1.txt file_2.txt ... file_42.txt category_2_folder/ file_43.txt file_44.txt ...
可以使用以下函數(shù)進行數(shù)據(jù)的加載:
sklearn.datasets.load_files(container_path, description=None, categories=None, load_content=True, shuffle=True, encoding=None, decode_error='strict', random_state=0)
參數(shù)解釋:
`container_path`:container_folder的路徑;
`load_content = True`:是否把文件中的內(nèi)容加載到內(nèi)存;
`encoding = None`:編碼方式。當前文本文件的編碼方式一般為“utf-8”,如果不指明編碼方式(encoding=None),那么文件內(nèi)容將會按照bytes處理,而不是unicode處理。
返回值:Bunch Dictionary-like object.主要屬性有
data:原始數(shù)據(jù);
filenames:每個文件的名字;
target_names:類別標簽的具體含義(由子文件夾的名字`category_1_folder`等決定)。
下面,即采用這種方式,使用測試數(shù)據(jù)集[The 20 Newsgroups data set](Home Page for 20 Newsgroups Data Set:http://qwone.com/~jason/20Newsgroups/)進行實例演示。先從網(wǎng)上下載該數(shù)據(jù)集,再在本地進行數(shù)據(jù)的加載。
```python# 加載庫import osimport sys##配置utf-8輸出環(huán)境#reload(sys)#sys.setdefaultencoding("utf-8")# 設置當前工作路徑os.chdir("D:\\my_python_workfile\\Thesis\\sklearn_exercise")# 加載數(shù)據(jù)from sklearn import datasetstwenty_train = datasets.load_files("data/20news-bydate/20news-bydate-train")twenty_test = datasets.load_files("data/20news-bydate/20news-bydate-test")``````pythonlen(twenty_train.target_names),len(twenty_train.data),len(twenty_train.filenames),len(twenty_test.data)```
(20, 11314, 11314, 7532)
```python print("\n".join(twenty_train.data[0].split("\n")[:3])) ```
From: cubbie@garnet.berkeley.edu ( )
Subject: Re: Cubs behind Marlins? How?
Article-I.D.: agate.1pt592$f9a
```python print(twenty_train.target_names[twenty_train.target[0]]) ```
rec.sport.baseball
```python twenty_train.target[:10] ```
array([ 9, 4, 11, 4, 0, 4, 5, 5, 13, 12])
可見,文件已經(jīng)被成功載入。
當然,作為入門的訓練,我們也可以使用`scikit-learn`自帶的`toy example`數(shù)據(jù)集進行測試、玩耍。下面,介紹一下如何加載自帶的數(shù)據(jù)集。
```python from sklearn.datasets import fetch_20newsgroups categories = ['alt.atheism', 'soc.religion.christian', 'comp.graphics', 'sci.med'] twenty_train = fetch_20newsgroups(subset='train', categories=categories, shuffle=True, random_state=42) ```文本特征提取
文本數(shù)據(jù)屬于非結(jié)構化的數(shù)據(jù),一般要轉(zhuǎn)換成結(jié)構化的數(shù)據(jù),方能進行實施機器學習算法實現(xiàn)文本分類。
常見的做法是將文本轉(zhuǎn)換成『文檔-詞項矩陣』。矩陣中的元素,可以使用詞頻,或者TF-IDF值等。
計算詞頻
```python from sklearn.feature_extraction.text import CountVectorizer count_vect = CountVectorizer(stop_words="english",decode_error='ignore') X_train_counts = count_vect.fit_transform(twenty_train.data) X_train_counts.shape ```
(11314, 129783)
使用TF-IDF進行特征提取
```python from sklearn.feature_extraction.text import TfidfTransformer tf_transformer = TfidfTransformer(use_idf = False).fit(X_train_counts) X_train_tf = tf_transformer.transform(X_train_counts) X_train_tf.shape ```
(11314, 129783)
以上程序使用了兩步進行文本的形式化表示:先用`fit()`方法使得模型適用數(shù)據(jù);再用`transform()`方法把詞頻矩陣重新表述成TF-IDF.
如下所示,也可以一步到位進行設置。
```python tfidf_transformer = TfidfTransformer() X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts) X_train_tfidf.shape ```
(11314, 129783)]
分類器訓練
```python from sklearn.naive_bayes import MultinomialNB clf = MultinomialNB().fit(X_train_tfidf,twenty_train.target) ``````python # 對新的樣本進行預測 docs_new = ['God is love','OpenGL on the GPU is fast'] X_new_counts = count_vect.transform(docs_new) X_new_tfidf = tfidf_transformer.transform(X_new_counts) predicted = clf.predict(X_new_tfidf) for doc,category in zip(docs_new,predicted): print("%r => %s") %(doc,twenty_train.target_names[category]) ```
'God is love' => soc.religion.christian
'OpenGL on the GPU is fast' => comp.graphics
分類效果評價
建立管道
```python from sklearn.pipeline import Pipeline text_clf = Pipeline([('vect',CountVectorizer(stop_words="english",decode_error='ignore')), ('tfidf',TfidfTransformer()), ('clf',MultinomialNB()), ]) text_clf = text_clf.fit(twenty_train.data,twenty_train.target) ```
測試集分類準確率
```python import numpy as np docs_test = twenty_test.data predicted = text_clf.predict(docs_test) np.mean(predicted == twenty_test.target) ```
0.81691449814126393
使用樸素貝葉斯分類器,得到的測試集分類準確率為81.7%,效果還不錯!
下面,使用線性核支持向量機看看效果如何。
```python from sklearn.linear_model import SGDClassifier text_clf_2 = Pipeline([('vect',CountVectorizer(stop_words='english',decode_error='ignore')), ('tfidf',TfidfTransformer()), ('clf',SGDClassifier(loss = 'hinge',penalty = 'l2', alpha = 1e-3,n_iter = 5, random_state = 42)), ]) _ = text_clf_2.fit(twenty_train.data,twenty_train.target) predicted = text_clf_2.predict(docs_test) np.mean(predicted == twenty_test.target) ```
0.82355284121083383
支持向量機的分類準確率有所提升。
`scikit-learn`中提供了更精細化的評價指標,如:各類別的精確度,召回率,F(xiàn)值等。
下面,我們來看看更詳細的指標表現(xiàn)如何。
```python from sklearn import metrics print(metrics.classification_report(twenty_test.target,predicted, target_names = twenty_test.target_names)) ```
precision recall f1-score support
alt.atheism 0.71 0.71 0.71 319
comp.graphics 0.81 0.69 0.74 389
comp.os.ms-windows.misc 0.72 0.79 0.75 394
comp.sys.ibm.pc.hardware 0.73 0.66 0.69 392
comp.sys.mac.hardware 0.82 0.83 0.82 385
comp.windows.x 0.86 0.77 0.81 395
misc.forsale 0.80 0.87 0.84 390
rec.autos 0.91 0.90 0.90 396
rec.motorcycles 0.93 0.97 0.95 398
rec.sport.baseball 0.88 0.91 0.90 397
rec.sport.hockey 0.87 0.98 0.92 399
sci.crypt 0.85 0.96 0.90 396
sci.electronics 0.80 0.62 0.70 393
sci.med 0.90 0.87 0.88 396
sci.space 0.84 0.96 0.90 394
soc.religion.christian 0.75 0.93 0.83 398
talk.politics.guns 0.70 0.93 0.80 364
talk.politics.mideast 0.92 0.92 0.92 376
talk.politics.misc 0.89 0.56 0.69 310
talk.religion.misc 0.81 0.39 0.53 251
avg / total 0.83 0.82 0.82 7532
測試集的精確度和召回率的表現(xiàn)均不錯.
下面看看『混淆矩陣』的結(jié)果。
```python metrics.confusion_matrix(twenty_test.target,predicted) ```使用網(wǎng)格搜索進行參數(shù)優(yōu)化
我們使用分類器進行文本分類的過程中,有些參數(shù)需要預先給定。如前面`TfidfTransformer()`中的`use_idf`;`MultinomialNB()`中的平滑參數(shù)`alpha`;`SGClassifier()`中的懲罰系數(shù)`alpha`。然而,參數(shù)設置為多少,并不能直接拍腦袋決定。因為參數(shù)的設置可能會導致結(jié)果天差地別。
為了不淪落為一個『調(diào)參狗』,我們來看看如何使用暴力的『網(wǎng)格搜索算法』讓計算機幫我們進行參數(shù)尋優(yōu)。
```python from sklearn.grid_search import GridSearchCV parameters = { 'vect__ngram_range':[(1,1),(1,2)], 'tfidf__use_idf':(True,False), 'clf__alpha':(1e-2,1e-3) } ```
如果要窮盡所有參數(shù)的組合,那勢必要花費很多時間來等待結(jié)果。有的『土豪』同學可能會想:我能不能用金錢來換時間?
答案是肯定的。如果你有一臺8核的電腦,那就把所有的核都用上吧!
```python gs_clf = GridSearchCV(text_clf_2,parameters,n_jobs = -1) ``` ```python gs_clf = gs_clf.fit(twenty_train.data,twenty_train.target) ```
設置`n_jobs = -1`,計算機就會幫你自動檢測并用上你所有的核進行并行計算。
```python best_parameters,score,_ = max(gs_clf.grid_scores_,key = lambda x:x[1]) for param_name in sorted(parameters.keys()): print("%s: %r" %(param_name,best_parameters[param_name])) ```
clf__alpha: 0.01
tfidf__use_idf: True
vect__ngram_range: (1, 1)
```python score ```
0.90516174650875025
-
機器學習
+關注
關注
66文章
8553瀏覽量
136923 -
數(shù)據(jù)可視化
+關注
關注
0文章
500瀏覽量
11470 -
算法實現(xiàn)
+關注
關注
1文章
3瀏覽量
1908
發(fā)布評論請先 登錄
Python機器學習庫談Scikit-learn技術
什么是機電一體化
機電一體化系統(tǒng)
一體化模塊貼片機概述
如何實現(xiàn)機電一體化設計?
如何實現(xiàn)一體化芯片-封裝協(xié)同設計系統(tǒng)的設計?
一體化伺服電機如何保存當前參數(shù)
測控一體化閘門系統(tǒng)
基于Python的scikit-learn編程實例
詳細解析scikit-learn進行文本分類
scikit-learn K近鄰法類庫使用的經(jīng)驗總結(jié)
scikit-learn的操作流程幾一體化實現(xiàn)的優(yōu)勢
評論