import asyncio
import discord
from discord.ext import commands, tasks
from discord import Interaction, Member, app_commands, ui
from discord.app_commands import Group, command
from discord.ext.commands import GroupCog
import traceback
import os
import csv
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
class ac_learn(commands.Cog):
def __init__(self, bot):
# 必要なファイルを読み取る
self.bot = bot
self.message_id = {
0: '問題なし',
1: '嫌がらせ',
2: '不適切な内容',
3: '詐欺・スパム'
}
@commands.Cog.listener()
async def on_ready(self):
self.check = app_commands.ContextMenu(
name='check',
callback=self.check_text
)
self.bot.tree.add_command(self.check)
self.learn = app_commands.ContextMenu(
name='learn',
callback=self.learn_text
)
self.bot.tree.add_command(self.learn)
async def check_text(self, interaction: discord.Interaction, message: discord.Message) -> None:
await interaction.response.defer(ephemeral=True)
try:
vanguard = Vanguard()
res = vanguard.check(message.content)
pred = self.message_id[res[0]]
embed = discord.Embed(
title=f"{interaction.user.display_name} によって送信されたメッセージ",
description=f"{message.content}\n\nこのメッセージの判定は\n{pred}",
color=0x00ff00
)
if res[0] == 0:
embed.color = 0x00ff00
else:
embed.color = 0xff0000
embed.set_thumbnail(url=message.author.display_avatar)
await interaction.followup.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="不明なコマンド",
description=f"エラーが発生しました。\n{e}",
color=0xff0000
)
await interaction.followup.send(embed=embed)
async def learn_text(self, interaction: discord.Interaction, message: discord.Message) -> None:
embed = discord.Embed(
title=f"{interaction.user.display_name} によって送信されたメッセージ",
description=f"{message.content}",
color=0x00ff00
)
embed.set_thumbnail(url=message.author.display_avatar)
try:
view = discord.ui.View(timeout=None)
view.add_item(SelectList(self.bot, interaction, message))
await interaction.response.send_message(embed=embed, view=view, ephemeral=True)
except Exception as e:
print(e)
class SelectList(discord.ui.Select):
def __init__(self, bot, interaction, message):
self.bot = bot
self.path = '/home/neko/pylearn/suzuka-vanguard.csv'
self.message = message
options = []
options.append(discord.SelectOption(
label="問題なし",
value="0",
description="このチャットテキストは問題ありません"
))
options.append(discord.SelectOption(
label="嫌がらせ",
value="1",
description="なりすましを含む、個人に対する攻撃"
))
options.append(discord.SelectOption(
label="不適切な内容",
value="2",
description="迷惑行為および、不適切な内容、下品な言葉の使用、悪態等"
))
options.append(discord.SelectOption(
label="詐欺・スパム",
value="3",
description="詐欺、スパムなど。刑務所にぶちこまれる楽しみにしておいて下さい!いいですね!"
))
# options.append(discord.SelectOption(
# label="",
# value="",
# description=""
# ))
# options.append(discord.SelectOption(
# label="",
# value="",
# description=""
# ))
# options.append(discord.SelectOption(
# label="",
# value="",
# description=""
# ))
super().__init__(placeholder="このテキストチャットはどうですか?", options=options, min_values=1, max_values=1)
async def callback(self, interaction: discord.Integration):
await interaction.response.defer(ephemeral=True)
try:
if (interaction.user.id in self.bot.owner_ids):
values = int(self.values[0])
with open(self.path, 'a', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
for text, label in zip([self.message.content], [values]):
writer.writerow([text, label])
embed = discord.Embed(
title="不明なコマンド",
description=f"書き込みました",
color=0x00ff00
)
await interaction.followup.send(embed=embed, ephemeral=True)
else:
raise("権限がありません")
except Exception as e:
embed = discord.Embed(
title="不明なコマンド",
description=f"エラーが発生しました。\n{e}",
color=0xff0000
)
await interaction.followup.send(embed=embed, ephemeral=True)
class Vanguard:
def __init__(self):
# ロード
self.texts = []
self.labels = []
self.path = '/home/neko/pylearn/suzuka-vanguard.csv'
with open(self.path, mode='r', newline='', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
self.texts.append(row[0])
self.labels.append(int(row[1]))
def check(self, message):
X_train, X_test, y_train, y_test = train_test_split(self.texts, self.labels, test_size=0.2, random_state=42)
# TF-IDFベクトル化
vectorizer = TfidfVectorizer()
X_train_vectorized = vectorizer.fit_transform(X_train)
X_test_vectorized = vectorizer.transform(X_test)
# モデルのトレーニング(ロジスティック回帰を使用)
# model = LogisticRegression()
# model.fit(X, self.labels)
svm_classifier = SVC(kernel='linear')
svm_classifier.fit(X_train_vectorized, y_train)
# テストデータで予測
predictions = svm_classifier.predict(X_test_vectorized)
# 精度の評価
accuracy = accuracy_score(y_test, predictions)
print(f"精度: {accuracy}")
# 分類したい文字列
new_text = [message]
# ベクトル化
# new_text_vectorized = vectorizer.transform([new_text])
# モデルで分類
# prediction = model.predict(new_text_vectorized)
new_message_vectorized = vectorizer.transform(new_text)
prediction_new = svm_classifier.predict(new_message_vectorized)
return prediction_new
async def setup(bot):
await bot.add_cog(ac_learn(bot))