我的主业是互联网运营,业余的python爱好者,学习python已经快两年,主攻网络爬虫与数据分析,爬虫能使用代理ip、打码平台、OCR识别、基本的js逆向处理反爬;数据分析主要使用pandas与pyecharts进行可视化,我的部分案例:
但数据存在的终极意义也许并非在最后的可视化,而在于利用大数据进行预测,为运营决策提供帮助,因此萌生学习机器学习的念头,我会在此记录我学习sklearn的整个过程,用自己的理解与思路进行记录,希望能帮到和我一样的小白,也给自己做个备忘录。我会在公众号:新青年TALKS,同步更新。
一、字典特征抽取
提供一个简单的字典数据:
measurements = [{'city':'Beijing','temperature':33.},{'city':'London','temperature':12.},{'city':'San Fransisco','temperature':18.}]
sklearn提供方法:DictVectorizer
使用方式也非常简单:
from sklearn.feature_extraction import DictVectorizer
dv = DictVectorizer()
dv_fit = dv.fit_transform(measurements)
print(dv_fit)
fit_transform()可以理解为将数据根据抽取方式转换成计算机识别的东西。
它其实是个数组,为了节省内存sklearn将其转为此种格式。我们可以使用toarray()将其转为ndarray:
使用get_feature_names()可以查看具体特征名:
print(dv.get_feature_names())
print(dv_fit.toarray())
这本质上使用的是one-hot编码,one hot编码是将类别变量转换为机器学习算法易于利用的一种形式的过程。简单来说,就是我将所有特征名称列出来,有这一项的标记1,没有就为0。在此之前,我在使用pyecharts绘制热力图时也用过类似方式,下面是示例:
df["注册时间"] = pd.to_datetime(df["注册时间"])
week = df["注册时间"].dt.weekday #转成周几
time = df["注册时间"].dt.hour # 转成小时
bp = pd.DataFrame({'week':week.tolist(),'time':time.tolist()}) #按周几和时间重建DataFrame
data = pd.DataFrame({'count' : bp.groupby( ['week','time'] ).size()}).reset_index() # 统计每天不同时间点注册人数
new_data = pd.DataFrame(index=[i for i in range(24)],columns=[i for i in range(7)]).fillna(0)# 新建空表,将已有数据填充进去,没有的则为0
# print(data)
for i,j,c in zip(data['time'].tolist(),data['week'].tolist(),data['count'].tolist()):new_data.iloc[i,j]=c# 有数据的定位修改数值
# print(new_data)
values = [[i, j, int(new_data.iloc[i, j])] for i in range(24) for j in range(7)]# 将完整数据表转为坐标形式
# print(values)
其他在此不做延申。
二、文本特征抽取
语法上与字典特征抽取类似,只是调用方式不同:
from sklearn.feature_extraction.text import CountVectorizer
data = ["i love python,life is so shot","i dislike python,life is too long"]
cv = CountVectorizer()
data_fit = cv.fit_transform(data)
print(cv.get_feature_names())
print(data_fit.toarray())
这种方式本质上是对词频统计,根据词出现的次数判断本文的情感倾向等。可以尝试在文本内多加一个"is"看下结果。
三、中文文本特征抽取
自己尝试放入中文文本,进行词频统计,会发现它是根据空格来进行统计的,所以中文文本需要进行分词,目前比较好用的就是jieba。
具体使用方式可跳到官方文档:fxsjy/jieba
- 这里准备了一份word文档,这更符合日常需求,所以需要先安装python读取word文档的模块:
from docx import Document
document = Document('企业遇到“商标流氓”怎么办?.docx')
text = []
for paragraph in document.paragraphs:text.append(paragraph.text)
说明:这里为了演示方便将文本写入了列表,但在实际应用中并不可取,会消耗更多内存。
import jieba
data = jieba.cut(str(text)) #返回的是生成器
data = list(data) #转成列表
data = ' '.join(data) #用空格分隔
注意:分词工具返回的是生成器,需要转成迭代器并用空格分隔词语,并且docx库读取出来的文本编码格式好像有点问题,需要强转成str
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
cv.fit_transform([data])
说明:.fit_transform()需要传入列表
这种词频统计的方式判断文章类型其实并不准确,因为很多文章有很多连接词,是没有实际影响力的,所以有更好的方式:tfidf[1]
TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency)。
简单来说就是计算每个词的权重。
- 同样是上面的文章,我们来计算每个词的权重(完整代码):
from sklearn.feature_extraction.text import TfidfVectorizer
from docx import Document
import jieba
document = Document('企业遇到“商标流氓”怎么办?.docx')
text = []
for paragraph in document.paragraphs:text.append(paragraph.text)
data = jieba.cut(str(text))
data = list(data)
data = ' '.join(data)
# cv = CountVectorizer()
# cv.fit_transform([data])
tfidf = TfidfVectorizer()
tf_idf = tfidf.fit_transform([data])
word = tfidf.get_feature_names()
weight = tf_idf.toarray()
for i in range(len(weight)):#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for遍历某一类文本下的词语权重for j in range(len(word)):print (word[j],weight[i][j])
说明:为了更好演示,我将词与该词权重放在一起观察,也就是最后两个for循环。
数值越大表示权重越高。
以上就是关于文本特征抽取的内容,目前还在学习当中。
参考
- ^https://baike.baidu.com/item/tf-idf