AIプロジェクト3日目:文章中に現れた単語に対して知識をひけらかす機能

とりあえず、持てる知識をどんどん出していってほしい。
それがAIに学習させる醍醐味だと思うのです。

とりあえず、プロトタイプとして、

  • 文章を区切り、sentenceにする
  • sentenceに対して、語彙リスト=voがの中の単語=キーが含まれているか確認する
  • 含まれていた単語に登録している知識=値からランダムに抽出
  • ランダムに抽出した知識をsentenceに対するコメントとして当てはめる。

こんなものを作りたいと思う。

文章を区切り、sentenceにする

これは前回かそこらでやったけど、結局単語を細かく切っていくと、おかしなことになってしまうので一文ずつに切っていくのが良いとの結論に至った。

content='''
長い文章・・・
'''
split_list1= '。|\n'
sentence_list=re.split(split_list1,content)

こんな感じで、元の文章を「改行」と「。」くらいで区切って、リストを作ってやる。

語彙リストから参照する

vo={'単語1':['知識1','知識2'],'単語2':['知識1','知識2']}
keys=list(vo.keys())
comment_list={}  #空の辞書={sentence:['知識1','知識2'],}
for sentence in sentence_list:
    comment_list.update({sentence:[]}) #辞書に追加していく
    for key in keys:#それぞれのsentenceに対して
        if key in sentence:#語彙=キーが含まれているとき
            try:#語彙の知識=値をランダムに出してリストに登録
                comment_list[sentence].append(random.choice(vo[key]))
            except:#語彙はあるけど知識がないときはスルー
                pass
        else:#語彙がないときもスルー
            pass
print(comment_list)

こんなんで、多分行けるはず。

試しに、
sentence_list=[‘JVCケンウッドは、JVCブランドより、新シリーズ「SOLIDEGE(ソリデージ)」のハイレゾ対応ヘッドホンとして「HA-SD7」を発表’]

で、試してみる。一応、語彙と知識はそれなりに貯めつつある。

結果

{'JVCケンウッドは、JVCブランドより、新シリーズ「SOLIDEGE(ソリデージ)」のハイレゾ対応ヘッドホンとして「HA-SD7」を発表': ['神奈川県横浜市神奈川区(旧日本ビクター本社所在地)に本社を置く、映像機器・音響機器・無線機器メーカー', '音楽用CD(CD-DA)を超える音質の音楽データの総称']}

おー、ちゃんとでてくれた。
ちなみに、ヒットした語彙は、「JVC」と、「ハイレゾ」かな。
これで、ひっちゃかめっちゃか自動で語彙を登録していき、ヒトの手でこつこつ知識を蓄えてあげていけば、、、成長するAIが作れるかもしれない・・・

今日はここまで。

次は、多分かなり進んでいると思う。

【AIプロジェクト】2日目:リストに重複した単語を1つにまとめる方法

#単語を抽出して語彙に記憶させる
語彙をできるだけ多く記憶させるために、ひたすらリストにappend() していくのはいいけど、ゴミが増える。
それぞれの語彙に対応する文章を割り出したい時に、その文章をもなんども引っ張ってくる恐れがあるから。

そんな無駄をなくすために、今日はリストに重複した単語を消す方法を考える。

リスト内の重複した単語を消去する

サンプルリストを作成

nums=[1,2,3,4,5,2,3,4,5,6,7,7,7,3,2,3,4,3,4,2,2,2,4,5,6,3]

とりあえず単語ではなくて数字にしてみる。適当に打ったので、何が何個含まれているのか、どれだけ重複しているのかわからない。

まずは、すべての要素に対して何が何個含まれているのか調べよう

重複した数字の個数を調べる

for num in nums: #numsリストにあるそれぞれのnumについて
    nums.count(num)

リスト内に何個含まれているのか個数を調べるときは、count() を使う
##カウントされた数マイナス1回消去する

次に、カウント数から1回引いた回数その数字を消せば良い

for num in nums:
    nums.count(num)
    for i in range(nums.count(num)-1): #カウントされた回数-1回の間
        nums.remove(num)

これで、重複した数字の消去が完了した。結果は次の通り。

print(nums)

[1, 6, 7, 2, 4, 5, 6, 3]

【AIプロジェクト】1日目:文字列からキーワードを抽出するプログラムの作成

突然AIを作ってみたくなった

AIを作ってみたくなった。といっても、あらゆる情報から判断して何かができるようなたいそうなものは作れない。
当面の目標は、価格.comの最新家電のニュースの感想を述べてくれるものを作りたいと思う。
さしあたって必要になりそうな技術は、スクレイピング、これはある程度身についたので後回し。

問題は、文字列の分析方法

問題になってくるのは文字列をいかに読ませ、分析させ、適切な感想を返すことができるようにするかが肝となる。

次に大事なのは、キャラクター性
これも、機械的に言葉を返すようじゃ面白くないし、何かクセはあるけれども憎めない、そんなキャラクターが必要になってくる。
あと、女子高生がいい。やっぱり。

まずはキーワード抽出

