「AI」良いニュースリリースと悪いニュースリリースを検出する「SEO」

# ニュースリリースの「良い」「悪い」を数値化して比較したい

ニュースリリースというのは、企業などが「こんなものを世の中に出したよ」という事をお知らせする文章です。
ニュースリリースの文章は、やはりオフィシャルなものなので、フォーマルな文面であることが普通で、あまりノリの軽い文章は使われません。
しかし、ニュースリリースも人間が書いている以上、文章としての「良し」「悪し」があるのですね。

## 「良い」ニュースリリースとは？

ニュースリリースの文章の目的が、リリースをニュースすることである以上、「良い」ニュースリリースの文章というのは、**事実（ニュース）を簡潔に、分かりやすく伝える**ことが第一だと思うのです。

つまり、まず、アナウンスしたい「こんなものを世の中に出したよ」という事実そのものを、ズバリと伝える。そして、そのリリースした物に対する付帯的な情報を、重要な物から順に、最小限の言葉で書き表す、というのが、「良い」ニュースリリースだと思います。

## Text2Importance

さて、ここに、文章の中のセンテンスを、文章全体の意味に対する重要度でスコア付けをするAIがあります。
[Text2Importance](https://github.com/tanreinama/text2importance-japanese)というAIで、私が作成してGitHubで公開しているものですが、これを使えば、文章全体の中で、どのセンテンスがどのくらいの意味を持っているかを数値化することができます。
![](https://raw.githubusercontent.com/tanreinama/text2importance-japanese/main/report/transformer.png)

**これを使って、文章の中のセンテンス毎の意味スコアを求めると、「良い」ニュースリリースは、きちんと前にあるセンテンスほど重要度が高い**（キレイにスコア順にセンテンスが並ぶ）筈だ、というのが、この記事のメインアイデアです。

## サンプル

大企業のニュースリリースなどは、ちゃんとしたライターに書かせているのか、大抵はかなり「良い」文章です。

### 良い例

ここではサンプルとして、[こちら](https://prtimes.jp/main/html/rd/p/000000118.000032088.html)の、ケンタッキーフライドチキンのニュースリリースを[Text2Importance](https://github.com/tanreinama/text2importance-japanese)に食わせてみましょう。
AIの実行は、[こちら](https://nama.ne.jp/)にあるデモンストレーションサイトを利用します。

**入力文章：**

```
日本KFCホールディングスグループの日本ケンタッキー・フライド・チキン株式会社(社長：近藤 正樹、本社：神奈川県横浜市、以下：日本KFC)は、全国のケンタッキーフライドチキン(以下：KFC)店舗で、1月6日(水)から「いちごチョコ パイ」を数量限定で販売します。
「いちごチョコ パイ」は、いちごの風味豊かな、甘酸っぱいいちごチョコクリームをサクサクのパイ生地で包んだパイです。クリームもパイ生地も、いちごをイメージしたかわいらしいピンク色に仕上げ、パイの断面まで鮮やかなピンク色です。お店のオーブンで丁寧に焼き上げ、ご提供します。
なお、チキンとご一緒にお食事のデザートとしてお楽しみいただきたく、1月6日(水)から人気の定番「オリジナルチキンパック」の選べるサイドメニューに「いちごチョコ パイ」が数量限定で仲間入りします。また、1月6日(水)以降、「いちごチョコ パイ」のおトクな発売記念スペシャルクーポンを「KFC公式アプリ」「KFC公式Twitterアカウント」で配布します。ぜひ、この機会にお試しください。
お食事やカフェタイムのデザートに、お子さまから大人まで、皆さまで楽しめる「いちごチョコ パイ」をどうぞ。
```

**[Text2Importance](https://github.com/tanreinama/text2importance-japanese)出力：**

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/1d3d3996-c0cc-9048-0793-098881d063e8.png)

一見して、上の方ほどスコアが高く、ほぼほぼセンテンスの書いてある順番とスコア順が同じであることが解ります。
これはつまり、「重要な事柄を先に書いて、後にゆくにつれて少しずつどうでも良い事柄へと移っている」ことを表しています。
ニュースリリースとして理想的な書き方ですね。

### 悪い例

一方、「悪い」ニュースリリースはどうでしょう？


**入力文章：**

```
皆様にご支援いただいた、「GPT-2日本語版」において、ついに、最大サイズとなるLargeモデルが公開されました！
Largeモデルは、20ヘッダー＋36階層で1280次元の埋め込みベクトルと、大変に巨大なモデルです。
このサイズになると、学習のための時間も膨大になり、皆様のご支援と応援がなかったら、とても作ろうとも思わなかったと思います。
現時点において、フリーで利用できる日本語の言語モデルとして、おそらく最大サイズのものではないかと考えております。
使用したGPUのメモリ制限から、AdamではなくAdagradアルゴリズムで学習させたため、まだ完全なLargeモデルの性能には到達していない可能性がありますが、text2text等のファインチューニングで使用するベースモデルとして、高度な日本語能力をAIに与えるモデルとなっております。
また、本日、別のBERTベースのAIで、『text2importance-japanese』も公開しました！
こちらは、長い文章から、その全体の意味に対する重要度を、センテンス毎に求めるAIモデルです。 
重要度の高いセンテンスを取り出せば抽出型要約AIとして、逆に重要度の低いセンテンスを取り除けば長文フィルターとして使えます。
また、長さの異なる文章を、意味を損なわずに同じくらいの長さに揃えるなどの用途にも使えます。
```

**[Text2Importance](https://github.com/tanreinama/text2importance-japanese)出力：**

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/338aa175-6136-7bb3-3494-b44662fcaf8e.png)

私がやった[Campfireのプロジェクト](https://camp-fire.jp/mypage/projects/320938)の活動報告ですが、比べてみると酷いですね。
まず、事実を簡潔に伝えるのではなく、自分の感想とか関係ないことを書いてます・・・ニュースリリースで感想文書いてんのってどうよ？って事です。
さらに、GPT-2のニュースリリースな筈なのに、後半には別のリリースについても言及してますね。
ニュースリリースなのに、前半と後半で別のリリースが書かれている！これは、やっちゃいけない例そのものです。（笑）

## 数値化

さて。では、その「良し」「悪し」を数値化して比較してみましょう。
「きちんとスコア順に並んでいるかどうか」のスコアは、[レーベンシュタイン距離](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%BC%E3%83%99%E3%83%B3%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%A4%E3%83%B3%E8%B7%9D%E9%9B%A2)を使えば求める事ができます。
Pythonで[レーベンシュタイン距離](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%BC%E3%83%99%E3%83%B3%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%A4%E3%83%B3%E8%B7%9D%E9%9B%A2)を求めるには、ずばり「leven」というパッケージがあるので、それを使います。

```sh
$ pip install leven
```

ただ、残念なことにlevelパッケージにある「levenshtein」関数は、文字列同士の比較しかできません。
数値列を扱う関数を作るのは面倒なので、ここでは、数値を直接Unicode文字コードとして、強引に文字列同士の比較に変形してしまします。

```python
from leven import levenshtein
import numpy as np

id2str = lambda x: "".join(["%c"%a for a in x])
```

そして、0.0から1.0の数値で、数値の大きい方が「良い」ニュースリリースと言えるようなスコアを作ります。
まずはケンタッキーフライドチキンのニュースリリースのスコアから。

```python
# KFCニュースリリースのText2Importanceスコア列
kfc = [0.3872562050819397,0.3342874050140381,0.2530961334705353,0.23218540847301486,0.20209820568561554,0.21009677648544312,0.20749619603157046,0.19680413603782654]

# レーベンシュタイン距離を求める
kfcscore = levenshtein(id2str(np.argsort(kfc)[::-1]), id2str(np.arange(len(kfc))))
# レーベンシュタイン距離は元の長さが長いほど大きくなるので、元の長さで割る
kfcscore = 1.0 - kfcscore / len(kfc)

kfcscore # 0.75
```

**KFCのニュースリリースの「良さ」＝0.75**と出ました。

次に、Campfireの活動報告をスコア化。

```python
# Campfire活動報告のText2Importanceスコア列
nama = [0.3004983365535736,0.2944201231002808,0.22481632232666016,0.3048419654369354,0.21902528405189514,0.2915109694004059,0.2784830331802368,0.232647567987442,0.24233320355415344]

# レーベンシュタイン距離を求める
namascore = levenshtein(id2str(np.argsort(nama)[::-1]), id2str(np.arange(len(nama))))
# レーベンシュタイン距離は元の長さが長いほど大きくなるので、元の長さで割る
namascore = 1.0 - namascore / len(nama)

namascore # 0.2222222222222222
```

**活動報告のニュースリリースとしての「良さ」=0.222**と出ました。

きちんと、良いニュースリリースは大きなスコア、悪いニュースリリースは小さなスコアになっています。

## まとめ

ここで作成したスコアが、どの程度本当の「良し」「悪し」を数値化できているかは、必ずしも保証の限りではありません。
しかし、ニュースリリースという限定された文章ドメインの中では、そこそこそれっぽい数値化ができているのではないかと感じます。
また、センテンスの順序を元にしているので、ニュースリリースの中の「どこが悪いのか」や、「どう改善すれば良いか」を可視化できることも、この手法のメリットだと思っています。

SEO対策や、文章の校正、「こうした方が良いよ」というレコメンド、等に使えるかもしれないな～、と思っています。

**日本語を扱うAIで、「こんな事ができないか」等のコンサルを受けています！既存の公開済みモデルそのままであっても、アイデアと組み合わせ次第で、かなりいろんな事ができる可能性があります！**
お問い合わせは[私のHP](https://nama.ne.jp/tanrei/)からどうぞ！