故事背景
友圈一位要做毕设的小姐姐在求助postman怎么用,我就帮她答疑了一下。
我知道她的专业不是计算机相关的,所以很奇怪为什么要用postman。
原来她的毕设是要基于微博上最近10年关于房价的话题数据,来做分析,做未来房价的走势预测,训练模型。
她经过一番调研之后决定用百度的【语言处理技术】,实现基础数据的语义分析,即:情感极性分类结果,0负向、1中性、2正向。
官方提供的是基于postman的演示demo,虽然对咱们专业人士来讲很简答,但是对学文科的小姐姐还是有一定门槛的。
我教会小姐姐postman的使用之后问了她一个问题:
搞定数据源
小姐姐已经通过某宝拿到了20W+关于房价的微博数据,现在需要做的就是基于语义分析来获得这20W+数据集对房价走势的判断(我们使用了百度提供的【语言处理技术 NLP】服务),通过Navicat直接导入Excel中的数据源即可。
- 首先根据数据源和百度语义接口返回结果,设计mysql表结构。
- 考虑到数据有20万+,利用了mysql的可视化工具[Navicat]导入数据,也方便小姐姐操作。
注意:要做好表格源字段和目标字段的匹配
- 首次导入选择直接追加;后续优化模型重复导入数据时选择更新。
- 点击开始即可导入Excel源数据到mysql数据库中
- 导入完成,在Navicat控制台通过查询命令,共查询到231007条数据
搭建开发环境
考虑到小姐姐最终的目的是训练模型,而非学习编程,所以搭建开发环境还是怎么简单怎么来, 所以我就推荐她使用LNMP一键安装包,10几分钟左右就把LNMP环境搭建好了
撸代码
脚本关键代码及思路:
字段说明:
mysql语句中 liuxx 是数据库名 semantic_analysis是表名
代码设计思路:
使用do while循环,批量循环请求百度AI语义分析接口,查询positive_prob=0的数据(即未进行语义分析的数据)。
当查询不到数据时,说明所有数据已经成功请求百度语义分析接口,且将返回结果更新到数据表中。
注意问题:
每次查询之后都会休眠1秒,因为百度免费版语义分析请求接口有QPS限制,避免出现无效请求
实现流程
查询数据:
- 查询条件是 positive_prob=0(代表本条数据未请求百度接口)
- 查询排序: 根据id倒序
- 查询翻页: 每次查询10条
处理数据,请求百度接口:
- 将查询到的数据进行json_encode()处理,进而请求百度接口
处理百度返回结果
- 异常处理:当百度返回的error_code为282131时,表示文本内容过长,超过了百度语义分析的字数限制。
- mysql会将不符合百度语义分析的数据源删除,不再重复请求
- 输出返回结果,方便查询信息,定位问题
将返回结果更新到数据表中
- 当百度的返回结果 positive_prob 字段的值不为0时,表示语义分析成功,已返回结果
- 将返回的结果更新到mysql数据表中
批处理脚本核心文件代码:
文件名:batchProcessing.php
<?php ini_set('memory_limit', '256M'); //内存管理 include '../include/ConfigLiuxx.php'; //引入数据配置文件 include '../include/Db.php';//引入db数据库 include '../include/Logger.php';//引入log文件 include '../include/Request.php';//引入 http请求文件 define('Index_table', 'semantic_analysis'); //设置数据表名 语义分析 $db_liuxx = new Db($db_liuxx); //引入db配置文件 /** * 百度语义分析脚本 */ $access_token = "xxxxxxxxxxx"; //百度提供的token $url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify?charset=UTF-8&access_token=' . $access_token; //按百度要求拼接请求url $limit = 10; $offset = 0; do { $datas = $db_liuxx->get_all('select * from liuxx.semantic_analysis WHERE positive_prob = 0 order by id desc limit ' . $offset . ',' . $limit); foreach ($datas as $key => $value) { $id = $value['id']; $text = $value['text']; $params = ['text' => $text]; $bodys = json_encode($params); $response = request_post($url, $bodys); $res_data = json_decode($response, true); if ($res_data['error_code'] == 282131) { $db_liuxx->query('delete from liuxx.semantic_analysis WHERE id = ' . $id); var_dump($id . ' 文本过长 删除'); } echo 'id:'; var_dump('百度返回:'); var_dump($res_data); $data = [ 'positive_prob' => $res_data['items'][0]['positive_prob'], 'confidence' => $res_data['items'][0]['confidence'], 'negative_prob' => $res_data['items'][0]['negative_prob'], 'sentiment' => $res_data['items'][0]['sentiment'], 'ctime' => time(), ]; if ($data['positive_prob']) { var_dump($data); //更新条件 $condition = 'id = ' . $id; $res = $db_liuxx->query('update liuxx.semantic_analysis set positive_prob = ' . $data['positive_prob'] . ', confidence = ' . $data['confidence'] . ', negative_prob = ' . $data['negative_prob'] . ', sentiment = ' . $data['sentiment'] . ' where id = ' . $id); var_dump($res); } else { var_dump('百度未返回结果'); }; } sleep(1); } while (!empty($datas)); //能查到数据就一直循环 ?> /** * 发起http post请求(REST API), 并获取REST请求的结果 * @param string $url * @param string $param * @return - http response body if succeeds, else false. */ function request_post($url = '', $param = '') { if (empty($url) || empty($param)) { return false; } $postUrl = $url; $curlPost = $param; // 初始化curl $curl = curl_init(); // 抓取指定网页 curl_setopt($curl, CURLOPT_URL, $postUrl); // 设置header curl_setopt($curl, CURLOPT_HEADER, 0); // 要求结果为字符串且输出到屏幕上 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // post提交方式 curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost); // 运行curl $data = curl_exec($curl); curl_close($curl); return $data; }
执行批处理脚本
nohup:表示脚本生成的log日志和打印信息输出到nohup.log文件中
&:表示脚本后台运行
nohup php batchProcessing.php &
获得结果
脚本运行完毕后,即可在mysql中查询到经百度语义分析接口处理过的数据,结果示例如下图:
导出数据
通过Navcat工具,小姐姐就可以方便的将mysql数据结果导出到Excel。