典型意见引擎

用户意见在不同的网站,如微博评论,淘宝等电子商务网站评论里面都扮演量重要的角色。了解用户最典型的意见:

  1. 从监测角度讲,可以快速了解事件传播中网民的核心论点,从而做出相应决策。
  2. 从用户角度讲,能够快速掌握其他用户的意见,如其他用户对于某款产品的评价,帮助其选购。

例如,对某款香水的评论进行典型意见分析,会得到如下结果:味道很女人的(256类似),瓶子的设计也很漂亮了(237类似),留香时间很长(156类似)。

该引擎的使用需要以下三个步骤:

  1. 上传需要聚类的文本数据;
  2. 调用分析引擎(异步);
  3. 从服务器取得聚类的结果。

以下我们将按照上述的三个步骤来介绍引擎的调用。

上传数据

URL

http://api.bosonnlp.com/comments/push/TASK_ID

TASK_ID 是任务的ID,用于唯一识别该典型意见任务,可由字母和数字组成。

Warning

对于每次聚类任务应使用不同的 TASK_ID ,以免导致混淆。

HTTP Method
POST
HTTP Header
Content-Type
application/json
Accept
application/json
X-Token
YOUR_API_TOKEN (需要替换成您自己的 Token)
HTTP 请求 Body

JSON 格式的列表。每个元素为上传到聚类引擎的文档编号和内容组成的 JSON 对象,必须包含两个字段:

  1. _id

    文档的编号,可以采用整数或字符串

  2. text

    文档的内容,原始的文章信息

Note

注意,在文本数量较大时,请分批上传数据。每批最多上传不超过100条文本。

Java调用代码示例

HttpResponse<JsonNode> commentPushResponse = Unirest
    .post("http://api.bosonnlp.com/comments/push/TASK_ID")
    .header("Accept", "application/json")
    .header("Content-Type", "application/json")
    .header("X-Token", "YOUR_API_TOKEN")
    .body(YOUR_JSON_TEXT)
    .asJson();

调用分析

一旦所有待分析的文档都上传到了服务器以后,就可以启动分析模块。典型意见分析任务在后台进行,需要的时间比较长,该接口返回成功时仅表明分析任务已开始。

URL
http://api.bosonnlp.com/comments/analysis/TASK_ID
HTTP Method
GET
HTTP Header
Accept
application/json
X-Token
YOUR_API_TOKEN (需要替换成您自己的 Token)
HTTP GET 参数
参数名 取值范围 默认值 作用
alpha (0, 1] 0.8 调节聚类最大cluster大小
beta (0, 1) 0.45 调节聚类平均cluster大小

alpha 越大,最大产生的cluster会相应减小; beta 越大,形成cluster越不容易,平均cluster大小会减小。默认参数是在微博典型意见上得到不错结果的一组经验参数,在其他应用(如新闻典型意见)可能需要作相应的调整。

Java调用代码示例

HttpResponse<String> commentAnalysisResponse = Unirest
    .get("http://api.bosonnlp.com/comments/analysis/TASK_ID")
    .header("Accept", "application/json")
    .header("X-Token", "YOUR_API_TOKEN")
    .asString();

查看任务状态

一般典型意见任务都用于处理大量的文本,需要比较长的处理时间。通过这个接口,可以查看典型意见任务当前的状态信息。

URL
http://api.bosonnlp.com/comments/status/TASK_ID
HTTP Method
GET
HTTP Header
Accept
application/json
X-Token
YOUR_API_TOKEN (需要替换成您自己的 Token)
HTTP 返回 Body

返回 JSON 格式的状态信息。可能的状态列表如下:

名字 说明
NOT FOUND (在调用分析时)未找到任何数据
RECEIVED 成功接收到分析请求
RUNNING 数据分析正在进行中
ERROR 分析遇到错误退出
DONE 分析已完成

Java调用代码示例

HttpResponse<String> commentStatusResponse = Unirest
    .get("http://api.bosonnlp.com/comments/status/TASK_ID")
    .header("Accept", "application/json")
    .header("X-Token", "YOUR_API_TOKEN")
    .asString();

获取结果

