自然语言处理-文本特征值抽取(一)
2018-07-01 本文已影响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)