コピペで音声データの作成アプリが出来るようになる【Windows】【HTML】【JavaScript】【VBS】
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
背景・目的
なんのキッカケかは忘れましたが、音声データの作成をやってみたくなり、調べたところ簡単だったので、雑ですが、音声データ作成アプリっぽいものを作りました。
動作環境
・Windows 7
・HTML
・JavaScript
・VBScript
また、音声読み上げに関するランタイム、ライブラリは画像の通りです。
プログラム
speak.html ソースコード
<html>
<head>
<title>テキスト読み上げ音声ファイルメーカー</title>
<script language="javascript" type="text/javascript">
function OnLinkClickAudition() {
var txt = document.form1.msg.value;
var sh = new ActiveXObject("WScript.Shell");
sh.Exec("cmd /C wscript C:\\Users\\UserName\\Desktop\\speak\\Speak_Audition.vbs " + txt);
sh.null;
}
function OnLinkClickOutput() {
var txt = document.form1.msg.value;
var sh = new ActiveXObject("WScript.Shell");
sh.Exec("cmd /C wscript C:\\Users\\UserName\\Desktop\\speak\\Speak_Output.vbs " + txt);
sh.null;
}
</script>
<style type="text/css">
.btn-real-dent {
/*周りの凹み*/
display: inline-block;
position: relative;
text-decoration: none;
color: rgba(3, 169, 244, 0.54);
width: 100px;
height: 100px;
border-radius: 50%;
text-align: center;
background: #f7f7f7;
box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.08);
}
.btn-real-dent i {
/*ボタン自体*/
position: absolute;
content: '';
width: 80px;
height: 80px;
line-height: 80px;
left: 10px;
top: 9px;
border-radius: 50%;
font-size: 30px;
background-image: linear-gradient(#e8e8e8 0%, #d6d6d6 100%);
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.66);
box-shadow: inset 0 2px 0 rgba(255,255,255,0.5), 0 2px 2px rgba(0, 0, 0, 0.19);
border-bottom: solid 2px #b5b5b5;
}
.btn-real-dent .fa:active {
box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 2px rgba(0, 0, 0, 0.19);
border-bottom: solid 2px #d8d8d8;
}
.textlines {
padding: 0.5em; /* 内側の余白量 */
background-color: snow; /* 背景色 */
width: 40em; /* 横幅 */
height: 350px; /* 高さ */
font-size: 1em; /* 文字サイズ */
line-height: 1.2; /* 行の高さ */
}
</style>
</head>
<body>
<form name="form1">
<p>
<textarea name="msg" cols="30" rows="7" class="textlines"></textarea>
</p>
</form>
<a href="#" class="btn-real-dent" onClick="OnLinkClickAudition()">
<i class="fa fa-home">試聴</i>
</a>
<a href="#" class="btn-real-dent" onClick="OnLinkClickOutput()">
<i class="fa fa-home">出力</i>
</a>
</body>
</html>
Speak_Audition.vbs ソースコード
cntArgs = WScript.Arguments.Count
If cntArgs <> 1 Then
WScript.Echo "引数が" & intArgsCount & "個渡されました。" & vbCrLf _
& "指定可能な引数の数は 1 個なので処理を中止します。"
' 処理を中断
WScript.Quit
End If
arg = WScript.Arguments(0)
Set tts = WScript.CreateObject("Speech.SpVoice")
tts.Rate = 2
tts.Speak(arg)
Speak_Output.vbs ソースコード
cntArgs = WScript.Arguments.Count
If cntArgs <> 1 Then
WScript.Echo "引数が" & intArgsCount & "個渡されました。" & vbCrLf _
& "指定可能な引数の数は 1 個なので処理を中止します。"
' 処理を中断
WScript.Quit
End If
arg = WScript.Arguments(0)
Set tts = WScript.CreateObject("Speech.SpVoice")
Set stream = WScript.CreateObject("Speech.SpFileStream")
tts.Rate = 2
stream.Open "speak.wav", 3
Set tts.AudioOutputStream = stream
tts.Speak(arg)
stream.Close
コメント
使い道はあまり思いつかないですが、たった 3 つのファイルを作成するだけで音声データが作成出来ました。
以上
python で単語感情極性対応表を使った感情分析〜失敗!?〜
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
背景・目的
前回の記事で『単語感情極性対応表』という辞書の使い方について練習しました。
今度は実際に使ってみます。
動作環境
・Windows 7
・winpython 64bit 3.4.4
プログラム
ソースコード
#-*- encoding: utf-8 -*-
from pyknp import Juman
import pandas as pd
strlen = 10
###############################################################################
# 形態素解析
###############################################################################
# 形態素分析器 juman のインスタンス作成
juman = Juman(jumanpp=False)
# 形態素解析
text = '最近、痛ましい事件や事故のニュースが多い。'
result = juman.analysis(text)
# 形態素解析結果表示 および numpy 配列作成
print('*** 形態素解析結果 ***')
print('原文'.ljust(strlen, ' ') + '原形'.ljust(strlen, ' ') + '品詞'.ljust(strlen, ' ') + '分類'.ljust(strlen, ' '))
targetwords = []
for mrph in result.mrph_list():
print(mrph.midasi.ljust(strlen, ' ') + mrph.genkei.ljust(strlen, ' ') + mrph.hinsi.ljust(strlen, ' ') + mrph.bunrui.ljust(strlen, ' '))
targetwords.append(mrph.genkei)
print()
###############################################################################
# 単語感情極性解析
###############################################################################
# 単語感情極性対応表 のパスを設定する
filepath='C:\\Users\\UserName\\Desktop\\dictionary\\pn_table.txt'
print('*** 単語感情極性対応表 ***')
print('dictionary path = ' + filepath)
print()
# pandas で読み込む
pn_table = pd.read_csv(filepath, engine='python', encoding='shift_jis', sep=':', names=('Word','Reading','POS','PN'))
# 語のリスト と PN 値のリスト の作成
word_list = list(pn_table['Word'])
pn_list = list(pn_table['PN'])
# 語をキーとした PN 値辞書の作成
pn_dict = dict(zip(word_list, pn_list))
# 単語感情極性解析
print('*** 単語感情極性解析結果 ***')
for w in targetwords:
if w in pn_dict.keys():
print(w.ljust(strlen, ' ') + str(pn_dict[w]).ljust(strlen, ' '))
else:
print(w.ljust(strlen, ' ') + '無し'.ljust(strlen, ' '))
print()
結果
In [1]: runfile('C:/WPy64-3720/settings/.spyder-py3/jumanknptest5.py', wdir='C:/WPy64-3720/settings/.spyder-py3')
*** 形態素解析結果 ***
原文 原形 品詞 分類
最近 最近 名詞 時相名詞
、 、 特殊 読点
痛ましい 痛ましい 形容詞 *
事件 事件 名詞 普通名詞
や や 助詞 接続助詞
事故 事故 名詞 普通名詞
の の 助詞 接続助詞
ニュース ニュース 名詞 普通名詞
が が 助詞 格助詞
多い 多い 形容詞 *
。 。 特殊 句点
*** 単語感情極性対応表 ***
dictionary path = C:\Users\UserName\Desktop\dictionary\pn_table.txt
*** 単語感情極性解析結果 ***
最近 -0.0125929
、 無し
痛ましい -0.997224
事件 -0.8599600000000001
や -0.278384
事故 -0.9970530000000001
の 無し
ニュース -0.391963
が 無し
多い 無し
。 無し
In [2]:
コメント
分析速度は悪くなかったと思います。
『最近』や『ニュース』がネガティブな数値を示しています。
辞書を見てみると、そんなにネガティブではない単語にネガティブな数値が与えられているモノが多数あります。
ポジティブとネガティブの閾値など、単語感情極性対応表をもっと理解する必要がありそうです。
以上
python で 感情分析〜単語感情極性対応表を使う練習〜
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
背景・目的
『感情 python 』で検索すると『単語感情極性対応表』という辞書にたどり着きました。
ひとまず感触を確かめてみます。
動作環境
・Windows 7
・winpython 64bit 3.4.4
プログラム
単語感情極性対応表のダウンロード
・『単語感情極性対応表 ダウンロード』でネット検索・単語感情極性対応表のダウンロードサイトへのリンクをクリック
・ダウンロードサイトから日本語の辞書を選択
・全てを選択、テキストエディタにコピペしてテキストを保存
ソースコード
# -*- coding: utf-8 -*-
import pandas as pd
# 単語感情極性対応表 のパスを設定する
filepath='C:\\Users\\UserName\\Desktop\\dictionary\\pn_table.txt'
print('dictionary path = ' + filepath)
print()
# pandas で読み込む
pn_table = pd.read_csv(filepath, engine='python', encoding='shift_jis', sep=':', names=('Word','Reading','POS','PN'))
# 語のリスト と PN 値のリスト の作成
word_list = list(pn_table['Word'])
pn_list = list(pn_table['PN'])
# 語をキーとした PN 値辞書の作成
pn_dict = dict(zip(word_list, pn_list))
# 辞書テスト
text = '良い'
if text in pn_dict.keys():
print(text, pn_dict[text])
else:
print(text, '無し')
text = '悪い'
if text in pn_dict.keys():
print(text, pn_dict[text])
else:
print(text, '無し')
結果
In [1]: runfile('C:/WPy64-3720/settings/.spyder-py3/pn_table-test0.py', wdir='C:/WPy64-3720/settings/.spyder-py3')
dictionary path = C:\Users\UserName\Desktop\dictionary\pn_table.txt
良い 0.9999950000000001
悪い -1.0
In [2]:
コメント
参照を多く行う場合は dictionary と相場が決まっています。
これが出来れば、あとは形態素解析した文節を辞書で参照していけば良いだけですね。
以上
C# の HashSet と SortedSet
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
背景・目的
履歴を管理したり、重複を避ける場合には HashSet か SortedSet を使うのが王道だと思います。
HashSet と SortedSet がいったいどれほどの威力なのかを確かめました。
動作環境
・Windows 7
・Visual Studio 2017
プログラム
ソースコード
重複のあるランダムな List から重複のない List を作成します。なお、 1 行目の #define のコメントを外すと、 List の値を出力する事ができるようになります。
//#define OUTPUT_VALUES
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace speed_comparison_duplicate
{
class Program
{
static void Main(string[] args)
{
///////////////////////////////////////////////////////////////////////////////
// 重複のあるランダムな values List を作成し、
// values List から重複のない List を作成する。
///////////////////////////////////////////////////////////////////////////////
// 重複のあるランダムな values List の作成
// ある数の配列を用意する。
// 重複がない様に連番で初期化する。
// 乱数を使って配列の値を入れ替えて並び順をランダムにする。
// ランダムに並べ替えた配列を List に 2 回代入する。
///////////////////////////////////////////////////////////////////////////////
// values List から重複のない List の作成
// values List を調べて追加されたことのない要素で有れば、
// List に要素を追加する。
// パターンA
// Contains メソッドで values List の有無を調べる
// パターンB
// BinarySearch メソッドで values List の有無を調べる
// パターンC
// HashSet で重複のない List を作成する
// パターンD
// SortedSet で重複のない List を作成する
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// 重複のあるランダムな values List の作成
// ある数の配列を用意する。
// 重複がない様に連番で初期化する。
// 乱数を使って配列の値を入れ替えて並び順をランダムにする。
///////////////////////////////////////////////////////////////////////////////
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
// cntArray 個の配列作成
int cntArray = 30000;
int[] values = new int[cntArray];
// 配列の初期化
int startValue = 523;
for (int i = 0; i < values.Length; i++)
{
values[i] = startValue + i;
}
// 乱数発生器作成する
Random r = new Random();
// 配列を cntSwap 回シャッフルする
int cntSwap = cntArray;
for (int i = 0; i < cntSwap; i++)
{
// 入れ替える配列インデックスをランダムに選定する
int j = r.Next(0, values.Length);
// 配列の値の入れ替え
int tmpJ = values[j];
values[j] = values[i];
values[i] = tmpJ;
}
// cntDuplicate 個の重複のあるランダムな values List の作成
int cntDuplicate = 2;
List values_List = new List();
for (int i = 0; i < cntDuplicate; i++)
{
for (int j = 0; j < values.Length; j++)
{
values_List.Add(values[j]);
}
}
sw.Stop();
Console.WriteLine("配列作成終了");
string filepath = "C:\\Users\\UserName\\Desktop\\log.txt";
StreamWriter w = new StreamWriter(filepath, false, Encoding.GetEncoding("shift_jis"));
TimeSpan ts = sw.Elapsed;
w.Write("* 値のランダムな values List の個数:");
w.WriteLine(values_List.Count);
w.Write(" 重複数:");
w.WriteLine(cntDuplicate);
w.Write("値のランダムな values List の作成時間:");
w.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
#if (OUTPUT_VALUES)
w.WriteLine(string.Format("{0,10}", "Index") + ":" + string.Format("{0,20}", "Values"));
for (int i = 0; i < values_List.Count; i++)
{
w.WriteLine(string.Format("{0,10}", i) + ":" + string.Format("{0,20}", values_List[i]));
}
#endif
///////////////////////////////////////////////////////////////////////////////
// values List の空ループの時間調査
///////////////////////////////////////////////////////////////////////////////
sw.Reset();
sw.Start();
for (int i = 0; i < values_List.Count; i++)
{
}
sw.Stop();
Console.WriteLine("空ループ終了");
ts = sw.Elapsed;
w.WriteLine("");
w.Write("* values List の空ループ時間:");
w.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
///////////////////////////////////////////////////////////////////////////////
// values List から重複のない List の作成
// values List を調べて追加されたことのない要素で有れば、
// List に要素を追加する。
// パターンA
// Contains メソッドで values List の有無を調べる
///////////////////////////////////////////////////////////////////////////////
sw.Reset();
sw.Start();
List list1 = new List();
for(int i = 0; i < values_List.Count; i++)
{
if (!list1.Contains(values_List[i]))
{
list1.Add(values_List[i]);
}
}
sw.Stop();
Console.WriteLine(" Contains 終了");
ts = sw.Elapsed;
w.WriteLine("");
w.Write("* 重複のない list1 の個数:");
w.WriteLine(list1.Count);
w.Write(" 重複のない list1 の作成時間:");
w.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
#if (OUTPUT_VALUES)
w.WriteLine(string.Format("{0,10}", "Index") + ":" + string.Format("{0,20}", "Values"));
for (int i = 0; i < list1.Count; i++)
{
w.WriteLine(string.Format("{0,10}", i) + ":" + string.Format("{0,20}", list1[i]));
}
#endif
///////////////////////////////////////////////////////////////////////////////
// values List から重複のない List の作成
// values List を調べて追加されたことのない要素で有れば、
// List に要素を追加する。
// パターンB
// BinarySearch メソッドで values List の有無を調べる
///////////////////////////////////////////////////////////////////////////////
sw.Reset();
sw.Start();
List list2 = new List();
for (int i = 0; i < values_List.Count; i++)
{
int idx = list2.BinarySearch(values_List[i]);
if (idx < 0)
{
list2.Add(values_List[i]);
list2.Sort();
}
}
sw.Stop();
Console.WriteLine(" BinarySearch 終了");
ts = sw.Elapsed;
w.WriteLine("");
w.Write("* 重複のない list2 の個数:");
w.WriteLine(list1.Count);
w.Write(" 重複のない list2 の作成時間:");
w.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
#if (OUTPUT_VALUES)
w.WriteLine(string.Format("{0,10}", "Index") + ":" + string.Format("{0,20}", "Values"));
for (int i = 0; i < list2.Count; i++)
{
w.WriteLine(string.Format("{0,10}", i) + ":" + string.Format("{0,20}", list2[i]));
}
#endif
///////////////////////////////////////////////////////////////////////////////
// values List から重複のない List の作成
// values List を調べて追加されたことのない要素で有れば、
// List に要素を追加する。
// パターンC
// HashSet で重複のない List を作成する
///////////////////////////////////////////////////////////////////////////////
sw.Reset();
sw.Start();
HashSet hash = new HashSet();
for (int i = 0; i < values_List.Count; i++)
{
hash.Add(values_List[i]);
}
List hashList = hash.ToList();
sw.Stop();
Console.WriteLine(" HashSet 終了");
ts = sw.Elapsed;
w.WriteLine("");
w.Write("* 重複のない hash の個数:");
w.WriteLine(hash.Count);
w.Write(" 重複のない hash の作成時間:");
w.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
#if (OUTPUT_VALUES)
w.WriteLine(string.Format("{0,10}", "Index") + ":" + string.Format("{0,20}", "Values"));
for (int i = 0; i < hashList.Count; i++)
{
w.WriteLine(string.Format("{0,10}", i) + ":" + string.Format("{0,20}", hashList[i]));
}
#endif
///////////////////////////////////////////////////////////////////////////////
// values List から重複のない List の作成
// values List を調べて追加されたことのない要素で有れば、
// List に要素を追加する。
// パターンD
// SortedSet で重複のない List を作成する
///////////////////////////////////////////////////////////////////////////////
sw.Reset();
sw.Start();
SortedSet sset = new SortedSet();
for (int i = 0; i < values_List.Count; i++)
{
sset.Add(values_List[i]);
}
List ssetList = sset.ToList();
sw.Stop();
Console.WriteLine(" SortedSet 終了");
ts = sw.Elapsed;
w.WriteLine("");
w.Write("* 重複のない sset の個数:");
w.WriteLine(hash.Count);
w.Write(" 重複のない sset の作成時間:");
w.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
#if (OUTPUT_VALUES)
w.WriteLine(string.Format("{0,10}", "Index") + ":" + string.Format("{0,20}", "Values"));
for (int i = 0; i < ssetList.Count; i++)
{
w.WriteLine(string.Format("{0,10}", i) + ":" + string.Format("{0,20}", ssetList[i]));
}
#endif
///////////////////////////////////////////////////////////////////////////////
// 終了処理
///////////////////////////////////////////////////////////////////////////////
w.Close();
Console.WriteLine("");
Console.Write("何かキーを押して下さい。");
Console.ReadKey();
}
}
}
結果
ちょっと見づらいですが、結果です。
テキストエディタにコピペしてもらうと、もっと見やすくなると思います。
* 値のランダムな values List の個数:60000
重複数:2
値のランダムな values List の作成時間: 0時間 0分 0秒 1ミリ秒
* values List の空ループ時間: 0時間 0分 0秒 0ミリ秒
* 重複のない list1 の個数:30000
重複のない list1 の作成時間: 0時間 0分 2秒 619ミリ秒
* 重複のない list2 の個数:30000
重複のない list2 の作成時間: 0時間 0分 8秒 441ミリ秒
* 重複のない hash の個数:30000
重複のない hash の作成時間: 0時間 0分 0秒 1ミリ秒
* 重複のない sset の個数:30000
重複のない sset の作成時間: 0時間 0分 0秒 17ミリ秒
コメント
HashSet と SortedSet の威力が絶大でした。
HashSet と SortedSet では HashSet が圧倒的に早かったです。
SortedSet はソートしてる分遅かったのでしょうか。
以上
Windows で JUMAN と KNP と pyknp を使う
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
背景・目的
自然言語処理で感情分析やりたいと思っています。
感情分析の前処理として、ちょっと調べてみると、
JUMAN という形態素解析器
KNP という構文解析器
pyknp という Python バインディング
を使うのが良さそうでした。
しかし、 Windows 、 python3 という組み合わせでは JUMAN/KNP が shift-jis で python3 が utf-8 なので、 コーデックエラーが出ます。
このエラー回避にかなりハマったので、とりあえず、インストールして、形態素解析までたどり着いた方法をまとめます。
動作環境
・Windows 7
・winpython 64bit 3.7.2.0
・JUMAN 7.0
・KNP 4.11
・pyknp 0.22
事前に winpython はインストールされていることを前提とします。
winpython のインストールディレクトリは下記とします。
インストールディレクトリ:C:\WPy64-3720
プログラム
インストール
インストールについては以下のサイトを参考にしました。Windows 7 64bit に JUMAN/KNP(構文解析器)を導入しました - Qiita
リンクのサイト通りにやると特になんの問題も無く下記がインストール出来ました。
• KNP Ver.4.11 (Windows 64bit版)
• Juman Ver 7.0 (Windows 64bit版)
• pyknp(pyknp-0.22.tar.gz)
なお、 KNP と Juman のインストールフォルダは全てデフォルトにしています。
この後、エラー回避で対象となるフォルダ、ファイルを示していますが、デフォルトインストールした場合のフォルダ、ファイルになりますので、ご了承下さい。
【参考サイトの補足】
python コマンドは WinPython Command Prompt から実行します。
テストソースコード①
#-*- encoding: utf-8 -*-
from pyknp import Juman
juman = Juman(jumanpp=False)
result = juman.analysis("最近、痛ましい事件や事故のニュースが多い。")
for mrph in result.mrph_list():
print (mrph.midasi)
テストソースコード②
# -*- coding: utf-8 -*-
import pyknp
knp = pyknp.KNP()
line = '最近、痛ましい事件や事故のニュースが多い。'
result = knp.parse(line)
result.draw_tag_tree()
エラーコード
テストソースコードを実行すると、コーデックエラーとなり、以下の様なエラーメッセージが表示されました。
エラー回避
参考サイトによる pyknp のエラー回避
インターネットに参考になるサイトがありました。サイトの内容とエラーが合っているので、やってみました。
PyKNPをWindows10にインストールする(お土産付き) - Qiita
ディレクトリ:C:\Program Files\pyknp\pyknp-0.22.tar\dist\pyknp-0.22\pyknp-0.22\pyknp\juman
ファイル:juman.py
52行目
変更前
self.process = subprocess.Popen('bash -c "%s"' % command, env=env,
変更後
self.process = subprocess.Popen('"%s"' % command, env=env,
ディレクトリ:C:\Program Files\pyknp\pyknp-0.22.tar\dist\pyknp-0.22\pyknp-0.22\pyknp\juman
ファイル:juman.py
66行目
変更前
def query(self, sentence, pattern):
assert(isinstance(sentence, six.text_type))
self.process.stdin.write(sentence.encode('utf-8')+six.b('\n'))
self.process.stdin.flush()
result = ""
while True:
line = self.stdouterr.readline()[:-1].decode('utf-8')
if re.search(pattern, line):
break
result = "%s%s\n" % (result, line)
return result
変更後
def query(self, sentence, pattern, encoding="ms932"):
assert(isinstance(sentence, six.text_type))
self.process.stdin.write(sentence.encode(encoding)+six.b('\n'))
self.process.stdin.flush()
result = ""
while True:
line = self.stdouterr.readline()[:-1].decode(encoding)
if re.search(pattern, line):
break
result = "%s%s\n" % (result, line)
return result
このエラー回避でエラーメッセージに変化が現れた。
juman が見つからないといったエラーになった。
そして、独自にエラー回避を行った。
独自のエラー回避①
エラーメッセージで knp.py の処理が表示されていた。KNP のコンストラクタで jumanpp を強制的に使用する初期化だった。
jumanpp はそもそもインストールしていないので、コンストラクタを juman を使用する初期化に書き換えた。
ディレクトリ:C:\WPy64-3720\python-3.7.2.amd64\Lib\site-packages\pyknp\knp
ファイル:knp.py
30行目
変更前
def __init__(self, command='knp', server=None, port=31000, timeout=60,
option='-tab', rcfile='', pattern=r'EOS',
jumancommand='jumanpp', jumanrcfile='', jumanpp=True):
self.command = command
self.server = server
self.port = port
self.timeout = timeout
self.option = option.split()
self.rcfile = rcfile
self.pattern = pattern
self.socket = None
self.subprocess = None
self.jumanpp = jumanpp
変更後
def __init__(self, command='knp', server=None, port=31000, timeout=60,
option='-tab', rcfile='', pattern=r'EOS',
jumancommand='jumanpp', jumanrcfile='', jumanpp=False):
self.command = command
self.server = server
self.port = port
self.timeout = timeout
self.option = option.split()
self.rcfile = rcfile
self.pattern = pattern
self.socket = None
self.subprocess = None
self.jumanpp = jumanpp
ここで、またエラーとなった。
コーデックを utf-8 で行う処理が残っていた。
そこで、独自のエラー回避②を行った。
独自のエラー回避②
参考サイトによる pyknp のエラー回避とやっている事は同じです。
ディレクトリ:C:\WPy64-3720\python-3.7.2.amd64\Lib\site-packages\pyknp\juman
ファイル:process.py
64行目
変更前
def query(self, sentence, pattern):
assert(isinstance(sentence, six.text_type))
self.process.stdin.write(sentence.encode('uft-8')+six.b('\n'))
self.process.stdin.flush()
result = ""
while True:
line = self.stdouterr.readline().rstrip().decode('uft-8')
if re.search(pattern, line):
break
result = "%s%s\n" % (result, line)
return result
変更後
def query(self, sentence, pattern, encoding="ms932"):
assert(isinstance(sentence, six.text_type))
self.process.stdin.write(sentence.encode(encoding)+six.b('\n'))
self.process.stdin.flush()
result = ""
while True:
line = self.stdouterr.readline().rstrip().decode(encoding)
if re.search(pattern, line):
break
result = "%s%s\n" % (result, line)
return result
結果
テストソースコード①
テストソースコード②
図3 は等幅フォントではないため、罫線がズレて表示されていて、よく分からないので、テキストエディタにコピペして、ツリー構造がハッキリ分かる画像を4 に示します。
テストソースコード②
以上
10 秒で出来る形態素解析【python】【janome】【Windows】
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
プログラム
janome インストール
WinPython Command Prompt から pip でインストールします。コマンドはこちら
ソースコード
from janome.tokenizer import Tokenizer
t = Tokenizer()
for token in t.tokenize(u'私はこの味が好ましくない。'):
print(token)
結果
In [1]: runfile('C:/WinPython-64bit-3.4.4.6Qt5/settings/.spyder-py3/temp.py', wdir='C:/WinPython-64bit-3.4.4.6Qt5/settings/.spyder-py3')
私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
この 連体詞,*,*,*,*,*,この,コノ,コノ
味 名詞,一般,*,*,*,*,味,アジ,アジ
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
好ましく 形容詞,自立,*,*,形容詞・イ段,連用テ接続,好ましい,コノマシク,コノマシク
ない 助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ
。 記号,句点,*,*,*,*,。,。,。
In [2]:
コメント
たったこれだけで形態素分析が出来ちゃいます。
以上
C# で 逆行列を求める
こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。
この記事の目次
動作環境
・Windows 7
・Visual Studio 2017
プログラム
ソースコード
using System;
using System.Collections.Generic;
namespace inverse_matrix
{
class Program
{
static void Main(string[] args)
{
List> matrix = new List>();
matrix.Add(new List());
matrix[matrix.Count - 1].Add(1);
matrix[matrix.Count - 1].Add(1);
matrix[matrix.Count - 1].Add(-1);
matrix.Add(new List());
matrix[matrix.Count - 1].Add(-2);
matrix[matrix.Count - 1].Add(-1);
matrix[matrix.Count - 1].Add(1);
matrix.Add(new List());
matrix[matrix.Count - 1].Add(-1);
matrix[matrix.Count - 1].Add(-2);
matrix[matrix.Count - 1].Add(1);
List> inv = matrixinv(matrix);
for (int i = 0; i < inv.Count; i++)
{
for (int j = 0; j < inv[i].Count; j++)
{
if (j == 0) Console.Write(string.Format("{0,10}", inv[i][j]));
else Console.Write(" , " + string.Format("{0,10}", inv[i][j]));
}
Console.WriteLine("");
}
Console.ReadKey();
}
private static List> matrixinv(List> matrix)
{
// 戻り値 List
List> matrixinv = new List>();
// matrix の行数取得
int n = matrix.Count;
// matrix の列数が行数と同じであることの確認
int m = -1;
for (int i = 0; i < n; i++)
{
m = matrix[i].Count;
if(m != n)
{
return matrixinv;
}
}
int max;
// matrixinv に単位行列を格納する
for (int i = 0; i < n; i++)
{
// matrixinv に行を追加する
matrixinv.Add(new List());
// 1 行ずつ値の代入
for (int j = 0; j < n; j++)
{
if (i == j) matrixinv[matrixinv.Count - 1].Add(1.0); // 1 を代入
else matrixinv[matrixinv.Count - 1].Add(0); // 0 を代入
}
}
// 逆行列の計算
for(int k = 0; k < n; k++)
{
max = k;
double tmp;
for(int j = k + 1; j < n; j++)
{
if (Math.Abs(matrix[j][k]) > Math.Abs(matrix[max][k]))
{
max = j;
}
}
if (max != k)
{
for (int i = 0; i < n; i++)
{
// 入力行列側
tmp = matrix[max][i];
matrix[max][i] = matrix[k][i];
matrix[k][i] = tmp;
// 単位行列側
tmp = matrixinv[max][i];
matrixinv[max][i] = matrixinv[k][i];
matrixinv[k][i] = tmp;
}
}
tmp = matrix[k][k];
for (int i = 0; i < n; i++)
{
matrix[k][i] /= tmp;
matrixinv[k][i] /= tmp;
}
for (int j = 0; j < n; j++)
{
if (j != k)
{
tmp = matrix[j][k] / matrix[k][k];
for (int i = 0; i < n; i++)
{
matrix[j][i] = matrix[j][i] - matrix[k][i] * tmp;
matrixinv[j][i] = matrixinv[j][i] - matrixinv[k][i] * tmp;
}
}
}
}
//逆行列が計算できなかった時
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
if (double.IsNaN(matrixinv[j][i]))
{
matrixinv[j][i] = 0; // NaN を ゼロ に置き換える
}
}
}
// 戻り値
return matrixinv;
}
}
}
以上