美文网首页python-机器学习程序员
自然语言处理-文本特征值抽取(一)

自然语言处理-文本特征值抽取(一)

作者: 董小贱 | 来源:发表于2018-07-01 20:42 被阅读132次

    这是我有关机器学习的第一篇文章。机器学习看了有一段时间了,感觉其知识体系甚是繁杂, 各种原理也是互相交错。故先选择一个方向进行专门的学习。最近在看一些自然语言处理的一些东西,看了不少东西, 感觉还甚是迷茫,难以形成一个完整的体系, 故从易到难整理了一些东西, 也算是对近期学习的一个梳理。因为是对自然语言处理进行系统的初探,有些原理的也是不甚了解, 如果错误还望不吝指教,在此多谢。

    1:字典特征抽取: 对字典数据进行特征值化

    类:sklearn.feature_extraction.DictVectorizer

    dict_to_vec = DictVectorizer()
    看一下它的实例方法(源码中常用的一部分):
    dict_to_vec.fit_transform(X)
       X:字典或者包含字典的迭代器
        返回值:返回sparse矩阵
    dict_to_vec.get_feature_names()
       不接收参数
       返回按索引排序的特性名称列表。
    dict_to_vec.inverse_transform(X)
       X:转换之后的array数组或者sparse矩阵
       返回转换之前的数据
    dict_to_vec.transform(x)
      按照之前的标准转换
    

    实例代码:

    # coding:utf-8
    __author__ = "dongxiaojian"
    
    from sklearn.feature_extraction import DictVectorizer
    def dict_vec(params):
        """
        字典特征值抽取
        :param params: 字典或者包含字典的迭代器
        :return: 
        """
    
        dic = DictVectorizer(sparse=False) # sparse默认为True, 返回值将会是sparse矩阵。这里将其置为False, 返回值为one-hot编码的矩阵
        data = dic.fit_transform(params)
        print(dic.get_feature_names())
        print(data)
        print(dic.inverse_transform(data)) # 这里需要注意的是, 转回去的编码其实跟之前的有区别
    
    if __name__ == "__main__":
        params = [{'subjects': '语文', 'score': 100}, {'subjects': '数学', 'score': 90}, {'subjects': '英语', 'score': 10}]
        dict_vec(params)
    

    打印结果为:

     ['score', 'subjects=数学', 'subjects=英语', 'subjects=语文']
     [[100.   0.   0.   1.]
     [ 90.   1.   0.   0.]
     [ 10.   0.   1.   0.]]
     [{'score': 100.0, 'subjects=语文': 1.0}, {'score': 90.0, 'subjects=数学': 1.0}, {'score': 10.0, 'subjects=英语': 1.0}]
    

    2:文本特征抽取: 对文本数据进行特征值化

    类: sklearn.feature_extraction.DictVectorizer.text.CountVectorizer

    count_to_vec = CountVectorizer()
    count_to_vec.fit_transform(X)
      X: 包含文本的迭代器
    count_to_vec.get_feature_names()
     返回值: 对应的单词列表
    count_to_vec.inverse_transform(X)
    X: 转换之后的array数组或者sqarse矩阵
    

    示例代码:

    # coding:utf-8
    __author__ = "dongxiaojian"
    
    import jieba
    from sklearn.feature_extraction.text import CountVectorizer
    
    def count_vec(count):
        """
        :param count:包含文本的迭代器
        :return:
        """
        count_to_vec = CountVectorizer()
        data = count_to_vec.fit_transform(count)
    
        print(count_to_vec.get_feature_names())
        print(data.toarray())
        print(count_to_vec.inverse_transform(data))
    
    
    if __name__ == "__main__":
        str_con1 = '越过山丘 虽然已白了头 喋喋不休 时不我予的哀愁 还未如愿见着不朽 就把自己先搞丢 越过山丘 才发现无人等候 喋喋不休 再也唤不回温柔 为何记不得上一次是谁给的拥抱 在什么时候'
        str_con2 = """ 想说却还没说的 还很多 攒着是因为想写成歌 让人轻轻地唱着 淡淡地记着 就算终于忘了 也值了 说不定我一生涓滴意念 侥幸汇成河 然后我俩各自一端 望着大河弯弯 终于敢放胆 嘻皮笑脸 面对 人生的难"""
        # 加载自定义词典
        jieba.load_userdict('user_dict.txt') # 这一步其实没什么用, 只是把分词结果更能体现语义
        count1 = jieba.lcut(str_con1)
        count2 = jieba.lcut(str_con2)
        # 构建迭代器
        count = [' '.join(count1), ' '.join(count2)]
        # 中文特征值化
        count_vec(count)
    

    3.TF-IDF:体现词语在文本中的重要程度

    基本的解释:

     TF: Term Frequency  衡量一个term在文档中的出现的有多频繁。
        TF =  某个词出现在文档中的次数/文档中的总词数
    IDF: Inverse Document Frequency 衡量一个term的重要程度。
        有的在不同的文档出现的次数都很多,很显然, 这些词的重要程度就应该很低。例 如:is 、the、and、的、了、么、 呢。我们要做就是将在某篇文档中出现的次数高, 在其他的文章中出现的次数低的挑选出来。
        IDF = log(文档总数/含有t的文档数)
    TF-IDF: TF*IDF 
    

    实现TF-IDF在sklearn中有两种方式:

    3.1先进行CountVectorizer然后进行TfidfTransformer
    # coding:utf-8
     __author__ = "dongxiaojian"
    
    
    import jieba
    from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
    
    
    def count_vec_tfidf(count):
        """
        :param count:
        :return:
        """
        count_to_vec = CountVectorizer()
        data = count_to_vec.fit_transform(count)
        tfidf = TfidfTransformer()
        tfidf_response = tfidf.fit_transform(data)
        feature_names = count_to_vec.get_feature_names()
        tf_idf_value = tfidf_response.toarray()
        for i in range(len(tf_idf_value)):
            print('-------------------第{}个句子----------------'.format(int(i) + 1))
            for j in range(len(feature_names)):
                print(feature_names[j], tf_idf_value[i][j])
    
    
    if __name__ == "__main__":
        str_con1 = '越过山丘 虽然已白了头 喋喋不休 时不我予的哀愁 还未如愿见着不朽 就把自己先搞丢 越过山丘 才发现无人等候 喋喋不休 再也唤不回温柔 为何记不得上一次是谁给的拥抱 在什么时候'
        str_con2 = """ 想说却还没说的 还很多 攒着是因为想写成歌 让人轻轻地唱着 淡淡地记着 就算终于忘了 也值了 说不定我一生涓滴意念 侥幸汇成河 然后我俩各自一端 望着大河弯弯 终于敢放胆 嘻皮笑脸 面对 人生的难"""
        # 加载自定义词典
        jieba.load_userdict('user_dict.txt')
        count1 = jieba.lcut(str_con1)
        count2 = jieba.lcut(str_con2)
        # 构建迭代器
        count = [' '.join(count1), ' '.join(count2)]
        # 中文特征值化, 并进行tf-idf处理
        count_vec_tfidf(count)
    
    3.2 使用TfidfVectorizer直接一步到位
    # coding:utf-8
    __author__ = "dongxiaojian"
    
    import jieba
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    def words_tfidf(count):
        """
    
        :param count:
        :return:
        """
    
        tfidf_vec = TfidfVectorizer()
    
        tfidf_response = tfidf_vec.fit_transform(count)
        print(tfidf_response.toarray())
    
    
    if __name__ == "__main__":
        str_con1 = '越过山丘 虽然已白了头 喋喋不休 时不我予的哀愁 还未如愿见着不朽 就把自己先搞丢 越过山丘 才发现无人等候 喋喋不休 再也唤不回温柔 为何记不得上一次是谁给的拥抱 在什么时候'
        str_con2 = """ 想说却还没说的 还很多 攒着是因为想写成歌 让人轻轻地唱着 淡淡地记着 就算终于忘了 也值了 说不定我一生涓滴意念 侥幸汇成河 然后我俩各自一端 望着大河弯弯 终于敢放胆 嘻皮笑脸 面对 人生的难"""
        # 加载自定义词典
        jieba.load_userdict('user_dict.txt')
        count1 = jieba.lcut(str_con1)
        count2 = jieba.lcut(str_con2)
        # 构建迭代器
        count = [' '.join(count1), ' '.join(count2)]
        # 进行tf-idf特征值化
        words_tfidf(count)
    

    注:以上的方法知识其中一部分简单sklearn中的文本特征值化的一部分方法。其他类似的方法还有NLTK(自带语料库、词类分类库、分类、分词等功能)等。 但是观察其结果, 这些方法都是建立在词频的基础上实现的,其结果表达的含义早已失去了文本原有的意思,所以这几种方法处理起情感分析、问答系统类的问题还是能明显看出其弊端的。接下来的文章将介绍词语向量化的word2vec的方法。

    本人水平有限, 如有错误欢迎提出指正!如有参考, 请注明出处!!禁止原文抄袭,遇抄必肛!!!

    相关文章

      网友评论

        本文标题:自然语言处理-文本特征值抽取(一)

        本文链接:https://www.haomeiwen.com/subject/pmptuftx.html