SDGs特許(文章)か判定する


1.はじめに

  • SDGs技術の見える化という記事と関連の論文があってこれはいいなーとおもったので真似。

  • 上記のものは「このGoal関連の特許は●●件」というような集計結果がでているので、こちらは1文章単位で判定結果を出せるようにしてみた。


2.全体構成

こんな感じ↓
Client<-->Cloud Functions <--> AutoMLで作成したモデル(デプロイ済)

以下各部分

2.0 学習データ

  • 上記のモデルは特許文章のうち、【課題】部分を使ったようだけれどラベルを作るのが大変そう。
  • SDGsのゴール、インディケータというのがあったので、それを学習データとして使わせてもらった。300件程度。

2.1 AutoML(Vertex AI)

テキスト,ラベル の2行が入っているcsvファイルをアップロードすればよいだけ。
便利!

各カテゴリ最低100件は学習データを作れと文句を言われつつ、学習後の精度は7割いかないのでちょっと微妙な結果に。

2.1 Client

入力文章をCloud FunctionsへGETで渡して、結果をグラフにする形。
chart.jsを使わせてもらったけど、ラベルとdataを配列で渡せばいいだけで便利!

Client
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
</head>
<body>
  <h2>SDGs関連特許判定</h2>
  <textarea id="input_text" rows="4" cols="100" placeholder="判定対象の文章を入力してください。"></textarea>
  <button id="predict">判定!</button>
  <hr />
  <div id="tableinfo"></div>
  <div id="result"> </div>
  <canvas id="myBarChart" style="position: relative; height:'100px'; width:'50px'">
</canvas>

<script>
  document.getElementById('predict').addEventListener("click",function(e){
    const tableinfo = document.getElementById("tableinfo");
    document.getElementById("result").innerHTML = "";
    tableinfo.innerHTML = "実行中・・・";
    let text = document.getElementById("input_text").value;
    if(text==""){text="エネルギーをみんなに"}else{}
    const apiurl= "https://us-central1-streamlit-text-generate.cloudfunctions.net/predict_sdgs?text=" + text;    

    const res = fetch(encodeURI(apiurl)
        , {method: 'GET',mode: 'cors'}
        ).then(response => {return response.json();})
         .then((res2) => {
                if(res2){
                    const chartlabels =[
                    "1貧困をなくそう", 
                    "2飢餓をゼロ", 
                    "3すべての人に健康と福祉を", 
                    "4質の高い教育をみんなに", 
                    "5ジェンダー平等を実現しよう", 
                    "6安全な水とトイレを世界中に", 
                    "7エネルギーをみんなに そしてクリーンに", 
                    "8働きがいも経済成長も", 
                    "9産業と技術革新の基盤をつくろう",                        
                    "10人や国の不平等をなくそう", 
                    "11住み続けられるまちづくりを", 
                    "12つくる責任 つかう責任", 
                    "13気候変動に具体的な対策を", 
                    "14海の豊かさを守ろう", 
                    "15陸の豊かさも守ろう", 
                    "16平和と公正をすべての人に", 
                    "17パートナーシップで目標を達成しよう"
                    ];
                    const chartdatas = [];
                    const chartdic = {};
                    const chartdic_rev = {};

                    res2.forEach(element => {
                        chartdic[element["displayNames"]] = element['confidences'];
                        chartdic_rev[element['confidences']] = element["displayNames"];
                    });

                    chartlabels.forEach(elm=>{
                        chartdatas.push(chartdic[elm])
                    });

                    const maxscore = Math.max.apply(null,res2.map(function(o){return o.confidences;}))
                    document.getElementById("result").innerHTML = "<div>判定結果:「" + chartdic_rev[maxscore] +"」 (confidence=" + maxscore +")</div><hr />";

                    makechart(chartdatas,chartlabels)
                    tableinfo.innerHTML = ""
                }else{
                    alert("error");
                    tableinfo.innerHTML = ""
                }
            })
            .catch(error => {
            alert("error")
            tableinfo.innerHTML = "";
            });
  });
</script>

<script>
function makechart(chartdatas,chartlabels){
    var ctx = document.getElementById("myBarChart");
    var myBarChart = new Chart(ctx, {
      type: 'horizontalBar',
      data: {
       //凡例のラベル
        labels: chartlabels,
        datasets: [
          {
            label: 'confidence', //データ項目のラベル
            data: chartdatas, //グラフのデータ
            backgroundColor: "rgba(200,112,126,0.5)"
          }
        ]
      },
      options: {
        title: {
          display: true,
          text: 'SDGs判定'
        },
      }
    });
}
</script>
</body>
</html>


2.2 Cloud Functions

  • 基本的にここのスクリプトを流用させてもらった。printする部分をreturnに変更。
  • requirements.txt↓
google-cloud-aiplatform==1.1.1
google-cloud-storage==1.32.0
pandas==1.2.0

2.3 いくつか実行してみた結果

そんなに変な感じにはならなかったので良かった。

2.4 その他

  • AutoML以上に精度出せ得るかわららないけれど、自作のscikit-learnやXGBOOSTのスクリプトを使ってできる、とのことなので勉強してやってみたい。
  • それなら自分で書いて実行すればいいじゃんという話だけど、作成したモデルをデプロイしておけば、APIとして接続先を変えるだけですぐに利用できるのはありがたい。
  • 続き