JobPlus知识库 IT 工业智能4.0 文章
sklearn学习:训练一个分辨性别的模型

Version1

1.准备训练数据

将csv中的record读入,使用pandas。为了在文本文档上执行机器学习,我们首先需要将文本内容转换为数字特征向量。 
可以将名称分为单词袋(bag of words),如:

为训练集中任何文档中出现的每个词分配一个固定的整数id(例如,通过从单词到整数索引建立词典)。 
对于每个文档#i,计算每个单词的出现次数w并将其存储为特征的值, 其中,单词在字典中的索引X[i, j]#jjw

单词袋通常使用高位稀疏矩阵(high-dimensional sparse matrix)表示。

在我自己的例子中,我将读入的数据分为特征集X和结果集Y。

    # step1: prepare data, establish an iterable object,to use in CountVectorizer

    # word_list, to be used as X

    # gender_list, to be used as Y

    word_list = []

    gender_list = []

    file = pd.read_csv('your_filename.csv')

    df = pd.DataFrame(file)

    for i in range(len(df)):

        document = df[i:i + 1]

        gender = document['Gender'][i]

        if gender == 'men':

            title = document['Title'][i]

            if pd.isnull(title) == False:

                word_list.append(title)

                gender_list.append(0)

        elif gender == 'women':

            title = document['Title'][i]

            if pd.isnull(title) == False:

                word_list.append(title)

                gender_list.append(1)


准备好两个大的数据集之后,使用train_test_split将两个数据集划分为四个,分别为训练数据集,训练结果集,测试数据集和测试结果集。因为是supervised learning, 即有监督的学习模型,所以需要训练结果集,而两个测试数据集则用来测试模型的准确度。 

    # split data set into train set and test set using train_test_split

    # always use 70% for train data, 30% for test data

    X_train, X_test, Y_train, Y_test = train_test_split(word_list, gender_list,

                                                        test_size=0.3,

                                                        random_state=42)


2. 使用sklearn进行文本标记

文本预处理、分割和停止词的过滤,包含在一个高级组件中,使用该组件能够建立特征的字典,并将文本转化为特征向量。 
CountVectorizer支持单词或连续字符的计数。一旦拟合,向量化器就构建了一个特征索引字典。

    # step2: tokenize text

    count_vect = CountVectorizer()

    X_train_sparse_matrix = count_vect.fit_transform(X_train)

    X_test_sparse_matrix = count_vect.transform(X_test)

    dense_numpy_matrix = X_train_sparse_matrix.todense()


3.统计词频

统计词的个数尽管很有用,但存在一些问题,比如,即使谈论的主题是相同的,长文本也比短文本的平均计数更高。因此需要转化为频率。

