scikit-learn簡介
scikit-learn是Python最為流行的一個機器學習庫。它具有如下吸引人的特點:
簡單、高效且異常豐富的數據挖掘/數據分析算法實現;
基于NumPy,SciPy,以及matplotlib,從數據探索性分析,數據可視化到算法實現,整個過程一體化實現;
尤其是當我們要進行多種算法的效果對比評價,這種一體化實現的優勢就更加能夠凸顯出來了。
既然scikit-learn模塊如此重要,廢話不多說,下面馬上開搞!
項目組織及文件加載
項目組織
工作路徑:`D:\my_python_workfile\Thesis\sklearn_exercise` |--data:用于存放數據 |--20news-bydate:練習用數據集 |--20news-bydate-train:訓練集 |--20news-bydate-test:測試集
文件加載
假設我們需要加載的數據,組織結構如下:
container_folder/ category_1_folder/ file_1.txt file_2.txt ... file_42.txt category_2_folder/ file_43.txt file_44.txt ...
可以使用以下函數進行數據的加載:
sklearn.datasets.load_files(container_path, description=None, categories=None, load_content=True, shuffle=True, encoding=None, decode_error='strict', random_state=0)
參數解釋:
`container_path`:container_folder的路徑;
`load_content = True`:是否把文件中的內容加載到內存;
`encoding = None`:編碼方式。當前文本文件的編碼方式一般為“utf-8”,如果不指明編碼方式(encoding=None),那么文件內容將會按照bytes處理,而不是unicode處理。
返回值:Bunch Dictionary-like object.主要屬性有
data:原始數據;
filenames:每個文件的名字;
target_names:類別標簽的具體含義(由子文件夾的名字`category_1_folder`等決定)。
下面,即采用這種方式,使用測試數據集[The 20 Newsgroups data set](Home Page for 20 Newsgroups Data Set:http://qwone.com/~jason/20Newsgroups/)進行實例演示。先從網上下載該數據集,再在本地進行數據的加載。
```python# 加載庫import osimport sys##配置utf-8輸出環境#reload(sys)#sys.setdefaultencoding("utf-8")# 設置當前工作路徑os.chdir("D:\\my_python_workfile\\Thesis\\sklearn_exercise")# 加載數據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])
可見,文件已經被成功載入。
當然,作為入門的訓練,我們也可以使用`scikit-learn`自帶的`toy example`數據集進行測試、玩耍。下面,介紹一下如何加載自帶的數據集。
```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) ```文本特征提取
文本數據屬于非結構化的數據,一般要轉換成結構化的數據,方能進行實施機器學習算法實現文本分類。
常見的做法是將文本轉換成『文檔-詞項矩陣』。矩陣中的元素,可以使用詞頻,或者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()`方法使得模型適用數據;再用`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值等。
下面,我們來看看更詳細的指標表現如何。
```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
測試集的精確度和召回率的表現均不錯.
下面看看『混淆矩陣』的結果。
```python metrics.confusion_matrix(twenty_test.target,predicted) ```使用網格搜索進行參數優化
我們使用分類器進行文本分類的過程中,有些參數需要預先給定。如前面`TfidfTransformer()`中的`use_idf`;`MultinomialNB()`中的平滑參數`alpha`;`SGClassifier()`中的懲罰系數`alpha`。然而,參數設置為多少,并不能直接拍腦袋決定。因為參數的設置可能會導致結果天差地別。
為了不淪落為一個『調參狗』,我們來看看如何使用暴力的『網格搜索算法』讓計算機幫我們進行參數尋優。
```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) } ```
如果要窮盡所有參數的組合,那勢必要花費很多時間來等待結果。有的『土豪』同學可能會想:我能不能用金錢來換時間?
答案是肯定的。如果你有一臺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文章
8414瀏覽量
132612 -
數據可視化
+關注
關注
0文章
466瀏覽量
10252 -
算法實現
+關注
關注
1文章
3瀏覽量
1848
發布評論請先 登錄
相關推薦
評論