一旦任务完成执行,结果将会被保存在服务器的数据库中。这个时候可以通过 HTTP GET 来取得典型意见分析的结果。

URL
http://api.bosonnlp.com/comments/result/TASK_ID
HTTP Method
GET
HTTP Header
Accept
application/json
X-Token
YOUR_API_TOKEN (需要替换成您自己的 Token)
HTTP 返回 Body

返回 JSON 格式的列表,包含以下字段:

字段 类型 说明
_id 与上传_id类型相同 该典型意见的标示
opinion str 典型意见文本
num int 该典型意见类似的意见个数
list (str, int) 的列表 所有属于该典型意见的评论,其中str为意见,int为意见的来源评论ID

Note

上述的返回结果中忽略了独立的评论,即每个典型意见至少包含2条评论。

Java调用代码示例

HttpResponse<JsonNode> commentResultResponse = Unirest
    .get("http://api.bosonnlp.com/comments/result/TASK_ID")
    .header("Accept", "application/json")
    .header("X-Token", "YOUR_API_TOKEN")
    .asJson();

清除数据

清除 TASK_ID 对应的文本和典型意见分析结果。

URL
http://api.bosonnlp.com/comments/clear/TASK_ID
HTTP Method
GET
HTTP Header
Accept
application/json
X-Token
YOUR_API_TOKEN (需要替换成您自己的 Token)
HTTP 返回 Body
返回 String 格式的状态信息:
Cleared %d documents.

Java调用代码示例

HttpResponse<String> commentClearResponse = Unirest
    .get("http://api.bosonnlp.com/comments/clear/TASK_ID")
    .header("Accept", "application/json")
    .header("X-Token", "YOUR_API_TOKEN")
    .asString();

Python SDK 完整调用示例

# -*- encoding: utf-8 -*-
from __future__ import print_function, unicode_literals
from bosonnlp import BosonNLP

# 注意:在测试时请更换为您的API Token
nlp = BosonNLP('YOUR_API_TOKEN')


def print_comments(idx, comments):
    print('=' * 50)
    print('第%d组典型意见是:' % (idx + 1))
    print(comments['opinion'])
    print('-' * 20)
    print('共包含%s份文档,意见内容和原文ID如下:' % comments['num'])
    for comment, doc_id in comments['list']:
        print(comment, doc_id)


def main():
    with open('text_comments.txt', 'rb') as f:
        docs = [line.decode('utf-8') for line in f if line]
    all_comments = nlp.comments(docs)
    sort_all_comments = sorted(all_comments, key=lambda comments: comments['num'], reverse=True)
    for idx, comments in enumerate(sort_all_comments):
        print_comments(idx, comments)


if __name__ == '__main__':
    main()

详细的Python SDK 典型意见文档请看 这里

Java 完整调用示例

下面是 Java 的 Unirest 库 (Github) 调用 Bosondata 的 Comment API 的示例。

Tip

完整的示例代码可以从 这里 下载。

package commentApiExample;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;

