前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >写给【算法同学】的MLSQL机器学习教程

写给【算法同学】的MLSQL机器学习教程

作者头像
用户2936994
发布2022-04-25 08:08:01
6040
发布2022-04-25 08:08:01
举报
文章被收录于专栏:祝威廉祝威廉

数据集和MLSQL版本

这次我做了个文本分类的案例,数据集在这里:

http://qwone.com/~jason/20Newsgroups/20news-19997.tar.gz

MLSQL版本为

http://download.mlsql.tech/1.6.0-SNAPSHOT/mlsql-engine_2.4-1.6.0-SNAPSHOT.tar.gz

当然了,MLSQL Console 也需要安装的。大家可以照着文档安装MLSQL

将数据保存到数据湖提速

20newsgroups默认是以单个文件一篇内容的形式存储的,需要遍历文件夹然后读取文件,速度比较慢,不利于SQL做处理。所以我们读取后存储到数据湖里,两行代码搞定:

代码语言:javascript
复制
-- 加载数据,MLSQL支持加载市面上大部分存储,HBase,ES,Hive,Delta,MySQL等等
-- 这里递归加载文件,wholetext 表示会把一个文件当成一个字段。
load text.`/20_newsgroups/*/*` where wholetext="true" as 20newsgroups;

-- 把文本内容最后保存成数据湖里的格式。并且控制文件数。这样可以后续使用速度更快。
save overwrite 20newsgroups as delta.`ai_data.20newsgroups` where fileNum="16";

额,说好的SQL呢,这个load和save就只有那么一点点像SQL。MLSQL新增加了几个SQL语法,其实是简化SQL,所有语法加起来,也就七八个句式吧,不相信可以回头看看这个文档MLSQL语法指南

另外还有个需要注意的点是:

这个数据集文件数比较多,用不了MLSQL Console里的上传功能,你可以直接把目录拷贝到你的主目录里面。如果是单机的话默认是在 /home/users/用户名 下。集群的话则是在HDFS对应的目录上。这个取决于MLSQL Console USER_HOME 环境变量的配置。

代码的含义都在代码的注释里。以后我们要使用这个数据集,只需要加载数据湖的数据库ai_data里的20newsgroups表即可。像下面这个句法结构:

代码语言:javascript
复制
load delta.`ai_data.20newsgroups` as 20newsgroups;

探索下数据分类的分布

20newsgroups 有20个分类。我们先看看这20个分类的文章分布情况,确定下样本是否均衡。在MLSQL Console里新建 `20news_visualize.mlsql` 脚本,大概是这个样子的:

然后开始撸代码:

代码语言:javascript
复制
load delta.`ai_data.20newsgroups` as 20newsgroups;

-- 提取数据中的分类,因为隐含在路径里。这段代码其实依赖路径位置,所以不可移植
select *, split(file,"/")[4] as label from 20newsgroups as 20newsgroups;

--我们可视化下数据分布

select label,count(*) as label_count from 20newsgroups where label !="" group by label as visual_data;

加载数据,把路径里的的分类信息提取出来,最后统计下label下的内容数。很简单吧。这次真的都是SQL了。

MLSQL可以将一条SQL语句映射成一张表,然后下一句可以接着对这张表进行处理,所以可以避免单条SQL 过于复杂。因为大家都是搞算法的,对python应该会很熟悉,所以这里我决定用Python的plotly做可视化。MLSQL里可以直接写Python(也可以把Python代码搞成一个单独文件,然后include进来):

代码语言:javascript
复制
!python env "PYTHON_ENV=source activate dev";
!python conf "schema=st(field(content,string))";

!ray on visual_data '''

import pandas as pd
import plotly.express as px
from plotly.io import to_html
from vega_datasets import data
from pyjava.api.mlsql import PythonContext,RayContext

# 这里我们不连接Ray做计算,所以url设置为None
ray_context = RayContext.connect(globals(),None)

# 通过ray_context获取表visual_data里的数据
data = list(ray_context.collect())
df = pd.DataFrame(data, columns=data[0].keys())

fig = px.bar(df,
             y="label_count",
             x="label",
             color="label")
fig.update_xaxes(title_text='文章目录')
fig.update_yaxes(title_text='文章数')

html = to_html(
    fig,
    config={},
    auto_play=False,
    include_plotlyjs=True,
    include_mathjax="cdn",
    post_script=None,
    full_html=True,
    animation_opts=None,
    default_width="50%",
    default_height="50%",
    validate=False,
)

# 返回一条记录
context.build_result([{"content":html}])

''' named visual_data;

前面两个设置了python环境和返回值。中间那一坨内嵌python的句式如下:

!ray on 【表名1】【 python代码】 【新表名】;

这个含义表示,我需要使用Python代码对对表1的数据进行处理,处理完成后返回一张新的表。Python和SQL就这么完美的结合了。

