您的位置:首页 > 其它

sklearn、nltk、gensim语料输入对比之sklearn

2015-08-24 13:21 323 查看
sklearn 语料处理:

sklearn的sklearn.datasets.load_files方法支持从目录读取所有分类好的文本。不过目录必须按照一个文件夹一个标签名的规则放好。比如本文使用的数据集共有2个标签,一个为“net”,一个为“pos”,每个目录下面有6个文本文件。目录如下所示:

neg

1.txt

2.txt

……

pos

1.txt

2.txt

….

12个文件的内容汇总起来如下所示:

neg:
shit.
waste my money.
waste of money.
sb movie.
waste of time.
a shit movie.
pos:
nb! nb movie!
nb!
worth my money.
I love this movie!
a nb movie.
worth it!


我们来探究一下load_files方法返回的Bunch对象

from sklearn.datasets import load_files

movie_reviews=load_files("C:\\Users\\ning\\Desktop\\moivereview")

movie_reviews.data
Out[3]:
[b'nb! nb movie!',
b'worth it! ',
b'waste of time.',
b'a nb movie.',
b'waste of money.',
b'worth my money.',
b'waste my money.',
b'nb!  ',
b'I love this movie!',
b'sb movie. ',
b'shit.',
b'a shit movie.']

movie_reviews.target
Out[4]: array([1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0])

movie_reviews.target_names
Out[5]: ['neg', 'pos']

type(movie_reviews)
Out[6]: sklearn.datasets.base.Bunch


sklearn.cross_validation.train_test_split方法可以进行数据集的切分:

train_features, test_features, train_target, test_target = train_test_split(movie_reviews.data, movie_reviews.target, test_size = 0.2)


空间向量化

在调用分类器模型之前,我们需要把训练数据空间向量化,一个常用的String转Vector的模型是TF-IDF模型。

TF-IDF模型模型初始化:

from sklearn.feature_extraction.text import  TfidfVectorizer

count_vec = TfidfVectorizer(binary = False, decode_error = 'ignore',stop_words = 'english')


TF-IDF模型模型参数说明:

1、停用词的过滤。

初始化count_vec的时候,我们在count_vec构造时传递了stop_words = ‘english’,表示使用默认的英文停用词。可以使用count_vec.get_stop_words()查看TfidfVectorizer内置的所有停用词。当然,在这里可以传递你自己的停用词list(比如这里的“movie”)

2、TF-IDF的计算。

这里词频的计算使用的是sklearn的TfidfVectorizer。这个类继承于CountVectorizer,在后者基本的词频统计基础上增加了如TF-IDF之类的功能。

我们会发现这里计算的结果跟我们之前计算不太一样。因为这里count_vec构造时默认传递了max_df=1,因此TF-IDF都做了规格化处理,以便将所有值约束在[0,1]之间。

3、count_vec.fit_transform的结果是一个巨大的矩阵。我们可以看到上表中有大量的0,因此sklearn在内部实现上使用了稀疏矩阵。本例子数据较小。如果读者有兴趣,可以试试机器学习科研工作者使用的真实数据,来自康奈尔大学:http://www.cs.cornell.edu/people/pabo/movie-review-data/。这个网站提供了很多数据集,其中有几个2M左右的数据库,正反例700个左右。这样的数据规模也不算大,1分钟内还是可以跑完的,建议大家试一试。不过要注意这些数据集可能存在非法字符问题。所以在构造count_vec时,传入了decode_error = ‘ignore’,以忽略这些非法字符。

TF-IDF模型初始化之后还未有数据填充,使用fit_transform方法可以填充训练数据,使用transform方法可以转换测试数据为向量。

tfidf_train_features = count_vec.fit_transform(train_features)
tfidf_test_features  = count_vec.transform(test_features)


训练模型和结果分析, MultinomialNB分类器

from sklearn.naive_bayes import MultinomialNB
mNB_classifier = MultinomialNB().fit(tfidf_train_features, train_target)
doc_class_predicted = mNB_classifier.predict(tfidf_test_features)


#准确率与召回率  ,没搞懂~
from sklearn.metrics import precision_recall_curve
precision, recall, thresholds = precision_recall_curve(test_target , mNB_classifier.predict(tfidf_test_features))


完整代码:

#加载数据集
from sklearn.datasets import load_files
movie_reviews=load_files("C:\\Users\\ning\\Desktop\\moivereview")
movie_reviews.data
movie_reviews.target
movie_reviews.target_names
type(movie_reviews)
#分割数据集
from sklearn.cross_validation import train_test_split
train_features, test_features, train_target, test_target = train_test_split(movie_reviews.data, movie_reviews.target, test_size = 0.2)#空间向量化
from sklearn.feature_extraction.text import TfidfVectorizer
count_vec = TfidfVectorizer(binary = False, decode_error = 'ignore',stop_words = 'english')
tfidf_train_features = count_vec.fit_transform(train_features) tfidf_test_features = count_vec.transform(test_features)
#构建模型
from sklearn.naive_bayes import MultinomialNB mNB_classifier = MultinomialNB().fit(tfidf_train_features, train_target) doc_class_predicted = mNB_classifier.predict(tfidf_test_features)
#准确率与召回率
from sklearn.metrics import precision_recall_curve
precision, recall, thresholds = precision_recall_curve(test_target , mNB_classifier.predict(tfidf_test_features))


在sklearn中TF-IDF的训练结果是用稀疏矩阵表示出来的:

for f in tfidf_test_features:
print (type(f))

<class 'scipy.sparse.csr.csr_matrix'>
<class 'scipy.sparse.csr.csr_matrix'>
<class 'scipy.sparse.csr.csr_matrix'>


查看其稀疏表示形式和还原成array形式:

for f in tfidf_test_features:
print(f)
print("\n###")

(0, 5)        1.0

###
(0, 2)        0.917085830686
(0, 1)        0.398689828256

###
(0, 1)        1.0

###

for f in tfidf_test_features:
print(f.toarray())
print("\n###")

[[ 0.  0.  0.  0.  0.  1.  0.]]

###
[[ 0.          0.39868983  0.91708583  0.          0.          0.          0.        ]]

###
[[ 0.  1.  0.  0.  0.  0.  0.]]

###


可见稀疏表示形式是记录了矩阵中的位置和对应的值,其他位置默认为0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: