<?xml version="1.0" encoding="UTF-8" ?>
<feed
	xmlns="http://www.w3.org/2005/Atom"
	xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
	xml:lang="ja-JP"
>
	<title>私と自然言語処理</title>
	<subtitle>最新4件を表示します。</subtitle>
	<id>tag:txqz.net,1970:/genre/%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86</id>
	<link rel="self" href="http://txqz.net/genre/%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86.atom"/>
	<link rel="alternate" type="application/rss+xml" href="http://txqz.net/genre/%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86.rdf"/>
	<link rel="alternate" type="application/xhtml+xml" href="http://txqz.net/genre/%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86.xhtml"/>
	<link rel="alternate" type="text/html" href="http://txqz.net/genre/%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86.html"/>
	<link rel="contents" href="http://txqz.net/genre" title="タグ一覧"/>
	<link rel="first" href="http://txqz.net/genre/%28%E7%A6%8F%29" title="(福)"/>
	<link rel="prev" href="http://txqz.net/genre/%E8%87%AA%E6%B2%BB%E4%BD%93" title="自治体"/>
	<link rel="next" href="http://txqz.net/genre/%E8%87%AA%E7%94%B1%E9%80%A3%E5%90%88" title="自由連合"/>
	<link rel="last" href="http://txqz.net/genre/%EF%BD%83%EF%BD%83TLD" title="ｃｃTLD"/>
	<author>
		<name>陽坂智佐</name>
		<email>spambasket@txqz.net</email>
	</author>
	<entry>
		<title>研究室の合宿で全自動メシをクソBotに変換しました</title>
		<id>tag:txqz.net,2009-08-23:/blog/2009/08/23/1812</id>
		<link rel="alternate" href="http://txqz.net/blog/2009/08/23/1812"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>今日まで2日間、<a href="http://tai.ia.inf.shizuoka.ac.jp/" title="静岡大学情報学部佐藤研究室 - トップページ">研究室</a>の合宿で<a href="http://www.grandview-atami.com/" title="熱海のリゾートコンドミニアム「グランビュー熱海」オーシャンビュー展望風呂と海鮮料理">グランビュー熱海</a>というコンドミニアムで開発合宿をしていた。これがとてもよくて、先生が授業で営業を精力的に行ったためとかでまず女子の割合が高い。そしてご飯が自動的に出てくる。屋上に風呂があって見晴らしがいい。すぐ前が海でリアルが爆発している。そんな中OB共は怠惰な時間をすごしておりまったく救いようがない。</p>
<p>たとえば私などは<a href="http://twitter.com/yozbot" title="yozbot (yozbot) on Twitter">yozbot</a>というクソみたいなBotを作成するのみで、これは私の今までの投稿をなんかマルコフ連鎖? とかいうので再構築しているもので、ていうかまず実装したアルゴリズムがマルコフ連鎖になっているのかも不明で、ただPythonの勉強をしたかっただけだった。</p>
<p>まず、自分のタイムラインは古い分がすでにサーバにあるので、新しい部分を1時間おきくらいにでも取得してくる必要がある。こんな感じ:</p>
<pre><code class="python">#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import MySQLdb
import twitter
import time
import calendar

api = twitter.Api()
statuses = api.GetUserTimeline('youzaka')

