一、字典特征抽取
字典数据抽取就是把字典中的一些类别数据
分别转化成特征值
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""
字典数据提取
"""
# 实例化
dict = DictVectorizer(sparse=False)
# sparse=False后,dict在调用fit_transform后则返回的是ndarray
# 调用fit_transform方法输入数据并转换
# 每一个数据为一个字典
data = dict.fit_transform(
[{'city': '北京', 'temperature': 100},
{'city': '上海', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
)
# 获取特征信息
print(dict.get_feature_names_out())
"""
['city=上海' 'city=北京' 'city=深圳' 'temperature']
"""
print(data)
"""
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
"""
return None
if __name__ == '__main__':
dictvec()
\
二、文本特征抽取
作用:对文本数据特征值化,可以应用于文章的分类
第一种方法:统计文本出现次数
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
"""
# 实例化
cv = CountVectorizer()
# 调用fit方法
data = cv.fit_transform(["life is is short,i like python",
"life is too long,i dislike python"]
)
# 查看特征值
print(cv.get_feature_names_out())
"""
['dislike' 'is' 'life' 'like' 'long' 'python' 'short' 'too']
单个字母不统计
"""
# toarray-转换成ndarray
print(data.toarray())
"""
统计文章当中出现的词出现的次数
[[0 2 1 1 0 1 1 0]
[1 1 1 0 1 1 0 1]]
"""
if __name__ == '__main__':
countvec()
文本特征抽取CountVectorizer()的用途是什么呢?
count主要用于文本分类
单个字母不能代表文章内容,因此不做统计
如果文本是中文的呢? 比如上面的代码为
data = cv.fit_transform(["人生苦短,我喜欢python",
"人生漫长,不用python了!"]
我们调用cv.get_feature_names_out()方法,结果为:
[‘不用python了’ ‘人生漫长’ ‘人生苦短’ ‘我喜欢python’]
很明显,这并不是我们想要的结果,中文应该按照词进行划分
例如:人生,苦短,喜欢…
因此中文不支持直接特征抽取,需要先对中文语句进行分词,再进行特征抽取
import jieba
def cut_word():
"""
先对文字进行分词处理
"""
t1 = jieba.cut("1、今天很残酷,明天更残酷,后天很美好,"
"但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
t2 = jieba.cut("2.我们看到的从很远星系来的光是在几百万年之前发出的,"
"这样当我们看到宇宙时,我们是在看它的过去。")
t3 = jieba.cut("3、如果只用一种方式了解某样事物,你就不会真正了解它。"
"了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
# jieba.cut返回了一个词语生成器,需要先转换成列表
content1 = list(t1)
content2 = list(t2)
content3 = list(t3)
# 再将每个列表以空格分开,变成字符串
content1 = ' '.join(content1)
content2 = ' '.join(content2)
content3 = ' '.join(content3)
return content1, content2, content3
def hanzivec():
"""
对中文进行特征值化
"""
cv = CountVectorizer()
t1, t2, t3 = cut_word()
data = cv.fit_transform([t1, t2, t3])
print(data.toarray())
"""
[[0 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 0]
[0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 1]
[1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0]]
"""
print(cv.get_feature_names_out())
"""
['一种' '不会' '不要' '之前' '了解' '事物' '今天' '光是在' '几百万年' '发出' '取决于' '只用' '后天' '含义'
'大部分' '如何' '如果' '宇宙' '我们' '所以' '放弃' '方式' '明天' '星系' '晚上' '某样' '残酷' '每个'
'看到' '真正' '秘密' '绝对' '美好' '联系' '过去' '这样']
可以看到,单个汉字是不会作为特征值的
"""
但是! 统计文本次数的方法使用的并不广泛,原因在于一些常见的词语使用的特别频繁,导致这些"废话"在文中的占比很高,比如"比如", “因此”, “但是”…
因此这些中性词语如果在两篇文章中都有大篇幅出现,也不能说明两篇文章类型相似 .
下面就介绍另一种算法:TF-IDF
第二种算法:TF-IDF
TF: term frequency 词语频率
IDF: 逆文档频率inverse document frequency
总的来说,该算法分为两步:第一步是TF,与CountVectorizer()一样,需要统计词语列表,重点是第二步IDF,他的公式为:
显然,越是"废话"的词语,出现频率在所有文章中都偏高,IDF值也相应减少
分母加上1是为了避免分母为0
TF-IDF算法就是TF * IDF的值,这个值称为重要性
根据这个值,我们就能知道某一篇文章重要性较高的词汇了
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
def tf_idf_vec():
t1, t2, t3 = cut_word()
tf = TfidfVectorizer()
data = tf.fit_transform([t1, t2, t3])
print(tf.get_feature_names_out())
print(data.toarray())
数值越大,表示词语越重要