Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all 21093 articles
Browse latest View live

Mac Catalina Audacity(オーダシティ) 音声入力を受け取ってくれない不具合を解決した話

$
0
0

目的

  • 最新OSでAudacityが音声入力に対応してくれない不具合が発生して解決した話をまとめる

環境

項目情報
OSmacOS Catalina(10.15.3)
ハードウェアMacBook Pro (16-inch ,2019)
プロセッサ2.6 GHz 6コアIntel Core i7
メモリ16 GB 2667 MHz DDR4
グラフィックスAMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB

問題

  • インストール直後にインプットデバイスを内蔵マイク設定しているけど音声を受け付けてくれない。
  • 録音を始めても全く音の波形が入らない。

20200312111718.png

解決方法

  1. ターミナルを起動して下記コマンドを実行し管理者になった。

    $sudo su
    
  2. 下記コマンドを実行してターミナル経由でAudacityを起動した。

    #open /Applications/Audacity.app/Contents/MacOS/Audacity
    
  3. Audacityのアプリが起動した。

    スクリーンショット 2020-03-14 12.26.41.png

  4. 左上の録音ボタンをクリックしたところ下記のウインドウが開いたので「許可」をクリックした。

    スクリーンショット 2020-03-14 12.20.32.png

  5. 再度録音を行ったら正常に録音している音波の波形が確認された。

スクリーンショット 2020-03-14 12.20.47.png


🔰UIPath 初心者のボクがハマった点 備忘録 (随時更新)

$
0
0

UIPath初心者のボクが使っててハマった点をメモしておくよ😰😰😰

エクセル関係

同じようなアクティビティが2系統ある!

問題:
たとえば「セルを読み込み」を見てみると、2種類あるよ😱😱😱 どっちを使えばいいのー❗❓
image.png

対処方法:
「ワークブック」の下にある「セルを読み込み (ReadCell)」は、エクセルがインストールされていない環境でも使えるようだよ📗📊 一方、「Excel」の下にある「セルを読み込み (ExcelReadCell)」は、エクセルのインストールが必要だよ📇📝 通常の利用であれば、アクティビティの英語名の頭に「Excel」がついている方を使おう👌😘✨

開いたエクセルは必ず閉じてしまう!

問題:
Excelアプリケーションスコープ (ExcelApplicationScope)」で開いたエクセルファイルは、スコープが終わると必ず閉じてしまい開いたままにできない😰😰💦💦
image.png

対処方法:
あらかじめ「プロセスを開始」で引数に同じエクセルファイルを指定して開いた状態で、さらに「Excelアプリケーションスコープ」を使ってエクセルファイルを開いておくと、「Excelアプリケーションスコープ」が終了してもファイルが閉じないよ👌😘✨

フツーにセルを読むとエラーが出る!

問題:
セルを読み込み (ExcelReadCell)」でセルを読み込んで変数に出力しようとすると、以下のエラーが出てしばらくハマった😰
セルを読み込み: StringConverter を System.Double から変換できません。
原因は、出力結果を文字列変数に出力していて、読もうとしていたセルが表向きは整数だったけど中身の値に端数が含まれていたこと💦💦

対処方法:
「セルを読み込み (ExcelReadCell)」の「表示形式を保持」のオプションをONにしておくと、常にセルに表示される書式そのままで文字列として変数に出力されるので、エラーが出ない👌😘✨
もしくは格納する変数型をGenericValueにする🤔🤔
image.png

セルに小数を書き込んでもセル上では整数になってしまう

問題:
セルに書き込み (ExcelWriteCell)」で小数「1.1」を書き込んでも、エクセルのセル上では
「1」と表示されてしまう🤔🤔💦

対処方法:
これはエクセルに書き込んだセルの表示形式に沿った見え方になってしまうせいだよ💦💦 エクセルの表示形式を操るUIPathのアクティビティはないので、必要であればあらかじめ手で設定しておくか、キーボードショートカット等で表示形式を設定してね👌😘✨

置換が意外とメンドウ!あいまい検索も!

Excelブック内での文字列検索は「範囲内で検索 (ExcelLookUpRange)」を使うんだけど、このアクティビティは指定した「範囲」 (省略可能)で指定した「値」を検索して、最初のセルのアドレスを「結果」に文字列として返すよ🤔🤔
image.png
ただ、そうすると指定した範囲内のすべての値を検索/置換するのに、このアクティビティだけでは対応できないんだ😰💦

そうすると、たとえば「A1:G10」の範囲で検索置換をしようとすると、行と列のループ (「繰り返し (While)」)を2重に回して、行数を1から10まで、列名をAからGまで、とかで繰り返し処理を作る必要があるネ🤔🤔 プログラミングができないと難しい...😰😰😰😰😰

あと、エクセル本体では「大文字と小文字を区別する」「セル内容が完全に同一であるものを検索する」「半角と全角を区別する」があるけど、これを「範囲内で検索 (ExcelLookUpRange)」で使いたい場合はメンドウ...😰😰😰😰😰「範囲内で検索 (ExcelLookUpRange)」は、表示形式で表示されている文字ではなく、エクセルのセル内の「真の値」(セルを選択したときに数式バーに表示される値)に部分一致する最初のセル(大文字小文字を区別しない、半角/全角は区別する)を返すのだけれど、それ以外の方法を試そうとするとプログラミングが必要だネ🤔🤔

Pythonで毎日AtCoder #5

$
0
0

はじめに

前回
5日目です。今日はコンテストがあります。今日のコンテスト

#5

問題

考えたこと
1WAしました。
与えられる文字列に'ict'が含まれているかを判断する問題です。いくつかの文字を除いて'ict'になればいいというのが大事で、'ict'のどれかを除いてもいいのです。
最初は、この条件を見落していたのでWAしました。それを改善して順番通りに変換していくようにしました。

importres=str(input())s=s.lower()l='ict'step=0foriinrange(len(s)):ifs[i]==l[step]:step+=1ifstep==3:print('YES')quit()print('NO')

stepでindexを指定することで、順番通りに探してくれます。
s.lower()は、sを全て小文字にします。

まとめ

A問題なのにWAしてしまったのが悔しいです。今日のコンテストがんばりましょう!
では、また

ポートフォリオを作り始めて1ヶ月、感じたこと。

$
0
0

プログラミング初学者が、ポートフォリオを作り始めて1ヶ月程度経って感じていることを書きます。
ポートフォリオの内容はゲームの紹介ウェブページ?のようなものです。
色々書きたいことはありますが、ざっくり下記3つにまとめました。

(1)計画を組んでも抜けが多くて見通しの甘さを痛感する

始めにDB設計をしてその後、必要なビュー、テーブルの作成などやりましたが、
作業の途中に「これ、この機能が必要じゃないのか?でもやり方わからん\(^^)/」とか
とにかく抜けが多くてやり直しが多いです。まぁ初めてやることだから
見通しがしにくいというのはあるのでしょうが...

(2)本、カリキュラムなどと違って全て自分の頭でやるから迷うことが多い

