オモイアイ - X（旧Twitter）の投稿から共通点を見つけるツール

## 概要

![企画書.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/03a6564f-b82e-44b8-b829-a16355d04ede.png)

「オモイアイ」は、X（旧Twitter）の投稿を分析し、ユーザー間の共通点を見つけるPythonツールです。
自然言語処理を活用して、投稿データから共通のキーワードを抽出し、会話のきっかけや相性を発見することを目的としています。

この記事では、ツールの仕組みや処理の流れをコードを交えながら解説します。

## ソース
https://github.com/Syogo-Suganoya/TweetMate

## サンプル
### Input

投稿データ

| ユーザーA | ユーザーB |
| - | - |
| 新しいカフェ見つけた☕️雰囲気最高 | 明日はカフェ巡りデーにしようかな |
| カフェで読書すると落ち着く | パンケーキふわふわで幸せ…！ |
|  | 今日はカレー作った🍛スパイス多めにして大正解 |
|  | ランチは久しぶりにラーメン🍜 |

### Output

共通点

`カフェ`

## 主な機能

1. **投稿データ取得**
   - X API またはモックデータを使用して、指定されたユーザーの投稿を取得します。

2. **共通キーワード抽出**
   - 日本語のストップワードを除外し、TinySegmenterを用いてトークン化を行い、共通キーワードを抽出します。

3. **モックデータ対応**
   - 実データがなくても動作確認が可能です。

## 処理の流れ

### 1. コマンドライン引数の解析

ツールはコマンドライン引数を受け取り、モックデータを使用するか、実際のユーザーIDを指定するかを選択できます。

以下は引数を解析するコードです：

```python
from argparse import ArgumentParser

def parse_args():
    parser = ArgumentParser(description="オモイアイ 共通点発見ツール")

    parser.add_argument("--mock", action="store_true", help="モックデータを使用する")
    parser.add_argument("--user1", type=str, help="一人目のXのユーザー名")
    parser.add_argument("--user2", type=str, help="二人目のXのユーザー名")

    args = parser.parse_args()

    # バリデーション
    if args.mock:
        if any([args.user1, args.user2]):
            parser.error("--mock を指定した場合、--user1、--user2 は指定できません。")
    else:
        missing = [opt for opt in ["user1", "user2"] if getattr(args, opt) is None]
        if missing:
            parser.error(f"--mock を使わない場合、以下の引数が必要です: {', '.join('--' + m for m in missing)}")

    return args
```

### 2. 投稿データの取得

ユーザーの投稿データを取得するために、X API またはモックデータを使用します。
以下は、データ取得を行うクラスの一部です：

```python
from lib import x_api

class CommonKeywordDataset:
    def __init__(self):
        self.user1 = None
        self.user2 = None
        self.tweets1 = []
        self.tweets2 = []

        self._load_metadata()

    def _load_metadata(self):
        if args.mock:
            self.user1 = "634829374928374657"
            self.user2 = "783295847239182374"
            get_posts_method = x_api.get_user_posts_mock
        else:
            self.user1 = args.user1
            self.user2 = args.user2
            get_posts_method = x_api.get_user_posts
        self.tweets1 = [extract_post_text(t.text) for t in get_posts_method(self.user1).data]
        self.tweets2 = [extract_post_text(t.text) for t in get_posts_method(self.user2).data]
```

このクラスでは、`_load_metadata` メソッドを使用して、指定されたユーザーの投稿データを取得し、テキストを前処理した結果をリストに格納します。
モックデータを使用する場合と実データを使用する場合で処理を切り替えています。

### 3. テキストの前処理

投稿データにはURLやハッシュタグ、メンションなどの不要な情報が含まれているため、それらを削除する前処理を行います。

以下は、前処理を行う関数のコードです：

```python
import re

def extract_post_text(text):
    text = re.sub(r"http\S+", "", text)  # URL削除
    text = re.sub(r"[@#]\S+", "", text)  # @メンションや#ハッシュタグ削除
    return text.lower()  # 小文字化
```

この関数では、正規表現を使用してURLやハッシュタグ、メンションを削除し、テキストを小文字化しています。
これにより、余計な情報を排除し、キーワード抽出の精度を向上させます。

### 4. 日本語ストップワードの読み込み

日本語のストップワード（頻出するが意味を持たない単語）を除外するために、外部リソースを使用してストップワードリストを取得します。

以下は、ストップワードを読み込む関数のコードです：

```python
import urllib.request

def load_stopwords():
    url = "https://raw.githubusercontent.com/stopwords-iso/stopwords-ja/master/stopwords-ja.txt"
    response = urllib.request.urlopen(url)
    return set(response.read().decode("utf-8").splitlines())
```

この関数では、GitHub上の日本語ストップワードリストをダウンロードし、セット形式で返します。
これにより、不要な単語を効率的に除外できます。

### 5. 共通キーワードの抽出

最後に、2人のユーザーの投稿データから共通のキーワードを抽出します。

以下は、共通キーワードを抽出する関数のコードです：

```python
from tinysegmenter import TinySegmenter

def extract_common_keywords(texts1, texts2, top_n=10):
    stopwords_ja = load_stopwords()
    segmenter = TinySegmenter()
    tokens1 = segmenter.tokenize(" ".join(texts1))
    tokens2 = segmenter.tokenize(" ".join(texts2))
    keywords1 = [t for t in tokens1 if t not in stopwords_ja and len(t.strip()) > 1]
    keywords2 = [t for t in tokens2 if t not in stopwords_ja and len(t.strip()) > 1]
    return list(set(keywords1) & set(keywords2))[:top_n]
```

この関数では、以下の処理を行っています：

1. ストップワードを除外。
2. TinySegmenterを使用して日本語のトークン化を実施。
3. トークン化された単語リストから、共通するキーワードを抽出。

`top_n` 引数を指定することで、上位N個の共通キーワードを取得できます。

## 実行例

以下のコマンドでツールを実行できます：

### 実データを使用する場合

```bash
python src/main.py --user1 <ユーザー1のID> --user2 <ユーザー2のID>
```

### モックデータを使用する場合

```bash
python src/main.py --mock
```

実行結果として、2人のユーザー間で共通するキーワードが表示されます。

## まとめ

「オモイアイ」は、自然言語処理を活用して、X（旧Twitter）の投稿データから共通点を見つけるツールです。
本記事では、ツールの処理の流れをコードを交えながら解説しました。

今後は、Webアプリケーション化や感情分析の導入など、さらなる機能拡張を予定しています。
ぜひ、このツールを活用して、新しいつながりを見つけてみてください！