scikit-learnをテキスト分類に適用
9631 ワード
テキストマイニングのpaperは統一的なbenchmarkを見つけることができなくて、自分でプログラムを走るしかなくて、通りかかった先輩が20 newsgroupsあるいはその他の使いやすい公共データセットの分類(すべての種類の分類結果を要して、すべてあるいは一部の特徴を取ってどうでもいい)を知っていたら、面倒な伝言を残して今のbenchmarkに教えて、万謝!
ええ、本文を話します.20 newsgroupsの公式サイトには3つのデータセットがあり、ここでは最も原始的な20 news-1997を使用しています.tar.gz.
次の手順に分けられます.
データセットのロード
提feature 分類 Naive Bayes KNN SVM クラスタリング 説明:scipy公式サイト
参考になりましたが、ちょっと散らかっていてバグがありました.本文ではブロックを分けて見ます.
Environment:
Python 2.7 + Scipy (scikit-learn)
1.データセットのロード
20 news-1997.tar.gzはデータセットをダウンロードしてscikit_に解凍しますlearn_Dataフォルダの下で、データをロードします.詳細はcodeコメントを参照してください.
loadが完了しているかどうかを確認できます.
結果:
['comp.graphics', 'comp.os.ms-windows.misc', 'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardware', 'comp.windows.x']
2.提feature:
さっきloadが入ってきたnewsgroup_trainはdocumentの1編で、私たちはそこからfeatureを抽出して、つまり語頻ああ神馬の、fit_を使いますtransform
Method 1. HashingVectorizer,規定feature個数
結果:
Size of fea_train:(2936, 10000)Size of fea_train:(1955, 10000)The average feature sparsity is 1.002%
10000語、すなわち10000次元featureしか取らなかったので、疎度はまだ低くありません.実際にはTfidfVectorizer統計で万次元のfeatureが得られ、私が統計したすべてのサンプルは13 w多次元で、かなりまばらな行列です.
**************************************************************************************************************************
TF-IDFがtrainとtestで抽出したfeature次元が異なるというコード注記がありますが、どうやって同じにしますか?2つの方法があります.
Method 2. CountVectorizer+TfidfTransformer
2つのCountVectorizerにvocabularyを共有させる:
結果:
*************************
CountVectorizer+TfidfTransformer*************************the shape of train is (2936, 66433)the shape of test is (1955, 66433)
Method 3. TfidfVectorizer
2つのTfidfVectorizerにvocabularyを共有させる:
結果:
*************************TfidfVectorizer*************************the shape of train is (2936, 66433)the shape of test is (1955, 66433)
また、sklearnにカプセル化されたfeature関数、fetch_20newsgroups_vectorized
Method 4. fetch_20newsgroups_vectorized
しかし、この方法ではいくつかのクラスのfeatureを選択することはできません.20クラスのfeatureをすべて出すしかありません.
結果:
*************************fetch_20newsgroups_vectorized*************************the shape of train is (11314, 130107)the shape of test is (7532, 130107)
3.分類
3.1 Multinomial Naive Bayes Classifier
コード&commentを参照して、説明しない
私の最後の3行の注釈に注意して、どうしてf 1≠2*(正確率*リコール率)/(正確率+リコール率)
ここで、関数calculate_result計算f 1:
3.2 KNN:
3.3 SVM:
結果:
*************************
Naive Bayes*************************predict info:precision:0.764recall:0.759f1-score:0.760*************************KNN*************************predict info:precision:0.642recall:0.635f1-score:0.636*************************SVM*************************predict info:precision:0.777recall:0.774f1-score:0.774
4.クラスタリング
結果:
*************************KMeans*************************predict info:precision:0.264recall:0.226f1-score:0.213
本明細書のすべてのコードのダウンロード:ここ
精度が低いようですね…では、すべての特徴を使いましょう……結果は以下の通りです.
*************************Naive Bayes*************************predict info:precision:0.771recall:0.770f1-score:0.769*************************KNN*************************predict info:precision:0.652recall:0.645f1-score:0.645*************************SVM*************************predict info:precision:0.819recall:0.816f1-score:0.816*************************KMeans*************************predict info:precision:0.289recall:0.313f1-score:0.266
Pythonの詳細については、引き続き更新されますので、このブログと新浪微博Rachel Zhangに注目してください.
ええ、本文を話します.20 newsgroupsの公式サイトには3つのデータセットがあり、ここでは最も原始的な20 news-1997を使用しています.tar.gz.
次の手順に分けられます.
データセットのロード
提feature 分類
参考になりましたが、ちょっと散らかっていてバグがありました.本文ではブロックを分けて見ます.
Environment:
Python 2.7 + Scipy (scikit-learn)
1.データセットのロード
20 news-1997.tar.gzはデータセットをダウンロードしてscikit_に解凍しますlearn_Dataフォルダの下で、データをロードします.詳細はcodeコメントを参照してください.
#first extract the 20 news_group dataset to /scikit_learn_data
from sklearn.datasets import fetch_20newsgroups
#all categories
#newsgroup_train = fetch_20newsgroups(subset='train')
#part categories
categories = ['comp.graphics',
'comp.os.ms-windows.misc',
'comp.sys.ibm.pc.hardware',
'comp.sys.mac.hardware',
'comp.windows.x'];
newsgroup_train = fetch_20newsgroups(subset = 'train',categories = categories);
loadが完了しているかどうかを確認できます.
#print category names
from pprint import pprint
pprint(list(newsgroup_train.target_names))
結果:
['comp.graphics', 'comp.os.ms-windows.misc', 'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardware', 'comp.windows.x']
2.提feature:
さっきloadが入ってきたnewsgroup_trainはdocumentの1編で、私たちはそこからfeatureを抽出して、つまり語頻ああ神馬の、fit_を使いますtransform
Method 1. HashingVectorizer,規定feature個数
#newsgroup_train.data is the original documents, but we need to extract the
#feature vectors inorder to model the text data
from sklearn.feature_extraction.text import HashingVectorizer
vectorizer = HashingVectorizer(stop_words = 'english',non_negative = True,
n_features = 10000)
fea_train = vectorizer.fit_transform(newsgroup_train.data)
fea_test = vectorizer.fit_transform(newsgroups_test.data);
#return feature vector 'fea_train' [n_samples,n_features]
print 'Size of fea_train:' + repr(fea_train.shape)
print 'Size of fea_train:' + repr(fea_test.shape)
#11314 documents, 130107 vectors for all categories
print 'The average feature sparsity is {0:.3f}%'.format(
fea_train.nnz/float(fea_train.shape[0]*fea_train.shape[1])*100);
結果:
Size of fea_train:(2936, 10000)Size of fea_train:(1955, 10000)The average feature sparsity is 1.002%
10000語、すなわち10000次元featureしか取らなかったので、疎度はまだ低くありません.実際にはTfidfVectorizer統計で万次元のfeatureが得られ、私が統計したすべてのサンプルは13 w多次元で、かなりまばらな行列です.
**************************************************************************************************************************
TF-IDFがtrainとtestで抽出したfeature次元が異なるというコード注記がありますが、どうやって同じにしますか?2つの方法があります.
Method 2. CountVectorizer+TfidfTransformer
2つのCountVectorizerにvocabularyを共有させる:
#----------------------------------------------------
#method 1:CountVectorizer+TfidfTransformer
print '*************************
CountVectorizer+TfidfTransformer
*************************'
from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer
count_v1= CountVectorizer(stop_words = 'english', max_df = 0.5);
counts_train = count_v1.fit_transform(newsgroup_train.data);
print "the shape of train is "+repr(counts_train.shape)
count_v2 = CountVectorizer(vocabulary=count_v1.vocabulary_);
counts_test = count_v2.fit_transform(newsgroups_test.data);
print "the shape of test is "+repr(counts_test.shape)
tfidftransformer = TfidfTransformer();
tfidf_train = tfidftransformer.fit(counts_train).transform(counts_train);
tfidf_test = tfidftransformer.fit(counts_test).transform(counts_test);
結果:
*************************
CountVectorizer+TfidfTransformer*************************the shape of train is (2936, 66433)the shape of test is (1955, 66433)
Method 3. TfidfVectorizer
2つのTfidfVectorizerにvocabularyを共有させる:
#method 2:TfidfVectorizer
print '*************************
TfidfVectorizer
*************************'
from sklearn.feature_extraction.text import TfidfVectorizer
tv = TfidfVectorizer(sublinear_tf = True,
max_df = 0.5,
stop_words = 'english');
tfidf_train_2 = tv.fit_transform(newsgroup_train.data);
tv2 = TfidfVectorizer(vocabulary = tv.vocabulary_);
tfidf_test_2 = tv2.fit_transform(newsgroups_test.data);
print "the shape of train is "+repr(tfidf_train_2.shape)
print "the shape of test is "+repr(tfidf_test_2.shape)
analyze = tv.build_analyzer()
tv.get_feature_names()#statistical features/terms
結果:
*************************TfidfVectorizer*************************the shape of train is (2936, 66433)the shape of test is (1955, 66433)
また、sklearnにカプセル化されたfeature関数、fetch_20newsgroups_vectorized
Method 4. fetch_20newsgroups_vectorized
しかし、この方法ではいくつかのクラスのfeatureを選択することはできません.20クラスのfeatureをすべて出すしかありません.
print '*************************
fetch_20newsgroups_vectorized
*************************'
from sklearn.datasets import fetch_20newsgroups_vectorized
tfidf_train_3 = fetch_20newsgroups_vectorized(subset = 'train');
tfidf_test_3 = fetch_20newsgroups_vectorized(subset = 'test');
print "the shape of train is "+repr(tfidf_train_3.data.shape)
print "the shape of test is "+repr(tfidf_test_3.data.shape)
結果:
*************************fetch_20newsgroups_vectorized*************************the shape of train is (11314, 130107)the shape of test is (7532, 130107)
3.分類
3.1 Multinomial Naive Bayes Classifier
コード&commentを参照して、説明しない
######################################################
#Multinomial Naive Bayes Classifier
print '*************************
Naive Bayes
*************************'
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
newsgroups_test = fetch_20newsgroups(subset = 'test',
categories = categories);
fea_test = vectorizer.fit_transform(newsgroups_test.data);
#create the Multinomial Naive Bayesian Classifier
clf = MultinomialNB(alpha = 0.01)
clf.fit(fea_train,newsgroup_train.target);
pred = clf.predict(fea_test);
calculate_result(newsgroups_test.target,pred);
#notice here we can see that f1_score is not equal to 2*precision*recall/(precision+recall)
#because the m_precision and m_recall we get is averaged, however, metrics.f1_score() calculates
#weithed average, i.e., takes into the number of each class into consideration.
私の最後の3行の注釈に注意して、どうしてf 1≠2*(正確率*リコール率)/(正確率+リコール率)
ここで、関数calculate_result計算f 1:
def calculate_result(actual,pred):
m_precision = metrics.precision_score(actual,pred);
m_recall = metrics.recall_score(actual,pred);
print 'predict info:'
print 'precision:{0:.3f}'.format(m_precision)
print 'recall:{0:0.3f}'.format(m_recall);
print 'f1-score:{0:.3f}'.format(metrics.f1_score(actual,pred));
3.2 KNN:
######################################################
#KNN Classifier
from sklearn.neighbors import KNeighborsClassifier
print '*************************
KNN
*************************'
knnclf = KNeighborsClassifier()#default with k=5
knnclf.fit(fea_train,newsgroup_train.target)
pred = knnclf.predict(fea_test);
calculate_result(newsgroups_test.target,pred);
3.3 SVM:
######################################################
#SVM Classifier
from sklearn.svm import SVC
print '*************************
SVM
*************************'
svclf = SVC(kernel = 'linear')#default with 'rbf'
svclf.fit(fea_train,newsgroup_train.target)
pred = svclf.predict(fea_test);
calculate_result(newsgroups_test.target,pred);
結果:
*************************
Naive Bayes*************************predict info:precision:0.764recall:0.759f1-score:0.760*************************KNN*************************predict info:precision:0.642recall:0.635f1-score:0.636*************************SVM*************************predict info:precision:0.777recall:0.774f1-score:0.774
4.クラスタリング
######################################################
#KMeans Cluster
from sklearn.cluster import KMeans
print '*************************
KMeans
*************************'
pred = KMeans(n_clusters=5)
pred.fit(fea_test)
calculate_result(newsgroups_test.target,pred.labels_);
結果:
*************************KMeans*************************predict info:precision:0.264recall:0.226f1-score:0.213
本明細書のすべてのコードのダウンロード:ここ
精度が低いようですね…では、すべての特徴を使いましょう……結果は以下の通りです.
*************************Naive Bayes*************************predict info:precision:0.771recall:0.770f1-score:0.769*************************KNN*************************predict info:precision:0.652recall:0.645f1-score:0.645*************************SVM*************************predict info:precision:0.819recall:0.816f1-score:0.816*************************KMeans*************************predict info:precision:0.289recall:0.313f1-score:0.266
Pythonの詳細については、引き続き更新されますので、このブログと新浪微博Rachel Zhangに注目してください.