svmでサイコパスシステム作ってみたかったけど出来なかった話
これは結局うまく行かなかったもののただのメモ書きですのであしからず。
なんの参考にもならないよ!
でも、もし賢い方でしたら僕に教えてください!!
背景の背景
↑これがわかりやすかったので、使ってみようかなって思ったのが始まりです。
背景
犯罪者のツイッターアカウントとか結構残ってますよね。
最近だとアイドルを刺しまくった事件とか、ちょっと前だと浦安での通り魔とかの人のツイッターアカウントが話題になっていたと思うのです。
そういう人のつぶやきって、頻出単語も全然違うけどちょっと似てるところを感じたのが作ろうと思ったきっかけです。
それらのつぶやきデータを使って機械学習とかしてこのアカウントのは危ない人かどうか判定をできるようにしてみたかったのです。
とりあえず、犯罪者のつぶやきに似ている人は危ない人ということです。
犯罪者のツイッター情報あつめ
調べたら出てくるものですね・・・
こういう風に、ネットで調べて出てきた人のツイッターのつぶやきのテキストを280メガバイト文を学習データに使いました。
- 問題点
犯罪を犯した人のツイッターアカウントってすぐに凍結されちゃう。
アイドル刺した人も凍結されてます。さっさと保存しておけばよかった。
とりあえず、おこなったことですが、、、
3グラムに分けて素性を作る
自然言語処理だとNグラム使うのがポピュラーらしいのでとりあえず、文章を分かち書きして、3グラムずつにわけて素性にしました。
文を形態素で分けることを分かち書きといいまして、mecabさんで簡単に出来ます。
今から遊べる人ー
を3グラムに分けると
となります。
こういうことです!
同じ場所に同じ単語があれば、素性の値も同じにして、素性を作っていきました。
という文章があれば、素性は以下のようになります。
そうして、犯罪者の人から作った素性のラベルは+1一般人からの素性のラベルは-1としました。
ちなみに一般人は僕が見る限り、「今日はカラオケ行った!」とか、いつも今日もしょうもないことつぶやいているわ〜って思わせてくれる方たちのつぶやき、280メガバイトを入れました。
↓が中身です。
素性を作ったプログラムです。
スパゲッティコードって、本来は長い紆余曲折を経て作り出されるもののことだけど、僕は頭がスパゲッティなのでいきなりスバゲティを茹でるよ。
— alaki paca / 荒木パカ (@arabiiiiiiiiiii) 2017年2月12日
僕頭がスパゲッティなので、容量の悪い書き方していますが、
# -*- encoding: utf-8 -*-
#3/2作成
import sys
import re
from nltk.stem.porter import PorterStemmer
import MeCab
import glob
phyco = open("/home/araki/デスクトップ/phyco/twitter/box/phyco_feature.txt","w")
tagger = MeCab.Tagger('-Owakati')#これで分かち書きができる
dic = {}
feature_line =
id=1
files = glob.glob('/home/araki/デスクトップ/phyco/twitter/plus/*.txt') #table内のtxtファイルすべてを取得
for file in files: #txtファイルの数で回す。
fp1=open(file,'r')
for line in fp1:
line = re.sub(r"@[_0-9a-zA-Z]+","",line)#@xxxxxxを消す
line = re.sub(r"http://[_0-9a-zA-Z./]+","",line)#urlを消す
line = re.sub(r"<br />","\n",line)#<br />改行を消す
line = re.sub(r" ","",line)#空白も消す。
line_mecab=tagger.parse(line)#分かち書きを行う
line_mecab_split = line_mecab.split(" ")
line_len = len(line_mecab_split)
for line_sp_seg in range(0,line_len-3):
phyco.write("+1 ")
feature_line =
for sp_count in range(0,3):
s = str(sp_count+1) +"&"+line_mecab_split[line_sp_seg+sp_count]#数字&言葉を入れていく 例 2&言葉
if not s in dic:#辞書の中になかったら
feature_line.append(str(id)+":1 ")
dic[s] = id#辞書に数字をあてがう
id += 1
else:#辞書の中にあったら
feature_line.append(str(dic[s])+":1 ")
num_files = [(int(re.search("([0-9]+):", x).group(1)), x) for x in feature_line]#ソート
num_files.sort(key=lambda x:x[0])
feature_line = [x[1] for x in num_files]
for k in range(0,len(feature_line)):
phyco.write(feature_line[k])
phyco.write("\n")
'''
files = glob.glob('/home/araki/デスクトップ/phyco/twitter/mainus/*.txt') #table内のtxtファイルすべてを取得
for file in files: #txtファイルの数で回す。
fp1=open(file,'r')
for line in fp1:
line = re.sub(r"@[_0-9a-zA-Z]+","",line)#@xxxxxxを消す
line = re.sub(r"http://[_0-9a-zA-Z./]+","",line)#urlを消す
line = re.sub(r"<br />","\n",line)#<br />改行を消す
line = re.sub(r" ","",line)#空白も消す。
line_mecab=tagger.parse(line)#分かち書きを行う
line_mecab_split = line_mecab.split(" ")
line_len = len(line_mecab_split)
for line_sp_seg in range(0,line_len-3):
phyco.write("-1 ")
feature_line = []
for sp_count in range(0,3):
s = str(sp_count+1) +"&"+line_mecab_split[line_sp_seg+sp_count]#数字&言葉を入れていく 例 2&言葉
if not s in dic:#辞書の中になかったら
feature_line.append(str(id)+":1 ")
dic[s] = id#辞書に数字をあてがう
id += 1
else:#辞書の中にあったら
feature_line.append(str(dic[s])+":1 ")
num_files = [(int(re.search("([0-9]+):", x).group(1)), x) for x in feature_line]
num_files.sort(key=lambda x:x[0])
feature_line = [x[1] for x in num_files]
for k in range(0,len(feature_line)):
phyco.write(feature_line[k])
phyco.write("\n")
'''
libsvmを使ってみようとおもったけど、わからなかった。
libsvmさんを使ってスケーリングして、学習と思ったのですが・・・
svm-scaleは通ったのに、svm-trainは出来ないかった・・・
よくわからない・・・
とりあえず、スケーリングなしで学習してみました。
そして、学習用データに対してsvm-predictを使ってみたら、
5文交差検定
54%ってほとんど使い物にならないのでは・・・
偉い方に聞いてみた
偉い方ととは学校の先生のことです。
犯罪者のツイートだからといって、いつでも危ないことをつぶやいているわけではない。
同じ言葉を一般人も犯罪者も言っているはず、それだとノイズが多いため予測はできなさそう。
tf-idfを使ってありきたりな言葉を外したりCNN(Convolutional Neural Network)を使ったりword2vecを使って単語の塊をベクトルにして見た方がいいのではと言われた。
あとは言語からセンチメントを測ったりして素性を増やしたり、
いっそ、このツイートは危ないことを行っているから☓、これは普通のことを行っているから◯みたいにして素性にしたほうがいいのではないかと言われたが、それではキーワードマッチングになってしまう。
あとは。根本的にデータ量が少ないとも言われましたね。
svm-predictがわからない。
とりあえず判別させてみたいなーとおもってsvm-predictを自分のアカウント情報を入れて試してみました。
先頭列に正解のラベルが付きますが、これは正解率の計算のために使われるだけで、もちろん分類の際には利用されません。
っと書かれていたため、とりあえず0のラベルを付けて行ってみたらAccuracyは0になるのは当たり前だとして、output.txtの中身が全部1になっていました。
犯罪者データの内の一人の素性を使ってみてもラベルが1なのでAccuracyは100ですがoutput.txtは全部1になっていました。
わからない・・・
確率推定もできない。
確率推定をしたらサイコパス度を図れるかと思ったので素性作るプログラムの+1を1に-1を0に変えて-b 1 のコマンドを試してみたのですが、、、
model does not support probablity estimatesと出てきた・・・
だめだ。
だれも俺を愛さない。
っとまでが今の現状です。