我们首先使用fit方法来将我们的估计量与数据拟合,其次将transform方法转换为tf-idf表示。 通过跳过冗余处理,可以将这两个步骤组合在一起,以更快地达到相同的最终结果,即使用fit_transform。

    # step3: get frequencies (features)

    tfidf_transformer = TfidfTransformer()

    X_train_tfidf = tfidf_transformer.fit_transform(X_train_sparse_matrix)

    X_test_tfidf = tfidf_transformer.fit_transform(X_test_sparse_matrix


4. 培训分类器

这里先使用的是朴素贝叶斯分类器。

   # step4: training a classifier (after having features now)

    clf = MultinomialNB().fit(X_train_tfidf, Y_train)


后续也有改进为其他方法,如SVM。

5.预测和评估

   predicted = clf.predict(X_test_tfidf)

   print(predicted)

   accruacy = np.mean(predicted == Y_test)

   print(accruacy)


最终的运行结果为: 
[0 0 1 ... 1 1 1] 
4621 
0.9091105821250811

6.Version1完整代码

import pandas as pd

from sklearn.feature_extraction.text import CountVectorizer

from sklearn.feature_extraction.text import TfidfTransformer

from sklearn.naive_bayes import MultinomialNB

from sklearn.model_selection import train_test_split

import numpy as npif __name__ == '__main__':

    # step1: prepare data, establish an iterable object,to use in CountVectorizer

    # word_list, to be used as X

    # gender_list, to be used as Y

    word_list = []

    gender_list = []

    file = pd.read_csv('your_filename.csv')

    df = pd.DataFrame(file)

    for i in range(len(df)):

        document = df[i:i + 1]

        gender = document['Gender'][i]

        if gender == 'men':

            title = document['Title'][i]

            if pd.isnull(title) == False:

                word_list.append(title)

                gender_list.append(0)

        elif gender == 'women':

            title = document['Title'][i]

            if pd.isnull(title) == False:

                word_list.append(title)

                gender_list.append(1)

    # split data set into train set and test set using train_test_split

    # always use 70% for train data, 30% for test data

    X_train, X_test, Y_train, Y_test = train_test_split(word_list, gender_list,

                                                        test_size=0.3,

                                                        random_state=42)

    # step2: tokenize text

    count_vect = CountVectorizer()

    X_train_sparse_matrix = count_vect.fit_transform(X_train)

    X_test_sparse_matrix = count_vect.transform(X_test)

    dense_numpy_matrix = X_train_sparse_matrix.todense()

    # print(dense_numpy_matrix)

    # print(count_vect.vocabulary_)

    # print(X_train_sparse_matrix.shape) #(9,13) 9 sentences, 13 words

    # print(count_vect.vocabulary_.get(u'slip')) # return the id of words in vocabulary???

    

    # step3: get frequencies (features)

    tfidf_transformer = TfidfTransformer()

    X_train_tfidf = tfidf_transformer.fit_transform(X_train_sparse_matrix) 

    X_test_tfidf = tfidf_transformer.fit_transform(X_test_sparse_matrix)

    # print(X_train_tfidf,'\n','\n')

    #

    # print(X_test_tfidf)

    # print(X_train_tfidf)#.toarray())

    # print(type(X_train_tfidf))

    # print(X_train_tfidf.shape)

    

    # step4: training a classifier (after having features now)

    clf = MultinomialNB().fit(X_train_tfidf, Y_train)

    predicted = clf.predict(X_test_tfidf)

    # predicted = text_clf.fit(X_train_word_list,gender_list)

    print(predicted)

    print(len(predicted))

    accruacy = np.mean(predicted == Y_test)

    print(accruacy)

    # for doc,category in zip(word_list,predicted):

    #

     print(('{}=>{}').format(doc,word_list[category]))


Version2

1. 使用Pipline简化过程

sklearn提供了Pipline来简化上述过程。 
为了使vectorizer => transformer =>classifier更易于使用,scikit-learn提供了一个Pipeline类似复合分类器的类。

   # step2: using pipline as a compound classifier

    text_clf = Pipeline([('vect',CountVectorizer()),

                         ('tfidf',TfidfTransformer()),

                         ('clf',SGDClassifier(loss='hinge',penalty='l2',

                                              alpha=1e-3,random_state=42,

                                              max_iter=5,tol=None)),

                         ])


2.使用SVM模型

SVM即支持向量机模型,使用该模型,速度虽然比朴素贝叶斯慢一点,但是准确率更高。

上面的SDGClassifier。

3.Version2完整代码

import pandas as pd

from sklearn.feature_extraction.text import CountVectorizer

from sklearn.feature_extraction.text import TfidfTransformer

from sklearn.naive_bayes import MultinomialNB

from sklearn.pipeline import Pipeline

from sklearn.linear_model import SGDClassifier

from sklearn.model_selection import train_test_split

import numpy as np


if __name__ == '__main__':

    # step1: prepare data, establish an iterable object

    # word_list, to be used as X

    # gender_list, to be used as Y

    word_list = []

    gender_list = []

    file = pd.read_csv('your_filename.csv')

    df = pd.DataFrame(file)

    for i in range(len(df)):

        document = df[i:i + 1]

        gender = document['Gender'][i]

        if gender == 'men':

            title = document['Title'][i]

            if pd.isnull(title) == False:

                word_list.append(title)

                gender_list.append(0)

        elif gender == 'women':

            title = document['Title'][i]

            if pd.isnull(title) == False:

                word_list.append(title)

                gender_list.append(1)

    # split data set into train set and test set using train_test_split

    # always use 70% for train data, 30% for test data

    X_train,X_test,Y_train,Y_test = train_test_split(word_list,gender_list,

                                                     test_size=0.3,

                                                     random_state=42)

    # step2: using pipline as a compound classifier

    text_clf = Pipeline([('vect',CountVectorizer()),

                         ('tfidf',TfidfTransformer()),

                         ('clf',SGDClassifier(loss='hinge',penalty='l2',

                                              alpha=1e-3,random_state=42,

                                              max_iter=5,tol=None)),

                         ])

    # train data

    text_clf.fit(X_train,Y_train)

    # test

    X_test_word_list = [str(item).encode(encoding='utf-8') for item in X_test]

    predicted = text_clf.predict(X_test_word_list)

    

    accuracy = np.mean(predicted == Y_test)

    print(predicted)

    print(accuracy)




如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
387人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序