Google Cloud Natural Language APIを使ったテキストのカテゴリ分類
テキストの分類はその目的によって、様々な方法がとられます。Sentiment分析やEmotion分析も分類タスクの一つと考えられます。これらはテキストと分類結果との組み合わせを学習させることにより、実現しています。
以下の記事では文章ベクトルのコサイン類似度を使って、話題の分類をすることを試してみました。
こちらは、学習はしていませんが、いくつかのワードの平均値を求めることで、一番ちかい話題を推定するということをしています。この時、問題となったのは「どういうカテゴリに分類するか?」ということです。 例えば商品レビューの分析のように分析対象が決まっていれば、カテゴリを決めておくこともできますが、雑談を分類しようとすると、カテゴリの数が増えてしまい、なかなか大変そうです。
Googleのカテゴリ分類 (オンラインデモ)
そこで、Google CloudのNatural Language APIの一つの機能であるカテゴリ分類を試してみることにしました。
分類されるカテゴリは、こちらです。
体系的に620のカテゴリが定義されています。
テキストボックスに対象の文章を入力して「分類」ボタンを押すと、先ほどのカテゴリ分類と信頼スコア(confidence)が表示されます。
Sample Code
Google Cloudのチュートリアルは、pythonで記述されていますので、上記デモのFlutterのサンプルコードを記載しておきます。
まず、以下のパッケージをインストールしておきます。
flutter pub add http
flutter pub add google_fonts
mainのコードは以下の様になります。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:google_fonts/google_fonts.dart';
final categoryUrl = Uri.parse(
'https://cloud.google.com/natural-language/docs/categories?hl=ja');
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Classification Demo',
theme: ThemeData(
textTheme: GoogleFonts.kosugiMaruTextTheme(Theme.of(context).textTheme),
primarySwatch: Colors.blue,
),
home: const ClassificationPage(),
);
}
}
class ClassificationPage extends StatefulWidget {
const ClassificationPage({super.key});
@override
State createState() => _ClassificationPage();
}
class _ClassificationPage extends State {
final TextEditingController _textController = TextEditingController();
String classifyResult = '';
String key = '<Your API key>'; // Google Cloud からAPIを有効にしてキーを取得する
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Classification Sample'),
),
body: Container(
padding: const EdgeInsets.all(10.0),
child: Center(
child: Column(
children: [
TextField(
maxLength: 300,
keyboardType: TextInputType.multiline,
maxLines: 5,
minLines: 5,
autofocus: true,
controller: _textController,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
hintText: '分類する文章を入力してください。',
labelText: 'Input Text',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {
//classification(translateResult);
classification(_textController.text);
},
child: const Text('分類'),
),
const SizedBox(height: 10),
Text(classifyResult),
const SizedBox(height: 10),
],
),
),
),
);
}
void classification(query) async {
String url = "https://language.googleapis.com/v1/documents:classifyText";
String classsifyUrl = "$url?key=$key";
String body = json.encode({
"document": {"type": "PLAIN_TEXT", "language": "ja", "content": query},
"classificationModelOptions": {
"v2Model": {"contentCategoriesVersion": "V2"}
}
});
http.Response resp = await http.post(Uri.parse(classsifyUrl), body: body);
var decode = json.decode(resp.body);
setState(() {
classifyResult = decode.toString();
});
}
}
void classification()に、テキストを引数として渡すと、分類結果をclassifyResultにセットしています。
ニュースサイトの記事や、様々なブログを入力してみると、うまく分類できている様です。よろしければお試しください。