というのも、別のサイトで「ひとりガジェット速報(http://hitorigadget.wpblog.jp)」を運営しているけれども、いろいろとかなりグレーであるのと、
やっぱり自分の言葉で述べることが必要だと感じたから。

それはコピーコンテンツに対するSEO的な懸念と、物足りなさと、いろいろあるんだけど
自分の言葉で表現できるなにかが必要だってことを強く感じ始めtから。

そして、それでもやっぱり楽したい(クズ)

じゃあ代わりに言葉を編んでくれる人を作ればいいじゃない。

そんなわけで、とりあえず今日はキーワードをどうやって割り出すかを勉強した。

split() では上手くいかない

文字列を特定の文字列(,とか。とか)で分割する関数があるのは知っている。

ただ、これは上手くいかない。

text='''
新型CX-5のキーワードは「すべてのお客さまを笑顔にするSUV」。デザインは「洗練された力強さ」の表現を目指し、「魂動(こどう)」と呼ばれる同社のデザインコンセプトをより高い領域へ引き上げた。つややかさに精悍(せいかん)さを融合させた外観と、乗員の誰もが心地よさを感じる内装を作り上げることに挑戦したという。ボディーカラーには魂動デザインの造形を際立たせる新開発の「ソウルレッドクリスタルメタリック」を初採用した。ボディーサイズは全長4545×全幅1840×全高1690mmで、ホイールベースは2700mm。ラゲッジルーム容量は505リッター。 走行性能では、ドライバーのステアリング操作に応じてエンジンの駆動トルクを変化させることで車両の操縦性と安定性を高める「G-ベクタリング コントロール」を全車に標準装備したほか、静粛性や乗り心地を改善して同乗者の快適さも向上させた。また「マツダ・レーダー・クルーズ・コントロール」の追従速度を従来の30~100km/hから0~100km/hに拡大するなど、安全性能も見直した。 エンジンは、従来型と同じようにディーゼルが2.2リッター(SKYACTIV-D2.2)で、ガソリンが2リッター(SKYACTIV-G2.0)と2.5リッター(SKYACTIV-G2.5)となる。SKYACTIV-D2.2には、アクセル操作に対するクルマの反応をよりダイレクトにする「DE精密過給制御」のほか、ノック音を低減する「ナチュラル・サウンド・スムーザー」やノック音の発生そのものを抑制する「ナチュラル・サウンド・周波数コントロール」を採用し、走りの滑らかさと静かさを向上させた。JC08モード燃費は、SKYACTIV-D2.2:17.2~18.0km/リッター、SKYACTIV-G2.0:16.0km/リッター、SKYACTIV-G2.5:14.6~14.8km/リッター。
'''
text.split('。')

出典:http://news.kakaku.com/prdnews/cd=kuruma/ctcd=7010/id=61358/
splitでは、「。」の一つしか分割指定できないため、一文一文ずつしかリストにできない。
そんなんでは、単語やらキーワード抽出やらできないではないか!

とググって見ると、どうやらre.split() という正規表現があるらしい。


http://www.lifewithpython.com/2014/08/python-use-multiple-separators-to-split-strings.html

re.split()

import re
text='''
新型CX-5・・・・
(中略)
'''
re.split('も|が|を|に|へ|と|より|から|で|や|の|は|、|。|!|?|!|「|」|(|',text)

これで、「|」でわけた単語全てが分割要素となり、キーワードらしきものができた!

print(re.split('(中略)',text))

['\n新型CX-5', 'キーワード', '', 'すべて', 'お客さま', '笑顔', 'するSUV', '', 'デザイン', '', '洗練された力強さ', '', '表現', '目指し', '', '魂動', 'こどう', '', '', '呼ばれる同社', 'デザインコンセプト', '', '高い領域', '引き上げた', 'つ', '', 'かさ', '精悍', 'せいかん', 'さ', '融合させた外観', '', '乗員', '誰', '', '心地よさ', '感じる内装', '作り上げるこ', '', '挑戦した', 'いう', 'ボディーカラー', '', '魂動デザイン', '造形', '際立たせる新開発', '', 'ソウルレッドクリスタルメタリック', '', '初採用した', 'ボディーサイズ', '全長4545×全幅1840×全高1690mm', '', 'ホイールベース', '2700mm', 'ラゲッジルーム容量', '505リッター', '\n走行性能', '', '', 'ドライバー', 'ステアリング操作', '応じてエンジン', '駆動トルク', '変化させるこ', '', '車両', '操縦性', '安定性', '高める', 'G-ベクタリング コントロール', '', '全車', '標準装備したほか', '静粛性', '乗り心地', '改善して同乗者', '快適さ', '向上させた', 'また', 'マツダ・レーダー・クルーズ・コントロール', '', '追従速度', '従来', '30~100km/h', '0~100km/h', '拡大するなど', '安全性能', '見直した', '\nエンジン', '', '従来型', '同じよう', 'ディーゼル', '2.2リッター', 'SKYACTIV-D2.2', '', '', 'ガソリン', '2リッター', 'SKYACTIV-G2.0', '', '2.5リッター', 'SKYACTIV-G2.5', '', 'なる', 'SKYACTIV-D2.2', '', '', 'アクセル操作', '対するクルマ', '反応', '', 'ダイレクト', 'する', 'DE精密過給制御', '', 'ほか', 'ノック音', '低減する', 'ナチュラル・サウンド・スムーザー', '', 'ノック音', '発生そ', '', '', '', '抑制する', 'ナチュラル・サウンド・周波数コントロール', '', '採用し', '走り', '滑らかさ', '静かさ', '向上させた', 'JC08モード燃費', '', 'SKYACTIV-D2.2:17.2~18.0km/リッター', 'SKYACTIV-G2.0:16.0km/リッター', 'SKYACTIV-G2.5:14.6~14.8km/リッター', '\n']

うん、っぽくなってきたので、今日はここまで。

明日は抽出したキーワードの頻度とかをみることができるようにしよう。