def tosqltime(created_at):
    return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(calendar.timegm(time.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'))))

data = [(s.id, s.text.encode('utf_8'), tosqltime(s.created_at)) for s in statuses]

con = MySQLdb.connect(db='*****', user='*****', passwd='*****')
cur = con.cursor()

for (id, body, date) in data:
    sql = "insert ignore into tweets(id, body, date, treated) values(%s, %s, %s, 0)"
    cur.execute(sql, (id, body, date))
cur.close()</code></pre>
<p>タイムライン取得APIを叩いて、IDと本文と日付を取得して、それをDBにつっこんでいるだけ。tweetsテーブルのidカラムは主キーになっているので、IGNOREをつけておく。15行目で、取得したtextをそのまま使っていたらDBにつっこむところでUnicodeEncodeErrorが出た。Pythonはここら辺が慣れない。</p>
<p>マルコフ連鎖みたいなのが以下:</p>
<pre><code class="python">#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import MeCab
import MySQLdb
import re
import random

mecab = MeCab.Tagger('-Owakati')
con = MySQLdb.connect(db='*****', user='*****', passwd='*****')
cur = con.cursor()
sql = 'select id, body from tweets where treated = 0'
cur.execute(sql)
rows = cur.fetchall()
id_list = []
markov = {}

for row in rows:
    id_list.append(row[0])
    body = row[1]
    first = ""
    second = ""
    body = re.sub('https?://[^ ]+', '', body)

    if body == '':
        continue;

    parsed = mecab.parse(body.rstrip()).split(' ')
    parsed.insert(0, '[start]')
    parsed[-1] = '[end]'
    for third in parsed:
        if first and second:
            if (first, second) not in markov:
                markov[(first, second)] = []
            markov[(first, second)].append(third)
        first, second = second, third
cur.close()

cur = con.cursor()
for (first, second), list in markov.items():
    for third in list:
        sql = "insert into markov(first, second, third) values(%s, %s, %s)"
        cur.execute(sql, (first, second, third))
cur.close()

cur = con.cursor()
for id in id_list:
    sql = "update tweets set treated = 1 where id = %s"
    cur.execute(sql, id)
cur.close()</code></pre>
<p>取得したTwitterの書き込みのうち未処理のものについて、URLを削除してMecabに投げて形態素の配列を取得して、先頭と最後にそれぞれ[start]、[end]のマークをつける。で、どんどんDBに投げていく。たとえば、「研究室の合宿で全自動メシをクソBotに変換しました」を形態素分解すると「研究室」「の」「合宿」「で」「全」「自動」「メシ」「を」「クソ」「Bot」「に」「変換」「し」「まし」「た」となる (デフォルトの辞書の場合) ので、この文章から以下のルールを得られる:</p>
<table>
<thead>
<tr><th>start</th><th>second</th><th>third</th></tr>
</thead>
<tbody>
<tr><td>[start]</td><td>研究</td><td>室</td></tr>
<tr><td>研究</td><td>室</td><td>の</td></tr>
<tr><td>室</td><td>の</td><td>合宿</td></tr>
<tr><td>の</td><td>合宿</td><td>で</td></tr>
<tr><td>合宿</td><td>で</td><td>全</td></tr>
<tr><td>で</td><td>全</td><td>自動</td></tr>
<tr><td>全</td><td>自動</td><td>メシ</td></tr>
<tr><td>自動</td><td>メシ</td><td>を</td></tr>
<tr><td>メシ</td><td>を</td><td>クソ</td></tr>
<tr><td>を</td><td>クソ</td><td>Bot</td></tr>
<tr><td>クソ</td><td>Bot</td><td>に</td></tr>
<tr><td>Bot</td><td>に</td><td>変換</td></tr>
<tr><td>に</td><td>変換</td><td>し</td></tr>
<tr><td>変換</td><td>し</td><td>まし</td></tr>
<tr><td>し</td><td>まし</td><td>た</td></tr>
<tr><td>まし</td><td>た</td><td>[end]</td></tr>
</tbody>
</table>
<p>このルールから文章を作成してTwitterに投げるところはこんな感じ:</p>
<pre><code class="python">#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import MySQLdb
import re
import twitter

con = MySQLdb.connect(db='*****', user='*****', passwd='*****')
cur = con.cursor()
sql = "select second, third from markov where first='[start]' order by rand() limit 1"
cur.execute(sql)
row = cur.fetchone()

first = row[0]
second = row[1]
cur.close()

if re.search('[a-zA-Z]$', first) and re.search('^[a-zA-Z]', second):
    text = first + ' ' + second
else:
    text = first + second

while True:
    cur = con.cursor()
    sql = "select third from markov where first = %s and second = %s order by rand() limit 1"
    cur.execute(sql, (first, second))
    row = cur.fetchone()
    first, second = second, row[0]

    if second == '[end]':
        break

    if re.search('[a-zA-Z]$', text) and re.search('^[a-zA-Z]', second):
        text = text + ' ' + second
    else:
        text += second

api = twitter.Api('yozbot', '*****')
api.PostUpdate(text.decode('utf_8'))</code></pre>
<p>まず、最初の2語をランダムに選んで、その2語から次の単語をランダムに繋げていって、[end]が出たら終わりという単純なもの。次の単語を選ぶのに前の2語を使っているので、バリエーションの少ない組み合わせだと<a href="http://twitter.com/yozbot/status/4143245789" title="Twitter / yozbot: 北大クラスタ爆発しろ">そのままもとの投稿が出力されるということ</a>もありえて、そこらへんは調整したい。「北大」→「クラスタ」の連なりが1例しかなかったので、「北大」が選択された場合は100%「北大クラスタ爆発しろ」になってしまう。</p>
<table>
<thead>
<tr><th>first</th><th>second</th><th>third</th></tr>
</thead>
<tbody>
<tr><td>むしろ</td><td>クラスタ</td><td>内</td></tr>
<tr><td>特定</td><td>クラスタ</td><td>民</td></tr>
<tr><td>所属</td><td>クラスタ</td><td>以外</td></tr>
<tr><td>所属</td><td>クラスタ</td><td>ごと</td></tr>
<tr><td>から</td><td>クラスタ</td><td>臭</td></tr>
<tr><td>操作</td><td>クラスタ</td><td>[end]</td></tr>
<tr><td>関東</td><td>クラスタ</td><td>は</td></tr>
<tr><td>関東</td><td>クラスタ</td><td>と</td></tr>
<tr><td>て</td><td>クラスタ</td><td>解説</td></tr>
<tr><td>塚</td><td>クラスタ</td><td>の</td></tr>
<tr><td>北大</td><td>クラスタ</td><td>爆発</td></tr>
<tr><td>「</td><td>クラスタ</td><td>間</td></tr>
<tr><td>、</td><td>クラスタ</td><td>が</td></tr>
<tr><td>、</td><td>クラスタ</td><td>別</td></tr>
<tr><td>筑波大</td><td>クラスタ</td><td>に</td></tr>
<tr><td>筑波大</td><td>クラスタ</td><td>よく</td></tr>
<tr><td>ない</td><td>クラスタ</td><td>乙</td></tr>
<tr><td>の</td><td>クラスタ</td><td>の</td></tr>
<tr><td>大</td><td>クラスタ</td><td>より</td></tr>
<tr><td>大</td><td>クラスタ</td><td>っぽい</td></tr>
<tr><td>大</td><td>クラスタ</td><td>の</td></tr>
<tr><td>大</td><td>クラスタ</td><td>の</td></tr>
<tr><td>大</td><td>クラスタ</td><td>」</td></tr>
<tr><td>大</td><td>クラスタ</td><td>の</td></tr>
<tr><td>た</td><td>クラスタ</td><td>に</td></tr>
<tr><td>会話</td><td>クラスタ</td><td>と</td></tr>
<tr><td>で</td><td>クラスタ</td><td>内</td></tr>
<tr><td>京大</td><td>クラスタ</td><td>の</td></tr>
<tr><td>別</td><td>クラスタ</td><td>で</td></tr>
<tr><td>働く</td><td>クラスタ</td><td>甲</td></tr>
<tr><td>高専</td><td>クラスタ</td><td>?</td></tr>
<tr><td>新人</td><td>クラスタ</td><td>が</td></tr>
</tbody>
</table>
<p>これ、「大」→「クラスタ」ってなっているもののほとんどが「静大クラスタ」だったはずで、「京大」「北大」はあるのに「静大」はなくて辞書漏れ悲しいですという話ですね。</p>

			</div>
		</content>
		<category term="ポリタンク"/>
		<category term="Python"/>
		<category term="Twitter"/>
		<category term="Bot"/>
		<category term="自然言語処理"/>
		<trackback:ping>http://txqz.net/blog/2009/08/23/1812/tb</trackback:ping>
		<published>2009-09-22T22:58:13+09:00</published>
		<updated>2009-09-22T22:59:28+09:00</updated>
	</entry>
	<entry>
		<title>理想の新書の並べ方</title>
		<id>tag:txqz.net,2007-09-27:/blog/2007/09/27/2201</id>
		<link rel="alternate" href="http://txqz.net/blog/2007/09/27/2201"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://d.hatena.ne.jp/kongou_ae/20070924/1190650857" title="Aimless_Aegis - 新書の陳列はどうかしている">本屋に行くと刊行順に新書が並んでいて本を探しにくい</a>という話に<a href="http://b.hatena.ne.jp/extinx0109y/20070925#bookmark-5980423" title="はてなブックマーク - A Thinkeroid's notebook / 2007年09月25日">ブックマーク</a>がついて曰く:</p>
<blockquote cite="http://b.hatena.ne.jp/extinx0109y/20070925#bookmark-5980423" title="はてなブックマーク - A Thinkeroid's notebook / 2007年09月25日">
<p>[アハハ][ハウツー][魔界]「就活だからって普段来ねえ新書の棚にいちゃもんつけてんじゃねーよ、そもそも新書の分類が「政治」「経済」「ビジネス」みたいにスパッと分けられるか。文明開闢以来の「分類」ちう大問題を軽視」…等々、後ほど。</p>
</blockquote>
<p>そりゃヒエラルキー型分類に嫌気が差していまフォークソノミーが絶賛流行中なわけで、これは「政治」の本でそれ以外ではない! だなんて言えない。たとえば今日買ってきた新潮新書の『いつまでもデブと思うなよ』にしても、大まかに言うとこれは「健康」の本かもしれないけど、ダイエットの本でもあるしオタキングの本でもあるし中年男性の本でもある。</p>
<p>そういうキーワードから新書間の距離を計算して、より多くのキーワードを共有する本をなるべく近くに置くようなアルゴリズムでも考えてみたら評判になるかも。既存の知見をちょっと応用するだけだけど。</p>
<p>と思ったけど、新書って関連書籍の紹介があるじゃん。手元にあるレーベルで確認したのは講談社現代新書と光文社新書の2つだけど、『行動経済学 経済は「感情」で動いている』の場合は『財政学から見た日本経済』や『経済物理学の発見』、『マルクスだったらこう考える』など経済学つながりの新書が「既刊より」に列挙されているし、『東京の島』には『日本《島旅》紀行』や『郵便局を訪ねて1万局』、『温泉教授の日本全国温泉ガイド』など地理関係や紀行作品が紹介されている。光文社新書は書誌情報の列挙だけど講談社現代新書の場合は紹介文もついていて、『はじめての言語学』の場合は:</p>
<blockquote cite="urn:isbn:4-06-149701-4" title="はじめての言語学">
<p>本書著者も推薦する好著、井上史雄『敬語はこわくない』は、年々変化するよう例を豊富に紹介する「お求めやすい」入門書。同著者による『日本語は年速一キロで動く』は、綿密な全国調査で明かす図版満載の日本語論。</p>
</blockquote>
<p>などとなっている。レーベル側で関係書籍を列挙しててくれているわけで、売り上げを少しでも伸ばそうとする書店がこの情報を活用しない手はない。他のレーベルも、こういう形で本と本をリンクしてくれるといろいろありがたいのでぜひよろしくお願いしたいところ。</p>
			</div>
		</content>
		<category term="ネタ"/>
		<category term="ベクトル空間"/>
		<category term="新書"/>
		<category term="研究"/>
		<category term="自然言語処理"/>
		<category term="距離"/>
		<trackback:ping>http://txqz.net/blog/2007/09/27/2201/tb</trackback:ping>
		<published>2007-09-27T22:01:23+09:00</published>
		<updated>2007-09-27T22:01:23+09:00</updated>
	</entry>
	<entry>
		<title>MySQLでTF-IDFの計算、あと2つのベクトルの内積の計算</title>
		<id>tag:txqz.net,2006-12-19:/blog/2006/12/19/2347</id>
		<link rel="alternate" href="http://txqz.net/blog/2006/12/19/2347"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p>本文を形態素分解し、必要な品詞をtfテーブルとdfテーブルに入れる。分析対象となる文書群すべてについてこの処理を行い、各形態素のTF-IDF値を求めて文書をベクトル化する。他の文書ベクトルと内積を比較し、小さい順に「似ている記事」を求めたい (クラスタリングとかは別途)。</p>
<p>HarmanによるTF値の正規化とSparok JonesによるDF値の正規化をする場合のTF-IDF値の計算式は以下のようになる (<a href="http://www.r.dl.itc.u-tokyo.ac.jp/~nakagawa/infoDB/ir-vector.pdf">参考文献</a>):</p>
<pre><code class="math">tfidf(i,j) = log2(freq(i,j) + 1) / log2(NoT) * (log2(N / Dfreq(i)) + 1)</code></pre>
<h3>HarmanによるTFの正規化</h3>
<pre><code class="math">tf(i,j) = log2(freq(i,j) + 1) / log2(NoT)</code></pre>
<dl>
<dt>tf(i,j)</dt><dd>文書jにおける単語iのTF値</dd>
<dt>freq(i,j)</dt><dd>文書jにおける単語iの登場回数</dd>
<dt>NoT</dt><dd>文書j中のタームの種類数(num of terms)</dd>
</dl>
<h3>Sparck JonesによるDFの正規化</h3>
<pre><code class="math">idf(i) = log2(N / Dfreq(i)) + 1</code></pre>
<dl>
<dt>idf(i)</dt><dd>単語iのDF値</dd>
<dt>N</dt><dd>文書集合中の文書総数</dd>
<dt>Dfreq(i)</dt><dd>単語iが登場する文書数</dd>
</dl>
<h3>MySQL での表現</h3>
<dl>
<dt>TF値の分子</dt><dd><pre><code class="sql">SELECT log2(times + 1) FROM tf WHERE item='j' AND tag='i';</code></pre></dd>
<dt>TF値の分母</dt><dd><pre><code class="sql">SELECT log2(count(tag)) FROM tf WHERE item='j' GROUP BY item;</code></pre></dd>
<dt>IDF値のlogの分子</dt><dd><pre><code class="sql">SELECT count(id) FROM article;</code></pre></dd>
<dt>IDF値のlogの分母</dt><dd><pre><code class="sq;">SELECT times FROM df WHERE tag = 'i';</code></pre></dd>
</dl>
<p>全部くっつけると:</p>
<pre><code class="sql">SELECT item, tag, log2(tf.times + 1) / log2(total) * (log2(n / df.times) + 1) AS tfidf
  FROM tf
    LEFT JOIN df USING(tag)
    LEFT JOIN (SELECT item, count(tag) total FROM tf GROUP BY item) AS a USING(item)
    CROSS JOIN (SELECT count(id) AS n FROM items) AS b
  WHERE item="<var>j</var>";</code></pre>
<p>実際はユーザ変数を使った方がSQLが短くなっていいと思う。</p>
<pre><code class="sql">SELECT @total := count(tag) FROM tf WHERE item = "<var>j</var>";
SELECT @n := count(id) FROM items;
SELECT item, tag, log2(tf.times + 1) / log2(@total) * (log2(@n / df.times) + 1) AS tfidf
  FROM tf LEFT JOIN df USING(tag)
  WHERE item="<var>j</var>";</code></pre>
<p>これで記事の各形態素のTFIDF値が求められたので、tfidfテーブルに保管しておく。</p>
<h3>内積を求めて近い記事を出す</h3>
<p>とりあえず各記事の上位100単語くらいを使うことにする。</p>
<pre><code class="sql">INSERT INTO tfidf
  SELECT item, tag, log2(tf.times + 1) / log2(@total) * (log2(@n / df.times) + 1) AS tfidf
    FROM tf LEFT JOIN df USING(tag)
    WHERE item="<var>j</var>"
    ORDER BY tfidf DESC
    LIMIT 100;</code></pre>
<p>ある文書wがn次元のベクトルで表せる (w = {w<sub>1</sub> w<sub>2</sub> ... w<sub>n</sub>})とき、文書wとxの内積は</p>
<pre><code class="math">Σ(w<sub>i</sub> * v<sub>i</sub>) / √(Σ(w<sub>i</sub><sup>2</sup>) * Σ(v<sub>i</sub><sup>2</sup>))</code></pre>
<p>MySQLで書くと</p>
<pre><code class="sql">CREATE TEMPORARY TABLE inp
  SELECT self.tag, self.tfidf self, target.tfidf target
    FROM tfidf self
      LEFT JOIN (SELECT tag,tfidf FROM tfidf WHERE item='<var>v</var>') target USING(tag)
    WHERE self.item = '<var>w</var>';
SELECT sum(self * target) / sqrt(sum(pow(self,2))*sum(pow(target,2))) inp FROM inp</code></pre>
<h3>実際にやってみる</h3>
<p>実際にニュー速各板のスレでやってみた。だいたい同じニュースの続きのスレだと0.6以上の高い値に、似たようなネタの異なるニュースの場合は0.3～0.4くらいになった。以下はそれらの例。カッコ内が内積</p>
<h4>高い値 …… 同じニュースの次スレ、前スレ</h4>
<dl>
<dt>【経済】 「格差是正のため、正社員の待遇を非正規社員水準に合わせる」…経済財政諮問会議・八代氏★５</dt>
<dd><ul>
<li>【経済】 「格差是正のため、正社員の待遇を非正規社員水準に合わせる」…経済財政諮問会議・八代氏★４ (0.76865722990833)</li>
<li>【経済】 「格差是正のため、正社員の待遇を非正規社員水準に合わせる」…経済財政諮問会議・八代氏★３ (0.72848890331971)</li>
<li>【経済】「格差是正のため正社員待遇を非正規社員水準へ」…経済財政諮問会議メンバー・八代尚宏氏★２ (0.61619675121174)</li>
<li>【経済】「格差是正のため正社員待遇を非正規社員水準へ」…経済財政諮問会議メンバー・八代尚宏氏 (0.63664490692797)</li>
</ul></dd>
<dt>【芸能】森本レオが石原真理子の処女を奪ったことを認める「それでもやっぱりマリコがんばれ」</dt>
<dd><ul>
<li>【芸能】石原真理子「17歳で森本レオに処女奪われた」…週刊誌に暴露、「宣伝か」の声も★２ (0.82246383998552)</li>
<li>【芸能】石原真理子「17歳で森本レオに処女奪われた」…週刊誌に暴露、「宣伝か」の声も[12/18] (0.79417204039799)</li>
</ul></dd>
<dt>◆自治議論★64◆</dt>
<dd><ul>
<li>愛の説教部屋166(地獄キャンペーン実施中)（　ﾟдﾟ) (0.67651278868912)</li>
<li>◆自治議論★63◆ (0.81182145799799)</li>
<li>◆自治議論★62◆ (0.79929338782244)</li>
</ul></dd>
</dl>
<h4>中くらいの値 …… 似たようなネタだが異なるニュースのスレ</h4>
<dl>
<dt>【MLB】多田野、アスレチックスと再契約 春季キャンプでメジャー復帰目指す★３</dt>
<dd><ul>
<li>【社会】 ＮＨＫ職員（男）、電車で大学生（１８０cm・１２０kgの男子）に痴漢→逮捕…東京★３ (0.4629403483907)</li>
<li>【社会】 ＮＨＫ職員（男）、電車で大学生（男子）に痴漢→逮捕…東京★２ (0.41509734340642)</li>
</ul></dd>
<dt>【大阪】コリアNGOセンター事務局長「公立校で民族教育は不要との意見が出かねない…外国籍の子供に愛国心強調しないで」［12/18］</dt>
<dd><ul>
<li>【論説】 「"日教組が、教育荒廃の元凶"というのは言いがかりだ」…東京新聞★２ (0.35593573724151)</li>
<li>【日韓】 ［特派員コラム］韓国は日本を追い越すことができる?潜在力も意欲も韓国が上[12/18] (0.3069814685099)</li>
<li>【論説】 「愛国心、"格差"はぐらかす為か？ 学生らは愛国心強要に"日本社会の悪化"を感じている」…毎日新聞★３ (0.39403589906126)</li>
</ul></dd>
<dt>【フィギュアスケート】高橋・安藤・浅田・村主ら日本勢に謎の症状･･･体調不良者が続出★３</dt>
<dd><ul>
<li>【北海道】カキ「風評被害」に悲鳴、取扱額４０％減　ノロウイルス食中毒、今季の感染例ゼロなのに★２ (0.41831300355656)</li>
</ul></dd>
</dl>
<p>今回やってみて、同じニュースのスレッドは★１だろうが★８だろうが同じようなことを延々と話しているのではないかと感じた。何スレも立つような息の長いニュースについて、スレッドごとの単語の登場の仕方とか共起の仕方を見ていくと、ニュー速民のニュースへの態度を表せたりするかも。面白いのはフィギュアスケート選手の体調不良の記事とカキの風評被害の記事が関連付けられたこと。フィギュアスケートの記事中に「カキ」への言及がなくても、ニュー速民による噂話の可視化によって、実は関係あるかもしれない2つの記事が結びついた。なんか集合知かも～。</p>
<ins class="ps" datetime="2007-06-02T19:43:05+09:00" id="PS20070602194305">
<p>このとき使ったのと似たような手法を<a href="http://sangi.in/kouho">候補者ブログクローラ</a>でも使っています。</p>
</ins>
			</div>
		</content>
		<category term="MySQL"/>
		<category term="SQL"/>
		<category term="TF-IDF"/>
		<category term="ベクトル空間"/>
		<category term="内積"/>
		<category term="自然言語処理"/>
		<trackback:ping>http://txqz.net/blog/2006/12/19/2347/tb</trackback:ping>
		<published>2007-06-02T19:43:05+09:00</published>
		<updated>2007-12-04T18:55:11+09:00</updated>
	</entry>
	<entry>
		<title>Wikipediaのタイトルリストを形態素解析の辞書にまとめて登録したら</title>
		<id>tag:txqz.net,2006-10-04:/blog/2006/10/04/2115</id>
		<link rel="alternate" href="http://txqz.net/blog/2006/10/04/2115"/>
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://download.wikimedia.org/jawiki/latest/jawiki-latest-all-titles-in-ns0.gz">Wikipedia日本語版のタイトル一覧</a>を持ってきて<a href="http://ultimania.org/sen/" title="John - FrontPage">Sen</a>のユーザ辞書に突っ込んだのはいいけれども、名詞は名詞だけどどんな名詞か判断できないので一律に「名詞-from_wikipedia」として登録したら適切に使われなかった。そりゃ"from_wikipedia"なんてサブ品詞は形態素解析マシンが理解できないのだから当然。悔い改めて一律に「名詞-固有名詞」として、コストもテキトーな値にして登録してみた。</p>
<p>で、たとえば「クーリングオフ」という単語なのだけれども、「クーリングオフをする」とかいう文脈だと、ちゃんと「クーリングオフ」という新しい形態素が抽出される。しかし、「クーリングオフされた」だと「クー」「リング」「オフ」「さ」「れ」「た」になってしまう。それは、「クーリングオフ」は本当はサ変接続の名詞なのにもかかわらず「固有名詞」として登録してしまったのが悪い。</p>
<p>デフォルト辞書に含まれていない新しい語彙をまとめて登録するのにWikipediaを使えば楽かなと思ったけれども、実際は、少なくとも普通の名詞とサ変動詞にくっつく名詞というのを区別して登録しないといけない。30万弱もあるのにそんなのいちいちやってられない。あと、数字や化学式まで「固有名詞」として登録されてしまうから、「2007」が「2」と「007」に別れてしまったりする。そりゃ007はゼロゼロセブンのことなのだけれども、そんな誤爆しそうなフレーズを登録したら死ぬ。数字やアルファベットだったら、ほっておけば未知語として出てくるだろうから、数字やアルファベットだけからなる行は削除するとかしないといけない。</p>
<p>あとはてなキーワード一覧も用意したのだが、何も考えないでやったら文字コードがEUC-JPになってしまった。そのほかはUTF-8なのでいかにも都合が悪い。ということで<a href="http://www.atmarkit.co.jp/flinux/rensai/linuxtips/448cnvunicode.html" title="＠IT：Unicodeのテキストファイルをほかの文字コードに変換するには">lv</a>を使った。</p>
<pre><code>lv -Ou8 motoneta.txt > henkan.txt</code></pre>
<p>でUTF-8に変換できる。よく文字コード変換というとnkfが言及されるが、どっちが良いんだろう。GNOMEエディタだと「無効な文字がありました」と言われるファイルでも無理やり変換できる。</p>
			</div>
		</content>
		<category term="Wikipedia"/>
		<category term="形態素解析"/>
		<category term="日本語"/>
		<category term="自然言語処理"/>
		<trackback:ping>http://txqz.net/blog/2006/10/04/2115/tb</trackback:ping>
		<published>2007-07-28T17:42:18+09:00</published>
		<updated>2007-07-28T17:43:25+09:00</updated>
	</entry>
</feed>