これも当たり前ですが、他の人が作ったカリキュラムをやるのと違って正解がないため
進んでいるのかどうかを感じにくく、全て自分の頭で考えないといけないので
普段こういう思考法?をしていない僕にとっては非常に辛いんですね(今まで自分の頭で考えないゴキブリですみませんでした( ;∀;)

(3)自分のセンスのなさ、頭の悪さで潰れそうになる

皆さんもそうかもしれませんが、やっていくとデザインとかを考えたり
学習したところを何度も忘れり、大したことない問題で何時間も時間を使ったりなど
壁に何度もぶつかる訳ですが、その度に心が折れそうになるわけですね。
しかも誰もそれをフォローするわけでもないので、(環境次第ですが)
これはみんなやめてくやろなぁと実感します。
ちなみに僕の心は元々メンタル豆腐で既にグチャグチャに潰れて
豆腐だったか何かに変わっています\(^^)/
こけるのはもう慣れてしまったので、いかにすぐに立ち直るかが重要だと思っているので
とにかく死ぬ気で毎日体力が持つ限り続けていってます(`・∀・´)
...一人だとサボるので友人の監視付きですが( ´ ▽ ` )

大体こんなところです...要領の良さとかもあるのでしょうが、
いかに継続して毎日取り組めるかに全てがかかっているのかもしれません。
そのためにも目標を持つこと、体調管理、メンタル管理、環境構築などは欠かせません。

皆さんもどうか僕みたいに豆腐だったか何かにならないよう気をつけてくださいね!ヾ(๑╹◡╹)ノ"

「おにいちゃんのことなんか、全然好きじゃないんだからねっ...!」【ゼロからはじめるプロおにいちゃん】

$
0
0

はじめに

~我家の日常~
おにいちゃんの「よう妹。昨日夜遅くまで電話してて眠れなかったぞ。長電話もほどほどにしろよ」
妹「はぁ聞いてたの?マジできもいんですけど」
おにいちゃん「そんな言い方はないだろ。俺だってな...」
妹「うっさいからどっか行ってくれない。あたし忙しいんだけど」
おにいちゃん「.....。」
おにいちゃん (昔は「お兄ちゃんと結婚する」とか言ってくれてたのになぁ)

我家の妹は思春期に入り、お兄ちゃんと会話はおろか同じ空間にいるだけで嫌な顔をされてしまう。
それもあってか昔みたいに仲良くしたいのに、嫌味ばかり言ってしまう悪循環。
そんな毎日に嫌気がさしていた。そんなある日のこと...

いつものようにネットサーフィンをしていたらでこんなものを見つけた。
プロおにいちゃん育成API
おにいちゃん「本当に使えるのかこれ...。まぁ無料だし使ってみるか」

プロおにいちゃんへの道

おれは妹にどんなことを言ってたっけな。

これまでのおにいちゃん

この前はこんな感じだったな

よう妹。昨日夜遅くまで電話してて眠れなかったぞ

どれどれ、どんなもんかな

$ node proBro.js よう妹。昨日夜遅くまで電話してて眠れなかったぞ
感情:Neutral
感情指数:0.2779170937476806

別に悪いことは言ってなさそうだな...

考えるおにいちゃん

ただ思春期の妹ともなると、普通の言葉じゃ満足できないってわけか...
ならこんな感じで全力の愛を表現してやればいいのではないだろか。

妹よ。お前の顔を見るだけで俺の胸は熱くなり、何も考えることができなくなる。
もう一度おにいちゃんを仲良くやっていこうじゃないか

これだけ熱い思いをぶつければ間違いなく...

$ node proBro.js 妹よ。お前の顔を見るだけで俺の胸は熱くなり、何も考えることができなくなる。もう一度おにいちゃんを仲良くやっていこうじゃないか
感情:Negative
感情指数:0.5

なぜだ!!!

理解するおにいちゃん

ふむふむ。どうやら行き過ぎた言葉は重い感情として認識されるようだ。
ならば程よく、優しい言葉をかければちょうどよいのか。

$ node proBro.js やぁ妹よ。今日の髪型はかわいいな。長澤まさみかと思ったよ
感情:Positive
感情指数:0.626925485337811

(゚∀゚)キタコレ!!
完璧だ。これで妹と昔みたいに...

プロおにいちゃん

~後日~

妹「どいて。邪魔なんだけど」
(今日はこいつを使って..)

おにいちゃん「そんなこと言うなって。そういえば今日の髪型かわいいな。長澤まさみかと思ったよ」
妹「いきなりどうしたの?そんなこと言われたって..」
おにいちゃん (見える..見えるぞっ!!妹からの好感度が上がっていくのを!)

感情:Positive
感情指数:0.626925485337811

妹「...言いたいのはそれだけ?用がないならあたし行くけど」
おにいちゃん「待てって。今度お前が好きなアイスクリーム一緒に食べに行かないか?あそこのアイス昔から好きだもんな」

感情:Positive
感情指数:0.4908134011319556

妹「なんでそんな昔のこと覚えてるのよ...」
おにいちゃん「おれはプロおにいちゃんだからな。惚れたか?」
妹「バッカじゃないの?おにいちゃんのことなんか、全然好きじゃないんだからねっ...!

~Fin~

実装

全国の悩めるおにいちゃんのために、実装コードを配布したいと思います。
それでは皆様Good Sister Lifeを...


クリックでコード展開
proBro.js
constaxios=require('axios');constmsg=process.argv[2];constBASE_URL=`[API Base URL]/nlp/v1/sentiment`;constoptions={method:'post',baseURL:BASE_URL,headers:{'Content-Type':'application/json; charset=UTF-8','Authorization':'Bearer [your token]'},data:{"sentence":msg,"responseType":"json"}};constemotionCheck=async()=>{try{constres=awaitaxios.request(options);if(res.data.result.emotional_phrase.length<=1){for(leti=1;res.data.result.emotional_phrase.length;i++){if(/怒る|悲しい|不安|嫌|興奮|切ない|N*2/.test(res.data.result.emotional_phrase[i].emotion)){console.log(`感情:Negative`);console.log(`気持ちの入り度:${res.data.result.score}`);}else{console.log(`感情:${res.data.result.sentiment}`);console.log(`気持ちの入り度:${res.data.result.score}`);}}}else{console.log(`感情:${res.data.result.sentiment}`);console.log(`感情指数:${res.data.result.score}`);}}catch(error){console.log(error);}}emotionCheck();


まとめ

全おにいちゃんの悩める課題を解決するシステムが出来てしまいました。
このシステムを各家庭1つ配布することで、妹への想いの精度向上悲しみを生まない世界へと変えることができるのではないでしょうか。
またこのシステムは皆様自由にカスタマイズすることも可能ですので、よりよい妹ライフプロおにいちゃんライフを送ることができるよう協力をお願いします。

またこの記事を見たおにいちゃんの達が幸せになることを心より願っております。

Rails|generateコマンドで生成されるファイルに制限をかける(config.generatorsの設定)

$
0
0

はじめに

generateコマンドっていろんなファイルを作成してくれるけど、「helperファイルの自動生成は必要ないのになー」って時などには、かえって煩わしく感じますよね。

そこで今回は、config/application.rb内の設定によって、generate コマンドで生成されるファイルに制限をかけます。(※スキップオプションを付ける方法もあるけど省略)

まずはrails generation時の挙動を確認

ターミナルでrails generation(rails gに省略可)を行うと、色々なファイルが自動生成される。

> rails g controller user show      
Running via Spring preloader in process 
      create   app/controllers/user_controller.rb
       route   get 'user/show'
      invoke   erb
      create    app/views/user
      create    app/views/user/show.html.erb
      invoke   rspec
      create    spec/controllers/user_controller_spec.rb
      create    spec/views/user
      create    spec/views/user/show.html.erb_spec.rb
      invoke   helper
      create    app/helpers/user_helper.rb
      invoke    rspec
      create    spec/helpers/user_helper_spec.rb
      invoke   assets
      invoke    js
      create    app/assets/javascripts/user.js
      invoke    scss
      create    app/assets/stylesheets/user.scss

便利だけど、必要ないファイルがあれば、それだけ生成されないようにする。
(この自動生成したファイル等を削除したければ、ターミナルでrails destroy controller user showを実行しておく)

自動生成するファイルに制限をかける

今回は、config/application.rb内の設定で、
・assetsファイル
・testファイル
・ルーティング
の生成を無効にしてみる。

config/application.rb
putsclassApplication<Rails::Application#以下のように、generateコマンド時に生成されるファイルに制限をかけるconfig.generatorsdo|g|g.assetsfalseg.test_frameworkfalseg.skip_routestrueendend

上記の設定によって、

> rails g controller user show      
Running via Spring preloader in process 82700
      create  app/controllers/user_controller.rb
      invoke  erb
      create    app/views/user
      create    app/views/user/show.html.erb
      invoke  helper
      create    app/helpers/user_helper.rb

生成ファイルに制限がかかった。

このように、プロジェクトごとに設定を変えたり、自分好みのカスタマイズができる。

おわりに

今回が初のQiita投稿でした!

これからも新しく学んだこと等をQiitaに共有できればと思います。
ご覧いただきありがとうございました。

データベースとは [初心者向け][シンプルに]

$
0
0

データベースとは

データベース(略してDB)とは、大量のデータが入っている箱のようなもの。
(後からデータの追加、削除、検索をしやすい形に整理してある)

データベースの種類(型)

データベースには
「階層型」「ネットワーク型」「リレーショナル型」
の3つがある。
単にデータベースと言った場合はリレーショナル型をさすことが多い。(圧倒的に広く使われているそう)

リレーショナルデータベース(RDB)とは?

 →行と列からなる「表」でデータを管理するデータベース。↓
スクリーンショット 2020-03-14 15.02.23.png
↑こんなイメージですかね。

  • データの重複を避けられる
  • 検索能力が高い
  • SQLを用いたデータのアクセスが可能 (SQLとはデータベースとやり取りするときに使う言葉)

等の特徴がある。

どんなリレーショナルデータベースがあるか

代表的な製品は、
MySQL、Oracle、MS Access、MS SQL Server、DB2、PostgreSQLなどなど

ターミナルで画像のサイズを一括リサイズ

$
0
0

複数の写真の横幅を一瞬でリサイズする。今回は横幅を760pxにしたいとする。

手順

①任意の名前のフォルダを作成

今回はsize-changeというフォルダにする。

②リサイズしたい写真をフォルダの中に入れておく

③ターミナルからsize-changeフォルダに移動する

コマンドに以下を入力

cd

cdの後に半角スペースを入れて、size-changeフォルダをドラッグアンドドロップ→Enterキー

④ターミナルにリサイズの命令

コマンドに以下を入力→Enterキー

sips -Z 760 *.jpg

-Z = 比率を保って
760 = 高さと幅の最大値  という意味

以上です。

参考記事はこちら
https://arutega.jp/sips/


【PHP+MySQL】恐竜画像登録&画像表示にトライ!!!(恐竜シリーズプチ最終回)

$
0
0

はじめに

改良恐竜登録ツール(PHP+MYSQL版)
でも恐竜登録ツールを作成した。
しかし、何かが足りない。
恐竜登録と言えば、画像!!!

前回の記事で、DBに保存した画像の表示方法をまとめた。

今回は今までの内容を結集した恐竜画像登録&画像表示プログラムを作成してみた。

1.プログラム概要

機能1.登録済み恐竜画像を表示

dino_image1.jpg

例)7のリンクをクリックすると、インドミナスレックスの画像を表示。

dino_image2.jpg

機能2.恐竜の画像登録

(1)カテゴリーを確定後、登録したい恐竜(ティラノサウルス)を選択。
登録恐竜一覧には、画像登録済みの恐竜が表示されている。