python代码的逻辑我假设大家能看懂啦,其实就是利用plotly绘制一个bar图,然后渲染成html.

为了能够让MLSQL Console渲染这个html字符串,还需要给个暗号:

代码语言:javascript
复制
-- 暗示MLSQL Console 将内容作为报表渲染/ 最后可以看到结果非常的均衡
select content as html ,"" as dash from visual_data as output;

点开Dash,可以看到图了:

可以看到,数据分布非常的好,不愧是标准数据集。

开始写训练代码

那让我们开工吧,我找了个最简单办法做训练,就是用sklearn的贝叶斯。当然啦,大家可以尽管用你熟悉的框架,比如tensorflow,pytorch啥的。这里只是做个示例。

前面SQL部分代码都差不多,我们最后就是通过SQL转换,让表只包含value,label两个字段:

代码语言:javascript
复制
load delta.`ai_data.20newsgroups` as 20newsgroups;

-- 提取数据中的分类,因为隐含在url里。这段代码其实依赖路径位置,所以不可移植
select *, split(file,"/")[4] as label from 20newsgroups as 20newsgroups;


select label,value from 20newsgroups as 20newsgroups;

数据集通过SQL准备好了,就可以开工继续写Python了,和上面的例子一样,对表使用Python处理:

代码语言:javascript
复制
!python env "PYTHON_ENV=source activate dev";
!python conf "schema=st(field(count_vect,binary),field(tfidf_transformer,binary),field(nb,binary))";

!ray on 20newsgroups '''

import pandas as pd
import plotly.express as px
from plotly.io import to_html
from vega_datasets import data
from pyjava.api.mlsql import PythonContext,RayContext

ray_context = RayContext.connect(globals(),None)
data = list(ray_context.collect())
df = pd.DataFrame(data, columns=data[0].keys())

from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(df.value)

from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)

from sklearn.naive_bayes import MultinomialNB
print("这是进行训练的过程")
clf = MultinomialNB().fit(X_train_tfidf, df.label)
docs_new = ['God is love', 'OpenGL on the GPU is fast']
X_new_counts = count_vect.transform(docs_new)
X_new_tfidf = tfidf_transformer.transform(X_new_counts)

print("重要的一行在这里,这是进行预测的过程。")
predicted = clf.predict(X_new_tfidf)
for doc, category in zip(docs_new, predicted):
    print('%r => %s' % (doc, category))

# 最好是能讲数据序列化后上传到模型仓库
# 不过我们这里就先保存到文件里去
import pickle
context.build_result([{"count_vect":pickle.dumps(count_vect),"tfidf_transformer":pickle.dumps(tfidf_transformer),"nb":pickle.dumps(clf)}])

''' named model_data;

这里,我们把三个模型保存到了一条记录里面了。这样就得到一个叫modeldata的表。我们把这个表保存到数据库ai_model 里的表 20newsgroups里去。

代码语言:javascript
复制
save overwrite model_data as delta.`ai_model.20newsgroups` 
where overwriteSchema="true";

这样我们的训练过程就结束了。中间print的打印会输出到控制台:

预测啦

现在可以使用我们训练好的模型做预测了,基本逻辑就是加载模型,然后做预测咯。代码如下:

代码语言:javascript
复制
load delta.`ai_model.20newsgroups` as 20newsgroups_model;

!python env "PYTHON_ENV=source activate dev";
!python conf "schema=st(field(doc,string),field(predict_category,string))";

!ray on 20newsgroups_model '''

import pandas as pd
import plotly.express as px
from plotly.io import to_html
from vega_datasets import data
from pyjava.api.mlsql import PythonContext,RayContext
import pickle
ray_context = RayContext.connect(globals(),None)
data = list(ray_context.collect())
df = pd.DataFrame(data, columns=data[0].keys())

model_data = data[0]

count_vect = pickle.loads(model_data["count_vect"])
tfidf_transformer = pickle.loads(model_data["tfidf_transformer"])
clf = pickle.loads(model_data["nb"])

docs_new = ['God is love', 'OpenGL on the GPU is fast']
X_new_counts = count_vect.transform(docs_new)
X_new_tfidf = tfidf_transformer.transform(X_new_counts)

predicted_data = []

print("重要的一行在这里,这是进行预测的过程。")
predicted = clf.predict(X_new_tfidf)
for doc, category in zip(docs_new, predicted):
    predicted_data.append({"doc":doc,"predict_category":category})

context.build_result(predicted_data)

''' named model_data;

运行结果如下:

是不是很简单?

最后偷偷说一个: MLSQL支持把这个预测的Python脚本部署成一个服务,对外提供API预测。

下一篇,我们给假设不太习惯写Python代码的工程同学介绍下他们可以如何使用MLSQL来做机器学习。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档