public class CommentApiExample {
    // 请把TASK_ID换成您自己的ID
    public static final String COMMENT_PUSH = "http://api.bosonnlp.com/comments/push/TASK_ID";
    public static final String COMMENT_ANALYSIS = "http://api.bosonnlp.com/comments/analysis/TASK_ID";
    public static final String COMMENT_STATUS = "http://api.bosonnlp.com/comments/status/TASK_ID";
    public static final String COMMENT_RESULT = "http://api.bosonnlp.com/comments/result/TASK_ID";
    public static final String COMMENT_CLEAR = "http://api.bosonnlp.com/comments/clear/TASK_ID";
    // 请记得把 YOUR_API_TOKEN 换成您的 Token
    public static final String API_TOKEN = "YOUR_API_TOKEN";
    public static String filePath = "commentInfos.txt";
    public static boolean flag;
    public static void main(String[] args) throws JSONException,
                                                  UnirestException, IOException {
        // 读取根目录下的commentInfos.txt文件里的内容作为典型意见上传的数据,请根据自身需求做更改
        flag = readTxtFile(filePath);

        // 典型意见分析API调用
        HttpResponse<String> commentAnalysisResponse = Unirest
            .get(COMMENT_ANALYSIS)
            .header("Accept", "application/json")
            .header("X-Token", API_TOKEN)
            .asString();
        System.out.println(commentAnalysisResponse.getCode());

        // 调用查看状态的API来查看任务处理进度,这里每隔一段时间查询一次
        while (flag){
            // 典型意见状态API调用
            HttpResponse<String> commentStatusResponse = Unirest
                .get(COMMENT_STATUS)
                .header("Accept", "application/json")
                .header("X-Token", API_TOKEN)
                .asString();
            JSONObject jsonObj = new JSONObject(commentStatusResponse.getBody());
            String status = (String) jsonObj.get("status");

            try{
                Thread.sleep(2000);
            }catch(InterruptedException ie){
                ie.printStackTrace();
            }

            System.out.println(status);
            if ("DONE".equals(status)) {
                flag = false;
            }
            else
                System.out.println("请稍等,数据处理中...");
        }

        // 典型意见结果API调用
        HttpResponse<JsonNode> commentResultResponse = Unirest
            .get(COMMENT_RESULT)
            .header("Accept", "application/json")
            .header("X-Token", API_TOKEN)
            .asJson();
        System.out.println("以下是返回的结果:");
        JsonNode result = commentResultResponse.getBody();
        String jsonData = result.toString();
        try {
            JSONArray jsonArray = new JSONArray(jsonData);
            String s = "";
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObj = ((JSONObject) jsonArray.opt(i));
                int num = jsonObj.getInt("num");
                int id = jsonObj.getInt("_id");
                String op = jsonObj.getString("opinion");
                String list = jsonObj.getString("list");
                s += "num: " + num + ", _id: " + id + ", opinion: " + op + ", list: " + list + '\n';
            }
            // 返回的结果是一段 JSON,num 指该典型意见类似的意见个数,_id 指该典型意见的标示,opinion 指典型意见文本,
            // list 指所有属于该典型意见的评论,其中 str 为意见,int 为意见的来源评论 ID
            System.out.println(s);
        } catch (JSONException ex) {
            // 异常处理代码
            ex.printStackTrace();
        }

        // 典型意见清除API调用
        HttpResponse<String> commentClearResponse = Unirest
            .get(COMMENT_CLEAR)
            .header("Accept", "application/json")
            .header("X-Token", API_TOKEN)
            .asString();
        System.out.println(commentClearResponse.getBody());
    }

    public static boolean readTxtFile(String filePath ) {
        try {
            String encoding = "utf-8";
            File file = new File(filePath);
            if (file.isFile() && file.exists()) { // 判断文件是否存在
                InputStreamReader reader = new InputStreamReader(new FileInputStream(file), encoding);
                BufferedReader bufferedReader = new BufferedReader(reader);
                String lineTxt = null;
                int i = 0;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    System.out.println(i);
                    JSONArray jsonArray = new JSONArray();
                    JSONObject jsonObject = new JSONObject();

                    jsonObject.put("_id", ++i);
                    jsonObject.put("text", lineTxt);
                    jsonArray.put(jsonObject);
                    String body = jsonArray.toString();
                    System.out.println(body);

                    // 典型意见上传API调用
                    // 上传的数据是JSON格式的,必须包含_id(文档的编号,可以采用整数或字符串)和text(文档的内容,原始的文章信息)
                    HttpResponse<JsonNode> commentPushResponse = Unirest
                        .post(COMMENT_PUSH)
                        .header("Accept", "application/json")
                        .header("Content-Type", "application/json")
                        .header("X-Token", API_TOKEN)
                        .body(body)
                        .asJson();
                }
                reader.close();
                return true;
            }else{
                System.out.println("找不到指定的文件");
                return false;
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
            return false;
        }
    }
}

构建

下载完后,把解压好的文件夹放到 Eclipse 的 Workspace 文件夹下,再新建一个名字一样的 Java Project。

运行

把 X-Token 改成您自己申请的 Token。把 TASK_ID 换成您自己的 ID。

TASK_ID 是任务的ID,用于唯一识别该聚类任务,可由字母和数字组成。

应用场景示例

请看 汽车消费者典型意见