dino_image3.jpg

(2)ファイル選択ダイアログで、登録したい画像を選択して確定ボタンを押す。
(tirano_mini.jpg(選択した画像)が表示される。)

dino_image4.jpg

(3)登録が完了すると、登録済みの恐竜一覧にリンクが表示される。
dino_image5.jpg

(4)リンクをクリックすると登録された画像が表示される。
dino_image6.jpg

2.実際のコード

(1)画像格納用のテーブル(tbl_dinoimg)の作成
id:恐竜のID
ext:画像ファイルのmimeタイプ
img:画像ファイルをバイナリデータにしたもの

createtabletbl_dinoimg(idinteger,imgmediumblob,extvarchar(10),primarykey(id));
common_dino2_image.php
<?phpfunctionNewPdo($dbname){$dsn='mysql:dbname='.$dbname.';host=localhost:3308;charset=utf8mb4';$user='root';$password='root123';$dbh=newPDO($dsn,$user,$password);return$dbh;}functionCheckdino($db0,$qry0,$val1,$type1){$result3=$db0->prepare($qry0);//パラメータをセット$result3->bindparam(1,$val1);$result3->bindparam(2,$type1);$result3->execute();//検索結果を配列に格納する$select_data=$result3->fetch();return$select_data;}//クエリ実行して得られる全データ(パラメータ)functionget_SelectTypeData($db0,$query0,$val1){$result_a=$db0->prepare($query0);$result_a->bindparam(1,$val1);$result_a->execute();return$result_a;}//クエリ実行して得られる全データfunctionget_AllData($db0,$query0){$result_a=$db0->prepare($query0);$result_a->execute();return$result_a;}//$str1:検索対象文字列,$str_mark:探したい文字: 戻り値、探したい文字より前にある文字列functionget_BeforeMarkString($str1,$str_mark){$idx0=strpos($str1,$str_mark);$retstr=substr($str1,0,$idx0);return$retstr;}//$str1:検索対象文字列,$str_mark:探したい文字、探したい文字より後にある文字列functionget_AfterMarkString($str1,$str_mark){$idx0=strpos($str1,$str_mark);$retstr=substr($str1,$idx0+1);return$retstr;}?>
start_dino_image.php
<!DOCTYPE html><htmllang="ja"><metacharset="utf-8"><title>恐竜画像登録</title><body><h1>恐竜画像登録!!</h1><?phprequire"common_dino2_image.php";//画像フォーム部分$dbname='db_dino';$dbh=NewPdo($dbname);$query_type0="SELECT DISTINCT type0 from tbl_dino";?><!-- tbl_dinoに登録されている恐竜カテゴリーと一覧を表示する部分 --><formaction="start_dino_image.php"method="post">カテゴリー:
  <?php$result_a=get_AllData($dbh,$query_type0);$cate0=isset($_POST['dtype01'])?htmlspecialchars($_POST['dtype01']):null;?><selectname="dtype01"style="width: 100px"><?phpwhile($select_data=$result_a->fetch(PDO::FETCH_ASSOC)){//$cate0が$select_data['type0']と等しい場合if($cate0==$select_data['type0']){echo"<option selected>".$select_data['type0']."</option>";//$cate0が$select_data['type0']と等しくない場合}else{echo"<option>".$select_data['type0']."</option>";}}?></select><inputtype="submit"name = "btn2"value="確定"></form><?php$dbname='db_dino';$dbh=NewPdo($dbname);$query_select_type0="SELECT dname0 from tbl_dino where type0 = ?";$result3=get_SelectTypeData($dbh,$query_select_type0,$cate0);?><formaction="start_dino_image.php"enctype="multipart/form-data"method="post">対象恐竜:
  <selectname="dname"style="width: 280px"><?php$dino0=isset($_POST['dname'])?htmlspecialchars($_POST['dname']):null;?><?phpwhile($select_data=$result3->fetch(PDO::FETCH_ASSOC)){echo"<option>".$select_data['dname0']."</option>";}?></select><br><label>画像/動画アップロード</label><inputtype="file"name="upfile"><inputtype="hidden"name="btn3"value="<?=$cate0?>"><inputtype="submit"value="確定"></form><?php//ファイルアップロードがあったときtry{$dbname='db_dino';$dbh=NewPdo($dbname);//$pdo = new PDO("mysql:host=127.0.0.1;dbname=mediatest;charset=utf8", $user, $pass);if(isset($_FILES['upfile']['error'])&&is_int($_FILES['upfile']['error'])&&$_FILES['upfile']['name']!==""){//エラーチェックswitch($_FILES['upfile']['error']){caseUPLOAD_ERR_OK:// OKbreak;caseUPLOAD_ERR_NO_FILE:// 未選択thrownewRuntimeException('ファイルが選択されていません',400);caseUPLOAD_ERR_INI_SIZE:// php.ini定義の最大サイズ超過thrownewRuntimeException('ファイルサイズが大きすぎます',400);default:thrownewRuntimeException('その他のエラーが発生しました',500);}//拡張子を見る$tmp=pathinfo($_FILES['upfile']['name']);$extension=$tmp["extension"];if($extension==="jpg"||$extension==="jpeg"||$extension==="JPG"||$extension==="JPEG"){$ext1="image/jpeg";}elseif($extension==="png"||$extension==="PNG"){$ext1="image/png";}else{echo"非対応ファイルです.<br/>";echo("<a href=\"start_dino_image.php\">戻る</a><br/>");exit(1);}//カテゴリーと恐竜名からidを探す$sql_select="SELECT * FROM tbl_dino WHERE dname0=? and type0=?";$dname1=isset($_POST['dname'])?htmlspecialchars($_POST['dname']):null;$type1=isset($_POST['btn3'])?htmlspecialchars($_POST['btn3']):null;$select_data1=Checkdino($dbh,$sql_select,$dname1,$type1);$dino_id=$select_data1['id'];//画像・動画をバイナリデータにする.$raw_data=file_get_contents($_FILES['upfile']['tmp_name']);}$dbname='db_dino';$dbh=NewPdo($dbname);$sql_del="DELETE FROM tbl_dinoimg WHERE id=?";//画像・動画をDBから削除$result1=$dbh->prepare($sql_del);//パラメータをセット$result1->bindparam(1,$dino_id);$result1->execute();//画像・動画をDBに格納.$sql_ist="INSERT INTO tbl_dinoimg(id, img, ext) VALUES (?,?,?)";$result1=$dbh->prepare($sql_ist);//パラメータをセット$result1->bindparam(1,$dino_id,PDO::PARAM_INT);$result1->bindparam(2,$raw_data,PDO::PARAM_LOB);$result1->bindparam(3,$ext1,PDO::PARAM_STR);$result1->execute();echo$dino_id."<br>";}catch(PDOException$e){echo("<p>500 Inertnal Server Error</p>");exit($e->getMessage());}?><?php//tbl_dinoimgに登録されている恐竜idと名前を表示する。$sql_idall="SELECT T1.id,T1.dname0,T1.type0 FROM tbl_dino T1";$sql_idall=$sql_idall." INNER JOIN tbl_dinoimg T2 ON T1.id=T2.id ORDER BY T2.id";$dbname='db_dino';$dbh=NewPdo($dbname);$result1=get_AllData($dbh,$sql_idall);echo"<br><h4>登録恐竜一覧</h4><br>";while($row=$result1->fetch(PDO::FETCH_ASSOC)){$id=$row['id'];?><!-- idと恐竜名とカテゴリー名 --><ahref="dino_display_image.php?id=<?=$id?>"><?=$id?></a>:<?=$row['dname0']?>(<?=$row['type0']?>)
<?phpecho("\n"."<br/>");}$dbh=null;?></body></html>

実はこの格納した画像を表示する事が超大変だった。
(前回の記事の部分)
よくある下記のコードでは、画面に表示されるのはどこまでも深い
黒一色の画面だったのだ。

header("Content-Type: image/jpeg");echo($row['img']);

そのうちにbase64というキーワードを見つけることになる。
1.DBから画像バイナリデータを取得
2.base64でエンコード
3.2を画像のmimeタイプで表示
という手順があることが分かった

dino_display_image.php
<?phpif(isset($_GET['id'])&&$_GET['id']!==""){$id=$_GET['id'];}else{header("Location: start_dino_image.php");}try{require"common_dino2_image.php";$dbname='db_dino';$dbh=NewPdo($dbname);$sql_select="SELECT ext,img FROM tbl_dinoimg WHERE id = ?";$result1=$dbh->prepare($sql_select);//パラメータをセット$result1->bindparam(1,$id,PDO::PARAM_INT);$result1->execute();$row=$result1->fetch(PDO::FETCH_ASSOC);//取得した画像バイナリデータをbase64で変換。$img=base64_encode($row['img']);?><!-- エンコードした情報をimgタグに表示 --><imgsrc="data:<?phpecho$row['ext']?>;base64,<?phpecho$img;?>"><br><ahref="start_dino_image.php">戻る</a><?php}catch(PDOException$e){echo("<p>500 Inertnal Server Error</p>");exit($e->getMessage());}?>

参考URL

PHPでbase64の使い方を知ろう!サンプルコードで速攻理解

今後に向けて

PHPでは一応恐竜シリーズの区切りがついた。
他のプログラミング言語でも、このシリーズにトライしたいと考えている。

Mailer viewでヘルパーメソッドを使用する

$
0
0

Mailer viewでヘルパーを使いたい

郵便番号にハイフンをいれてくれるメソッド

application_helper.rb
defformat_zipcode_include_hyphen(zipcode)zipcode.include?('-')?zipcode:zipcode.insert(3,'-')end

mailer viewでいきなり使用するとエラーになった。

application_mailer.rb

application_mailer.rb
classApplicationMailer<ActionMailer::Baseadd_template_helper(ApplicationHelper)end

と記述する

view

mailer.ftml.slim
p#{format_zipcode_include_hyphen(zipcode)}

でうまくいきました。

PostgreSQLをMacへインストールしてRails newする

$
0
0

概要

ポートフォリオ作成時、今までずっとMySQLに慣れ親しんでいたので、
PostgreSQLとやらに挑戦しようと思い、とりあえずインストール方法〜新規Railsアプリ作成までをまとめてみました!

条件

  • macOS Mojave(ver 10.14.5)

手順

  • Homebrewを使用してPostgreSQLをインストール
  • PostgreSQLの起動 / 起動確認 / 停止方法
  • データベース一覧を表示
  • Ruby on Railsのバージョンを変更
  • アプリケーションを新しく作成
  • GitHubに登録し、ローカルリポジトリを作成
  • リモートリポジトリを作成

Homebrewを使用してPostgreSQLをインストール

postgresqlをインストール

brew install postgresql

バージョン確認

psql -V

インストール場所を確認

which psql

PostgreSQLの起動 / 起動確認 / 停止方法

起動

brew services start postgresql

起動状況の確認

brew services list

停止

brew services stop postgresql

データベース一覧を表示

データベース一覧を表示

                                            List of databases
         Name          |     Owner      | Encoding | Collate | Ctype |         Access privileges         
-----------------------+----------------+----------+---------+-------+-----------------------------------
 postgres              | ************** | UTF8     | C       | C     | 
 test-app_development  | ************** | UTF8     | C       | C     | 
 test-app_test         | ************** | UTF8     | C       | C     | 
 template0             | ************** | UTF8     | C       | C     | =c/**************                +
                       |                |          |         |       | **************=CTc/**************
 template1             | ************** | UTF8     | C       | C     | =c/**************                +
                       |                |          |         |       | **************=CTc/**************

Ruby on Railsのバージョンを変更

cd ~ #ホームディレクトリに移動
gem install rails --version="5.2.4.1" #今回はversion="5.2.4.1"を使用
rbenv rehash #gemの変更を反映

アプリケーションを新しく作成

cd
rails new test-app -d postgresql #rails newコマンドを実行
cd test-app #test-appディレクトリに移動
rails db:create #データベースを作成

GitHubに登録し、ローカルリポジトリを作成

GItHub Desktop から test-app のローカルリポジトリを作成。
左上の「Current Repository」→「Add」→「Add Existing Repository」を選択。

※「Add Repository」がクリックできない場合、事前に該当するアプリケーションのディレクトリで以下の作業を行う。

cd ~/git-app
git init #rails のバージョンによっては rails new 時に git init がされないケースがあるため

その後コミット。

リモートリポジトリを作成

[Publish repository]ボタンをクリックすると GitHub のリモートリポジトリが作成できる。
GitHub の Your repositories の欄に作成したアプリがあれば上手くいっている。

サーバー起動

rails s

できた!制作スタート!

Image from Gyazo

Pythonでパナソニックプログラミングコンテスト2020を解きたかった

$
0
0

はじめに

今回はA,Bしか解けませんでした。ABC相当のコンテストでAとBしか解けないのは良くない。

A問題

問題

考えたこと
問題に書いてある数列をコピーして、kでindexを指定してprintしました。

k=int(input())l=[1,1,1,2,1,2,1,5,2,2,1,5,1,2,1,14,1,5,1,5,2,2,1,15,2,2,5,4,1,4,1,51]print(l[k-1])

B問題

問題
1WA
考えたこと
問題文の図を見ると、i行目とi+1行目を足すとWになると思ったのでhの偶奇で判別して計算しようとしたら1WAしました。WAの理由は、W,Hが1のときを考慮していなかったためです。ですので、どちらかが1のときを場合分けして書きました。

importmathh,w=map(int,input().split())ifw==1orh==1:print(1)quit()ifh%2!=0:ans=w*(h-1)/2+math.ceil(w/2)print(int(ans))else:ans=w*h/2print(int(ans))

C問題

問題
12WA NoAC

考えたこと
やったー、数学の問題じゃんと思っていたら地獄を見ました。まずは、安直に全部sqrtにつっこんで計算して1WA付きたので、計算をうまく減らしてあげないといけないと思いました。ですので、紙とペンを用意して必死にゼロに近い数学力で計算していました。

\sqrt(a) + \sqrt(b) < \sqrt(c)は両辺は0以上なので、両辺を二乗して \\
= a + b < c 
= a + b - c + 2\sqrt(ab)< 0 が成り立てば\sqrt(a) + \sqrt(b) < \sqrt(c)を満たす \\

a + b - cは整数だから計算的にあふれないと思ったので、\\
2\sqrt(ab)をどうやって処理するかを考えました。\\
相加相乗平均の関係より、 \\
a + b >= 2 \sqrt(ab) \\
が成り立つ。等号成立条件はa = bなので、そのときはifで分ければいいと考えてました。 \\ 
問題は、a != bのときで、自分の力ではどうしても根号を消すことができませんでした。 \\

それで、うまく工夫したつもりでしたがWAは消えず...結局ACできませんでした。
コンテスト終了した後に他のACした人のコードを見るとDecimalとかいうモジュールを使って小数をうまく計算していました。こんなに楽に計算できたら、楽勝問題だったのに...

<追記>

fromdecimalimport*a,b,c=map(int,input().split())ifDecimal(a).sqrt()+Decimal(b).sqrt()<Decimal(c).sqrt():print("Yes")else:print("No")

でACでました。

まとめ

言語に対しての知識不足を再認識するコンテストでした。色々と悔しいし、悲しい。毎日AtCoderチャレンジをしているので、次回のコンテストこそは結果を残したいです。
では、おやすみなさい。

トップページに戻るボタンをjavascriptで(jQuery無しで)

$
0
0

はじめに

脱jQueryしていきたいのでだんだんと素のjavascriptで書いていくようにしていると段階です。
備忘録がわりです。復習を兼ねて1つ1つ解説入れていこうと思います。

対象

駆け出しエンジニアの方や学生,jQueryに頼りっぱなしが嫌な方。

ソースコード

main.js
// トップへ戻るボタンfunctionscrollTop(el,duration){lettarget=document.getElementById(el);// elと名付けたドキュメント要素を取得し、変数に格納するtarget.addEventListener('click',function(){letcurrentY=window.pageYOffset;// クリック時の縦方向へのスクロール量を取得letstep=duration/currentY>1?10:100;// 三項演算子で10or100を変数step(1回分のスクロール量)に格納lettimeStep=duration/currentY*step;// 1回のスクロールにかかった時間を格納letintervalID=setInterval(scrollUp,timeStep);// scrollUp()を一定時間ごとに繰り返す // scrollUp()で一定時間ごとに繰り返される関数functionscrollUp(){currentY=window.pageYOffset;if(currentY===0){// 垂直方向へのスクロール量が0になったらclearInterval(intervalID);// 処理を停止する}else{scrollBy(0,-step);// スクロールした分だけY軸方向へ戻る}}});}scrollTop('top-button',ページトップに到達する時間); //関数を呼び出す
index.html
<divid="top-button"><divclass="arrow">divでボタンを作る</div></div>

解説

'top-button'とidで指定されたHTMLドキュメントをクリックしたら、クリックした時点でのスクロール量を取得し、そのスクロール量に応じて速度を場合分けして、ページのトップまでY軸方向へ戻るという処理。

setInterval(),clearInterval()

ここうまく説明できないけど、setInterval()をclearInterval()で包んで、ページのトップまでいったら処理を止めるイメージ

let step = duration/currentY > 1 ? 10 : 100;

三項演算子

if (条件式) {
    //Trueの処理
} else {
    //Falseの処理
}
条件式 ? Trueの処理 : Falseの処理

上の2つは同じ意味。複雑になると推奨されないらしいです。
今回ではduration/currentYの値が1より大きかったら10,1以下だったら100を変数stepに格納するという処理ですね。

おわりに

勉強になりました。より良くなると教えてくれる方ぜひ教えてください。

初心者から始めるJava、オーバーロード・コンストラクタ

$
0
0

はじめに

この記事は備忘録である。
参考書レベルの内容だが、本記事に掲載するコードについては、
間違えたものが中心となる。これは実際にコーディング中に間違えた部分を掲載し、自分で反省するために投稿するという目的によるもの
また、後日にJavaSilver試験問題の勉強を兼ねて復習するため、深い部分の話はここでは触れない。

環境

言語:Java11、JDK13.0.2
動作環境:Windows10

オーバーロード

クラスの中では、同じ名前のメソッドが同居しても構わないルールがある。
ひとつのメソッドの中で、扱う引数を無制限に増やしてもすべての引数を一度に宣言するのは難しいので、必要な機能に分けて用意した方が、クラスを使う側からしても楽になる。

Cat.java
getCatStatus(doubleweight,doubleheight){()}getCatStatus(intage,intnumber){()}getCatStatus(Stringname,Stringvoice){()}

このとき、getCatStatus()を使った場合の引数指定に応じて、同じ名前のメソッドから合致するものを選んで使ってもらえる。
この機能の事をオーバーロードという。
注意点として、同じ名前の各メソッドが持つ引数の型・個数が異なるようにする必要がある
これには、戻り値の型による違いは含まれてないため、修飾子が違うだけの同じ引数を必要とするメソッドは作れない

コンストラクタ

クラスを用意してメソッドを書く際、クラスのオブジェクトが生成された直後にクラスフィールドの初期値を定めることが出来る。

Cat.java
classCat{privatedoubleweight;privateintage;publicCat(){weight=1.0;age=0;}}

クラス名と全く同じ名前のメソッドを書くと、クラスを使ってnewしてオブジェクトが生成された際自動的に初期値を格納することが出来る。

終わりに

オーバーロードで扱った、同じ名前のメソッドではあるが引数に応じて別の働きをもたせることが出来る機能を多態性(ポリモーフィズム:Polymorphism)という。

参考

出来るだけ自分で変数や式を書いてコンパイルしているので、完全に引用する場合はその旨記述する。

やさしいJava 第7版
Java SE11 Silver 問題集(通称黒本)

Mac 特定のウインドウのキャプチャを撮影する方法

$
0
0

目的

  • 特定のウインドウのみのキャプチャの作成方法をまとめる

実施方法

  1. キャプチャを撮影したいウインドウを表示する。
  2. 「command」 + 「shift」 + 「4」を同時に押下する。
  3. 「スペースキー」を押下する。
  4. キャプチャを撮影したいウインドウをクリックする。

Railsチュートリアルメモ - 第11章

$
0
0

(メモの目次記事はこちら)[https://qiita.com/yokohama4580/items/dedfd5510080273dc2a0]

(公式Railsチュートリアル第11章へのリンク)[https://railstutorial.jp/chapters/account_activation?version=5.1#cha-account_activation]

サマリ

  • メールの送信とアカウント有効化機能の実装
  • メタプログラミング
  • SendGridを利用した本番環境でのメール送信

ポイント

  • rails generate mailerでメーラーの雛形を作成できる
    • e.g. rails generate mailer UserMailer account_activation password_reset
    • 生成されるHTML/textメーラーのレイアウトはapp/views/layoutsで定義されている
  • コントローラー同様、メーラーの中で作成したインスタンス変数はテンプレートの中で使用することができる
  • 送信先やメールタイトルなどはmailメソッドで指定する
    • e.g. mail to:hoge@sample.com
  • deliver_nowメソッドを呼び出すことでメールを送信する
    • e.g. UserMailer.account_activation(@user).deliver_now
  • 名前付きroot
    • 名前付きrootの第一引数は:idになりBase64でエンコードされてURLが生成される
    • 第二引数としてハッシュを渡すとURLパラメーターにしてURLを生成してくれる。その際にエスケープも行ってくれる。
    • 名前付きrootの引数として指定されたものはコントローラー内でparams[:引数]でデコードされた状態で取り出すことができる
  • 以下を行うとメールのプレビューが有効になる
    • config/environments/development.rbに以下を追記する
    • test/mailers/previews/user_mailer_preview.rbを修正する
    • プレビューURLはhttps://localhost:3000/rails/mailers/user_mailer/
config.action_mailer.raise_delivery_errors=trueconfig.action_mailer.delivery_method=:testhost='localhost:3000'config.action_mailer.default_url_options={host: host,protocol: 'https'}
  • assert_matchで正規表現を利用してassertできる

  • sendメソッドは引数を評価してから実行するので、メタプログラミング(プログラムによるコードの生成)を行う際に利用される
    e.g.

attribute="foobar"user.send("#{attribute}_digest")# => user.foobar_digestが実行される
  • テストの中でのみassignsメソッドを使うと対応するアクション内のインスタンス変数にアクセスできるようになる

    • e.g. user = assigns(:user) => @userにアクセス可能になる
  • heroku addons:create sendgrid:starterでherokuにsendgridを導入できる

感想、詰まった箇所など

  • config/environments/development.rbを書き換えた後にサーバーの再起動を行わなかったせいでMissing host to link to! Please provide the :host parameter,...というエラーが出てしまい少し詰まった。
  • herokuにSendGridを追加した後、画面からユーザー登録を行うとメールが飛ばずにWe're sorry, but something went wrong.というエラー画面が表示された。ログを確認したところNet::SMTPAuthenticationError (535 Authentication failed: account disabledとなっていた。
  • 原因分からず解消しなかったため、herokuの画面からSendGridを「Delete Add-on」した後、再度SendGrid追加しようとしたところError Provisioning User - User status - bannedと表示されてしまった。
  • herokuアプリ自体を再作成してからsendgridを再追加することで解消した。

関数の呼び出しと参照

$
0
0

はじめに?

JavaScriptを使用するにあたり、関数はオブジェクトと考えたほうが良いです。
※オブジェクトについての説明は、下記を参照下さい。
オブジェクト

引数として関数に渡したり、変数に代入したりすることができます。

注意する点として、

関数の呼び出しと参照を区別しましょう。

記述例

実行される例functionsports(){return"baseball";}console.log(sports());// baseball

関数名に () を付けると関数の呼び出しになります。
上記では、sports という、関数をbaseballと定義し、
実行されました。

実行されない例functionsports(){return"baseball";}console.log(sports);// function sports()

関数名に () を付けずに関数名だけを書くと、
参照しているだけに、
なってしまいます:pensive:

参照では、変数や定数への代入が可能になります。

constfood=sports;// 関数を food に代入console.log(food());// baseball

上記では、 sports を food という名前で呼び出しています。

まとめ

参照では、
定義した関数名を他の場所で、
名前を変えて、実行する事ができます。

ただし、
代入が可能になってしまうと、
コードが長くなってしまった時、
定義されている物が、分からなくなってしまいます。
記述ミスが出てきます。

使用する際は、注意しましょう。

森久保乃々のネガティブ度を感情分析してみましたけど...。【ポジパと比較】

$
0
0

こちらの記事を見てCOTOHA APIというものを知り,面白そうだったので触ってみることに.
今回はCOTOHA APIを使って森久保乃々のネガティブ度を感情分析してみました.

環境

  • macOS Mojave 10.14.6
  • Python 3.7.6

COTOHA APIとは

自然言語,音声の処理を簡単に行えるAPIです.例えば構文解析や音声認識などができます.NTTコミュニケーションズが提供しています.

森久保乃々とは

アイドルマスターシンデレラガールズに登場するアイドルの1人で,14歳の少女です.机の下がホームで,ときにはプロデューサーから逃げ回ったり,ときにはアイドルを頑張ったりする,そんな子です.
普段は「〜ですけど...」と後ろ向きな発言が多い彼女ですが,一体どれほどネガティブなのか,それを検証してみようというわけです.

感情分析

使い方はこちら
無料枠だと1日1000コールという上限があるので注意.

例えば,初期Nカードの
「あの…もっ…もりくぼですけど…あ、はい、森久保乃々ですけど、あの、プロデューサーさん、いきなりで申し訳ないのですけど、あの、あたし、もうアイドルとか辞めようかなって思って…あの、その…」
というセリフをCOTOHA APIで感情分析すると以下のような結果になります.

{'result': {'sentiment': 'Negative', 'score': 0.48786837208987766, 'emotional_phrase': [{'form': '申し訳ない', 'emotion': 'N'}]}, 'status': 0, 'message': 'OK'}

scoreは0から1の範囲で出るので,このセリフはそこそこネガティブといえるでしょう.感情には「Positive」「Neutral」「Negative」の3種類があります.

実践

  • 分析対象のセリフはMobage版アイドルマスターシンデレラガールズ内に実装されているカードとする.カード1枚につき14種類のセリフがある.
  • 特訓前後で同じセリフは省く.
  • セリフはwebサイトからスクレイピングしてくる.(手作業の方が早かったかもしれない・・)
  • 各感情の回数,割合,平均スコアを算出.
  • さらに,割合×平均スコアを感情の度合いとする.これは,ポジティブなセリフが多ければ多いほど,かつそのスコアが高ければ高いほどポジティブであると考えられるためです.例えば,100%全てがポジティブなセリフで,その平均スコアが1.0なら,度合いは(positive, neutral, negative)=(1, 0, 0)となります.

コード

Githubにあげています.

結果

総セリフ数:410
このうち1つだけ感情が「Positive/Negative」のものがあったので,それは計算に入っていません.

感情回数割合 平均スコア度合い
Positive135回33%0.4280.141
Neutral215回52%0.3420.179
Negative59回14%0.5510.079

Negativeの平均スコアは他より高いものの,回数が少ないため度合いは低くなっています.少し意外な結果でしたが,これは彼女が初期の頃より成長している証だとも言えます.実際,初期のカードのみで感情分析してみると以下のような結果でした.

総セリフ数:25

感情回数割合 平均スコア度合い
Positive6回24%0.3580.086
Neutral12回48%0.3800.183
Negative7回28%0.5800.163

 比較

1人の結果だけでは評価しきれない部分もあるので,他のアイドルと比べてみます.今回はポジティブパッションを感情分析してみることに.
ポジティブパッションとは,本田未央,日野茜,高森藍子の3人からなるユニットの名前です.ポジティブでパッションな彼女たちならばきっと結果も変わってくるでしょう.

本田未央

総セリフ数:476

感情回数割合 平均スコア度合い
Positive199回41.8%0.4620.193
Neutral265回55.7%0.4210.234
Negative12回2.5%0.4420.011

日野茜

総セリフ数:409

感情回数割合 平均スコア度合い
Positive154回37.7%0.4250.160
Neutral228回55.7%0.4380.244
Negative27回6.6%0.3940.026

高森藍子

総セリフ数:457
このうち1つだけ感情が「Positive/Negative」のものがあったので,それは計算に入っていません.

感情回数割合 平均スコア度合い
Positive263回57.5%0.4640.267
Neutral172回37.6%0.3990.150
Negative21回4.6%0.4780.022

先ほどに比べて3人ともネガティブ度が低くポジティブ度が高い結果となりました.単純に回数だけを見てもネガティブな発言が少ないのがわかります.流石ポジパ.

度合いに関してまとめると以下のようになります.

名前Positive度Neutral度 Negative度
森久保乃々0.1410.1790.079
本田未央0.1930.2340.011
日野茜0.1600.2440.026
高森藍子0.2670.1500.022

こうしてみると目に見えて差があるように感じますね.藍子が一番ポジティブ度高かったのは意外でした・・.まあ対象としたセリフを限定したというのもあるのでしょうけど.

今回得たデータを他の手法で解析してみるのも面白そうなのでまた機会があればやってみたいですね.

まとめ

森久保乃々はやっぱりネガティブだったけど,昔よりは成長してるぞ森久保ォ!

初心者の初心者による初心者のためのランダムフォレスト(理論)

$
0
0

1. 本記事の目的

本記事では、ランダムフォレストについて理論的な説明を詳しくしていきます。
最近は深層学習を用いた研究が活発ですが、まだランダムフォレストの適用がふさわしい場面も多々あると言われています。そこで本記事では、気軽に利用できる機械学習アルゴリズムであるランダムフォレストへの理解を深めることで、より応用的な活用を可能にすることを目的とします。
加筆修正の必要箇所がございましたら、是非ご指摘頂けると幸いです。

2. ランダムフォレストの概要

ランダムフォレストは、権威ある記事では以下のように説明されています。

ランダムフォレストは、機械学習のアルゴリズムであり、分類、回帰、クラスタリングに用いられる。決定木を弱学習器とするアンサンブル学習アルゴリズムであり、この名称は、ランダムサンプリングされたトレーニングデータによって学習した多数の決定木を使用することによる。
フリー百科事典『ウィキペディア(Wikipedia)』

あるいは、

ランダムフォレスト(random forests)は機械学習のアルゴリズムのひとつで、決定木による複数の弱学習器を統合させて汎化能力を向上させる、アンサンブル学習アルゴリズムである
日経リサーチ「ランダムフォレスト」

これらの説明をみると、どうやらランダムフォレストは「決定木をベースとし、決定木を複数合体させた機械学習アルゴリズム」のようです。
決定木が複数束ねられていることから、フォレストと呼ばれていることが分かります。

つまり、ランダムフォレストの理解のためにはまず決定木について理解しなければなりません。
以下の記事では、その決定木についての詳説を行っているので、本記事では割愛します。
参考:初心者の初心者による初心者のための決定木

図49.png

現時点では何となく上図のイメージを持たれているところでしょうか。図左部では代表値と記していますが、多くは平均値を代表値として扱うことが多いようです。
このように、ランムフォレストは決定木を複数組み合わせ、その出力結果を総合して解釈することによって学習を行います。

しかし、組み合わせる決定木が同じだと、当然決定木を何本組み合わせたところで同じ出力結果が複数出力されるだけで、平均値による算出や多数決を行っても全く意味がありません。
そして決定木モデルは、そのアルゴリズムの性質上、モデル生成のための入力データが同じ場合は基本的には同じ決定木モデルが生成されてしまいます。(厳密には、不純度の算出の手法を替えることで異なるモデルとすることは可能です)

50.png

ですが一番初めの図では、回帰木1, 回帰木2, 回帰木3など異なる決定木モデルが生成されていました。これは複数モデルの組み合わせでモデルの精度を上げるランダムフォレストのまさに狙い通りになっています。
ではランダムフォレストでは、どのように複数パターンの決定木(決定木1, 決定木2, 決定木3...)を生成しているのでしょうか。
この疑問は、ランダムフォレストのアルゴリズムを理解することで解決されます。

3. アルゴリズム

ランダムフォレストのアルゴリズムは、その順で大きく三つから成ります。

1. データの抽出

2. 各データセットに対する決定木モデルの生成

3. 予測のためのデータを入力し、全ての決定木モデルによる結果を統合、1つの予測結果として出力する。

以下では、それぞれのステップについて細かく説明していきます。

3.1. 訓練データからN個のブートストラップデータ集合を抽出

ランダムフォレストでは、このデータ抽出が一つ大きな特徴として挙げられます。
先述したように、ランダムフォレストは決定木を複数組み合わせた学習器なので、その決定木モデルはそれぞれ異なる必要があり、そのためには、そのモデル生成のための教師データを異なるものにする必要があります。

ここで用いられるのが、ブートストラップ法という手法です。

ブートストラップ法

母集団となるデータがあるときに、母集団から重複を許してランダムにいくらかデータを取り出して再標本化をする手法。

具体例としては、
母集団を$X=x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9, x_{10}$としたとき、
1. 再標本化を行う回数と,再標本化されたサンプルのサンプルサイズを設定する(例では再標本化を3回,サンプルサイズを5としておく)
2. 母集団$X$から重複を許してランダムにサンプリングをする
ことで、

$$X_1 = x_1, x_3, x_3, x_6, x_9$$$$X_2 = x_2, x_2, x_2, x_3, x_7$$$$X_3 = x_2, x_4, x_4, x_5, x_8$$

というブートストラップデータ集合が抽出されます。

このブートストラップ法を用いて、ランダムフォレストにおいてはまず、「訓練データから、n個のデータから成るN個のブートストラップデータ集合を抽出」します。

3.2. 各データセットに対する決定木モデルを生成

続いて、3.1.で抽出したN個のデータ集合に対して、N個の決定木$T^{k}_n(k=1,2,...,N)$を生成する。
ここで非常に重要となるのが、この決定木の生成において、p個の特徴量(説明変数)からm個をランダムに選ぶということです。

  • ランダムサンプリングする特徴量の数mはユーザが自由に設定することができますが、一般的には変数の数の正の平方根を取ることが多いようです。

51.png

そして、この後決定木$T^{k}_n(k=1,2,...,N)$それぞれに対して学習を行わせるわけなのですが、その決定木アルゴリズムに関しては前記事(初心者の初心者による初心者のための決定木)で説明しているので今回は割愛させて頂きます。(そこが大変笑)

3.3. 全ての決定木モデルによる結果を統合、1つの予測結果として出力する。

このステップについては簡単な説明に留めますが、決定木$T^{k}_n(k=1,2,...,N)$を介してN個の出力結果が得られるので、回帰の時には平均値を、また分類の時には多数決を行うことによって、一つの出力結果を得ることができます。

図49.png

3.4. アルゴリズムまとめ

  1. 訓練データから、n個のデータから成るN個のブートストラップデータ集合を抽出

  2. p個の特徴量からm個をランダムに選び、各データセットに対する決定木モデル$T^{k}_n(k=1,2,...,N)$の生成

  3. 予測のためのデータを入力し、全ての決定木モデルによる結果を統合、1つの予測結果として出力する。(回帰の時は平均値、分類の時は多数決)

52.png

4. 特徴

ここで最後に、学習アルゴリズムとしてのランダムフォレストの長所/短所を整理します。

長所

  • 各決定木を作成する計算は並列化できるので、高速な計算が可能
  • 特徴量のスケーリングが必要ない(SVMなどの分類手法では必要になる)
  • 考慮するパラメータが少ない
  • どの特徴量が重要かを知ることができる

短所

  • 複雑なデータではSVMなどの分類手法に比べて汎化性能が下がる
  • ノイズが多すぎるデータでは過学習してしまう
  • 決定木よりも計算が複雑

5. 参考記事

初心者の初心者による初心者のための決定木
ブートストラップサンプリング(Bootstrap Sampling)法とそのscikit-learnを用いた実行
ランダムフォレストとは?PythonとRで実装してみよう!
ランダムフォレストの概要を大雑把に解説
【機械学習】ランダムフォレストについて メモ
ランダムフォレストの理論と重要な特徴量の選定
【機械学習】ランダムフォレスト

COTOHAで自分のQiita投稿文章をチェックしてみる。

$
0
0

きっかけ

COTOHAに関して、自分の前の記事とかでちょっとは触っていた。そんな中、あるQiitaの広告に気づく。
今、言語処理100本ノック 2015を進めているところではあるが、これは参加しないわけにはいかない。

ネタ探し

おそらくここが一番難しい所。明確に何か目的がある時にはよいけども、いざ何かネタを探そうとするとうまい事思いつかないのが世の常。お笑い芸人の皆さんは、ネタ帳を持ち歩き、ネタになりそうなものを探して気づいたら書き留めているという話。しかし締め切りは3月15日。明日。

あがく(その1)

既にこのキャンペーンに参加している人はたくさんいる。COTOHA開発者ブログを見ると色々なアイデアがそろっていて、見ているだけで面白い。そして同時にヒントになるものが無いか探しまくる。そして気づく。他の人のアイデアを見てもそれを超える事を思いつくのは難しい事に。ただ、雰囲気は感じる事が出来た。このあがきは無駄ではなかった。
ここで気づいた事。ここはシンプル行くべき。時間も無い。

あがく(その2)

前述ステップでもう一つ気づいた事。COTOHA APIには各種機能が準備されている。それぞれの具体的な使用例も挙げてくれている。一度ちゃんと一通り目を通しておくべき。ここで前準備期間がもう少しあれば何か思いついたかもしれない。もっと早い段階で読んでおくべきだった。
API一覧

あがく(その3)

この時点では実はちょっと諦め気分。でも諦めきれない。すでに時遅しかもしれないが、色々な文章を色々なサービスに投入してその結果を見てみると何か面白いものが出てくるかもしれない。
自然言語処理を簡単に扱えると噂のCOTOHA APIをPythonで使ってみた
のAPIライブラリ(?)を利用させて頂く。
使う文章は 自分が書いた前の記事「courseraのMachineLearningを修了。それに関して思いを馳せてみた。」。ポエムとして書いた文章なので、解析対象としては比較的適切と判断。とりあえず、キーワード抽出を使って何かつかめないか見てみる。

少し改造させて頂く(投稿文章はsample.txtに保存済み)
# ・・前略・・
# キーワード抽出API
defkeyword(self,document,max_keyword_num=5):#キーワードの上限個数に対応
# キーワード抽出API URL指定
url=self.developer_api_base_url+"v1/keyword"# ヘッダ指定
headers={"Authorization":"Bearer "+self.access_token,"Content-Type":"application/json;charset=UTF-8",}# リクエストボディ指定
data={"document":document,"max_keyword_num":max_keyword_num#この部分を追加させてもらう
}# ・・中略・・
#メイン部分
try:test_data=open("sample.txt","r")test_lines=test_data.readlines()sentence=test_lines# キーワード抽出API
result=cotoha_api.keyword(sentence,max_keyword_num=10)# 出力結果を見やすく整形
result_formated=json.dumps(result,indent=4,separators=(',',': '))print(codecs.decode(result_formated,'unicode-escape'))finally:test_data.close()

実行結果
コンソール出力
{"result": [{"form": "色々",
            "score": 81.724014
        },
        {"form": "機械学習",
            "score": 58.11082
        },
        {"form": "知識",
            "score": 54.63603
        },
        {"form": "自分",
            "score": 50.586876
        },
        {"form": "万能",
            "score": 39.102345
        },
        {"form": "簡単",
            "score": 32.145184
        },
        {"form": "活用",
            "score": 27.079329
        },
        {"form": "世の中",
            "score": 26.16732
        },
        {"form": "部分",
            "score": 25.904205
        },
        {"form": "勉強",
            "score": 24.463238
        }],
    "status": 0,
    "message": ""}


突出して「色々」がポイント高いw。数えてみたら10回使ってる。恐らく一般的な文章と比べて出現頻度が高い単語がキーワードとして選ばれている。言い換えればここに自分が思ってない単語が出てきていたらそれは口癖みたいなものだろう。ちなみに今回の文章も既に3回使っている。
希望としては「知識レイヤ」とかの単語が出てきてほしかった。
でもこれはこれで、自分が書いた文章の特徴が出てきて面白い。そして変に同じフレーズを繰り返していないかのチェックに使えそう。

という事で、投稿テーマをQiitaに投稿する(に限らないが)文章のチェックにCOTOHAを活用する事に決める。

投稿文章チェックしてみる

「不用意なフレーズ繰り返しチェック」「文章口調チェック」「感情チェック」のチェックを行いたい。

不用意なフレーズ繰り返しチェック

これは前述のキーワード抽出そのまま。トップ10の中に自分が表現したかった事と違っている単語が入っていたら見直し対象にする。

文章口調チェック

校正でチェックする事の一つに口調のチェックがある。「です・ます調」「だ・である調」を両方使ってはいけないというルール。両方の回数をチェックする事で見直す事が出来るようにする。

形態素解析

まずは、形態素解析をしてみる。analyze_all.json に出力は保存。

構文解析にはparseを使用
# 解析対象文
try:test_data=open("sample.txt","r")test_lines=test_data.readlines()# sentence = ' '.join(test_lines)
sentence=test_lines# 構文解析API実行(全角スペースで全文章をつなげる)
result=cotoha_api.parse(' '.join(sentence))# 出力結果を見やすく整形
result_formated=json.dumps(result,indent=4,separators=(',',': '))print(codecs.decode(result_formated,'unicode-escape'))finally:test_data.close()

実行結果
階層及び句点近辺
{"result":[{"chunk_info":{"・・中略・・":""},"tokens":[{"・・中略・・":""}]},{"chunk_info":{"id":347,"head":351,"dep":"P","chunk_head":0,"chunk_func":3,"links":[]},"tokens":[{"id":927,"form":"には","kana":"ニハ","lemma":"には","pos":"連用助詞","features":[],"attributes":{}},{"id":928,"form":"い","kana":"イ","lemma":"いる","pos":"動詞語幹","features":["A"],"attributes":{}},{"id":929,"form":"る","kana":"ル","lemma":"る","pos":"動詞接尾辞","features":["終止"],"attributes":{}},{"id":930,"form":"。","kana":"","lemma":"。","pos":"句点","features":[],"attributes":{}}]},

文末品詞チェック

result[?].tokens[?] を調べて、pos(品詞)が"句点"のものを見つけ、その手前の文言を調べればよさそう。※posは「Part of speech」の事らしい。

importjsonjson_file=open("analyze_all.json","r")try:wk_lines=json_file.readlines()# sentence = ' '.join(test_lines)
joson_str=''.join(wk_lines)json_body=json.loads(joson_str)result=json_body['result']forchunkinresult:wkstr=''tokens=chunk['tokens']foridx,tokeninenumerate(tokens):wkstr+=token['form']iftoken['pos']=='句点'andidx>=1:print('{0:s} 終了品詞:{1:s}'.format(wkstr,tokens[idx-1]['pos']))finally:json_file.close()

実行結果
階層及び句点近辺
考えてみた。 終了品詞:動詞接尾辞
してみたい。 終了品詞:動詞接尾辞
ない。 終了品詞:形容詞接尾辞
良い。 終了品詞:形容詞接尾辞
受講開始。 終了品詞:名詞
チャレンジしてみたくもなった。 終了品詞:動詞接尾辞
終わった。 終了品詞:動詞接尾辞
修了。 終了品詞:名詞
思う)。 終了品詞:括弧
思う。 終了品詞:動詞接尾辞
支払った。 終了品詞:動詞接尾辞
感覚)。 終了品詞:括弧
簡単ではない。 終了品詞:形容詞接尾辞
実感。 終了品詞:名詞
述べられてる。 終了品詞:動詞接尾辞
痛感。 終了品詞:名詞
事も。 終了品詞:連用助詞
つながる。 終了品詞:動詞接尾辞
知った。 終了品詞:動詞接尾辞
解る。 終了品詞:動詞接尾辞
様子。 終了品詞:名詞
思う。 終了品詞:動詞接尾辞
もの。 終了品詞:接続接尾辞
楽しそう。 終了品詞:形容詞接尾辞
よる。 終了品詞:動詞接尾辞
見つかる。 終了品詞:動詞接尾辞
深めたい。 終了品詞:動詞接尾辞
クソアプリ。 終了品詞:名詞
思われる。 終了品詞:動詞接尾辞
考察していきたい。 終了品詞:動詞接尾辞
感じる。 終了品詞:動詞接尾辞
諦めた。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
事。 終了品詞:名詞
使われる。 終了品詞:動詞接尾辞
感じ。 終了品詞:名詞
思われ。 終了品詞:動詞接尾辞
無かった。 終了品詞:形容詞接尾辞
世の中にはいる。 終了品詞:動詞接尾辞
復習してみました。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
しそう。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
呼べたりするのかな? 終了品詞:終助詞
持ってるらしい。 終了品詞:形容詞接尾辞
ライブラリ? 終了品詞:名詞
事らしい。 終了品詞:形容詞接尾辞
書かれてた。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
あったし。 終了品詞:接続接尾辞
スムースになる。 終了品詞:動詞接尾辞
ありそう。 終了品詞:動詞接尾辞
痛感。 終了品詞:名詞
思う。 終了品詞:動詞接尾辞
レベル。 終了品詞:名詞
感じた。 終了品詞:動詞接尾辞
必要。 終了品詞:名詞
必要。 終了品詞:名詞
感じる。 終了品詞:動詞接尾辞
感じ。 終了品詞:名詞
あるかな? 終了品詞:終助詞
思う。 終了品詞:動詞接尾辞
あった。 終了品詞:動詞接尾辞
あるか? 終了品詞:終助詞
はず。 終了品詞:名詞
思う。 終了品詞:動詞接尾辞
感謝です。 終了品詞:判定詞
はず。 終了品詞:名詞
想定される。 終了品詞:動詞接尾辞
使っているらしい。 終了品詞:形容詞接尾辞
使われてるらしい。 終了品詞:形容詞接尾辞
思う。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
思う。 終了品詞:動詞接尾辞
あるかもしれない)。 終了品詞:括弧
予定。 終了品詞:名詞
なってしまった。 終了品詞:動詞接尾辞
ありがとうございました。 終了品詞:独立詞

「復習してみました」がちょっと違うな、と思ってみてみたら、引用させてもらった他の投稿のタイトルだった。結構「だ・である調」は守れていたらしい。しかし、「思う」で終わってる文章が多い。まぁ「思いを馳せてみる」ポエムなのである意味妥当w。

感情チェック

各文章の感情をチェックして、意図せぬ感情起伏になってないかチェック。
sentimentのAPIは 自然言語処理を簡単に扱えると噂のCOTOHA APIをPythonで使ってみたが投稿されたときには無かったのか、ソース中になかったので、他の関数のをコピーして追加。

# 文タイプ判定API
defsentiment(self,sentence):# 文タイプ判定API URL指定
url=self.developer_api_base_url+"v1/sentiment"# ヘッダ指定
headers={"Authorization":"Bearer "+self.access_token,"Content-Type":"application/json;charset=UTF-8",}# リクエストボディ指定
data={"sentence":sentence}# リクエストボディ指定をJSONにエンコード
data=json.dumps(data).encode()# リクエスト生成
req=urllib.request.Request(url,data,headers)# リクエストを送信し、レスポンスを受信
try:res=urllib.request.urlopen(req)# リクエストでエラーが発生した場合の処理
excepturllib.request.HTTPErrorase:# ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
ife.code==401:print("get access token")self.access_token=self.getAccessToken(self.client_id,self.client_secret)headers["Authorization"]="Bearer "+self.access_tokenreq=urllib.request.Request(url,data,headers)res=urllib.request.urlopen(req)# 401以外のエラーなら原因を表示
else:print("<Error> "+e.reason)# レスポンスボディ取得
res_body=res.read()# レスポンスボディをJSONからデコード
res_body=json.loads(res_body)# レスポンスボディから解析結果を取得
returnres_body
こんな感じで出力してsentiment.jsonにファイル保存。
try:test_data=open("sample.txt","r")test_lines=test_data.readlines()# sentence = ' '.join(test_lines)
sentence=test_linesjoined_sentence=''.join(test_lines)sentence_list=joined_sentence.split('。')print('[')forsentenceinsentence_list:result=cotoha_api.sentiment(sentence)result_formated=json.dumps(result,indent=4,separators=(',',': '))print(codecs.decode(result_formated,'unicode-escape'))print(',')print(']')finally:test_data.close()
1リクエストの結果例
{"result":{"sentiment":"Positive","score":0.5401555923096191,"emotional_phrase":[{"form":"流行り","emotion":"P"}]},"status":0,"message":"OK"}

実行結果
jsonを処理して出力した結果
Neutral 0.268624    []
Positive    0.540156    [{'form': '流行り', 'emotion': 'P'}]
Neutral 0.303050    []
Positive    0.271682    [{'form': '良い', 'emotion': 'P'}]
Positive    0.071115    [{'form': '良い', 'emotion': 'P'}, {'form': 'まずは無料', 'emotion': 'P'}, {'form': 'カッコよくて欲しい', 'emotion': 'P'}]
Neutral 0.291507    []
Positive    0.363525    [{'form': '強く沸き上がり', 'emotion': 'P'}]
Neutral 0.274798    []
Neutral 0.264217    []
Positive    0.585754    [{'form': '早い', 'emotion': 'P'}]
Positive    0.256760    [{'form': '良い', 'emotion': 'P'}]
Neutral 0.231494    []
Negative    0.774002    [{'form': 'いけない', 'emotion': 'N'}, {'form': '簡単ではない', 'emotion': 'PN'}]
Positive    0.599232    [{'form': '実感', 'emotion': 'P'}]
Neutral 0.269050    []
Positive    0.092880    [{'form': 'よい', 'emotion': 'P'}, {'form': '適切な', 'emotion': 'P'}, {'form': '正確さ', 'emotion': 'P'}, {'form': '痛感', 'emotion': 'P'}]
Negative    0.829964    [{'form': '長い時間がかかる', 'emotion': 'N'}, {'form': '失敗すると', 'emotion': 'N'}, {'form': '多大な', 'emotion': 'PN'}]
Neutral 0.296784    [{'form': 'ダイレクトな', 'emotion': 'PN'}]
Neutral 0.346448    []
Positive    0.247956    [{'form': '簡単', 'emotion': 'PN'}, {'form': '解る', 'emotion': 'P'}]
Neutral 0.383904    []
Neutral 0.247514    [{'form': '簡単ではない', 'emotion': 'PN'}]
Neutral 0.369362    []
Positive    0.389558    [{'form': 'やっぱり楽しそう', 'emotion': 'P'}]
Neutral 0.292794    []
Negative    0.769889    [{'form': '初心者向け', 'emotion': 'N'}]
Neutral 0.334311    []
Positive    0.589350    [{'form': '壮大な', 'emotion': 'P'}]
Neutral 0.341264    [{'form': '簡単な', 'emotion': 'PN'}]
Neutral 0.350338    []
Positive    0.347399    [{'form': '知識があった', 'emotion': 'P'}, {'form': '比較的スムース', 'emotion': 'P'}]
Negative    0.660826    [{'form': '諦めた', 'emotion': 'N'}, {'form': 'なんとかなると', 'emotion': 'PN'}]
Neutral 0.271371    []
Negative    0.691616    [{'form': '無理だったろう', 'emotion': 'N'}]
Neutral 0.286343    []
Positive    0.669637    [{'form': '良い', 'emotion': '喜ぶ'}, {'form': '理解', 'emotion': 'P'}, {'form': 'なお良い感じ', 'emotion': 'P'}]
Positive    0.600185    [{'form': '役に立つと', 'emotion': 'P'}]
Neutral 0.255581    [{'form': '忘れていなかった', 'emotion': 'PN'}]
Neutral 0.368193    []
Neutral 0.354854    []
Neutral 0.343578    []
Negative    0.871992    [{'form': 'ただとらわれすぎると', 'emotion': 'N'}]
Neutral 0.331474    []
Neutral 0.425332    []
Positive    0.333227    [{'form': '必要ある', 'emotion': 'P'}]
Neutral 0.265064    [{'form': 'なんとかなると', 'emotion': 'PN'}]
Positive    0.536926    [{'form': '間違いではない', 'emotion': 'P'}]
Positive    0.629587    [{'form': '対応可能と', 'emotion': 'P'}]
Neutral 0.342275    []
Positive    0.505652    [{'form': '理解', 'emotion': 'P'}, {'form': 'スムース', 'emotion': 'P'}]
Negative    0.669981    [{'form': '理解できず間違った', 'emotion': 'N'}]
Positive    0.468893    [{'form': 'よかった', 'emotion': '喜ぶ'}, {'form': '痛感', 'emotion': 'P'}]
Neutral 0.223020    []
Neutral 0.223959    [{'form': '普通', 'emotion': 'PN'}]
Neutral 0.196458    []
Neutral 0.224248    [{'form': '必要', 'emotion': 'PN'}]
Neutral 0.290354    [{'form': '必要', 'emotion': 'PN'}]
Positive    0.773919    [{'form': '絡', 'emotion': '怒る,嫌'}, {'form': '複雑', 'emotion': 'PN'}, {'form': '綺麗な', 'emotion': 'P'}]
Neutral 0.426518    [{'form': '良かった', 'emotion': 'P'}, {'form': '必須でなく', 'emotion': 'N'}]
Neutral 0.159759    [{'form': '相当な', 'emotion': 'PN'}]
Neutral 0.217347    [{'form': '数学的', 'emotion': 'PN'}]
Positive    0.230669    [{'form': '理解する', 'emotion': 'P'}]
Neutral 0.276439    []
Positive    0.639602    [{'form': '感謝です', 'emotion': 'P'}]
Neutral 0.296018    []
Neutral 0.360645    [{'form': '相当な', 'emotion': 'PN'}]
Neutral 0.477751    []
Neutral 0.377498    []
Neutral 0.328837    []
Neutral 0.241177    []
Positive    0.438030    [{'form': '進化', 'emotion': 'P'}]
Positive    0.460860    [{'form': '進化', 'emotion': 'P'}, {'form': '効率的な', 'emotion': 'P'}]
Neutral 0.400177    []
Neutral 0.275407    []
Neutral 0.278125    []
Neutral 0.336289    []

グラフにするとこんな感じ。
image.png
ん?センチメントスコアはPositive/Negativeとは関係ない?Positiveを0、Negativeを-1にしてみる。
image.png
少々Negativeもあるけど、基本的にPositive基調の様子。Positive過ぎもしない。問題無いかな。

感想

本当は下書き保存時のURL指定すると、文章を抽出して一連の処理を一括でやれるようにしたり、グラフ描画とかも一括でやりかった。けど、ちょっと対応に時間かかりそうなので今回は諦めた。
自然言語処理を使って、ささやかながらも何かできた、という感覚を持てた。よかった。

終わりに

自分と同じように、何かしたいと思った時に、その何かを思いつくのが大変という人は多いはず。
基本的には、ネタ探しの部分とか切り捨てる文章だけど、同じように悩んでいる人にとって少しでも参考になればと思いそのままにしてます。

参考にさせてもらったページ

自然言語処理を簡単に扱えると噂のCOTOHA APIをPythonで使ってみた

COTOHA開発者ブログ

Viewing all 21093 articles
Browse latest View live