クイックノート

ちょっとした発見・アイデアから知識の発掘を

AIが動画の見所をスコアリング!【ミドコロAI】

近年、インターネットで動画を見ることがほとんど当たり前になってきました。 しかし、中には長時間の動画もあり、それをずっと見続けるのは厳しいものがあります。

特に生配信を主体とするバーチャルユーチューバー(Vtuber)の配信では、数時間にものぼる超長時間動画が標準的になっています。

忙しい人は、長時間動画のうち見所だけをつまんで視聴したいと思うでしょう。

そこで、AIがVtuberの動画のミドコロを数値化して、グラフでわかりやすく表示してくれるサービスを作成しました。 その名もミドコロAIです。

vtuber.nekast.com

動画の見所が一目瞭然

数値化された見所が動画プレイヤーの下部にグラフで表示されます。 このグラフを見て、ミドコロ値の高い箇所がAIが見るべきと判断したシーンにです。

f:id:u874072e:20200806140204p:plain
ミドコロスコア

グラフ上をクリックすると、動画プレーヤーのシークバーを対応する時間に移動できるので、グラフの山をクリックしていくと見所をつまみながら動画を見ることができます。

自動的にミドコロのみを再生

忙しい人は、グラフをクリックするのすら面倒に感じるかもしれません。 そんな時は、「ミドコロSkip」を有効にしましょう。

「ミドコロSkip」機能では、ミドコロ値が高いところのみを再生するように、自動的に動画をスキップします。イメージはテレビのCM自動スキップ機能のような感じでしょうか。

これで、見所として判定された箇所のみをつまみながら見ることができます。

まとめ

AIが動画の見所をスコアリングしてくれるサービスを紹介しました。 Vtuberの動画が見たいけど、長時間見続けるのはしんどいという方は是非利用してみて下さい。

【Stripe】Checkoutに商品の選択ボックスを付ける

StripeはWebサイトにオンライン決済を導入できるサービスです。
オンラインイベントでの集金にクレジットカード決済を導入したい
と思った時にとても便利です。

Stripeを導入する方法はいくつかありますが、
中でもStripe Checkoutは自動的に生成されたコードをコピペするだけで
サイト内に決済ボタンを導入できてしまいます。

ただし、デフォルトで生成されるコードは、
一つの商品について一つのボタンのみです。

Stripe自体では、一つの商品について複数の料金体系を設定できるのですが、
この場合も、Checkoutで生成されるのは一つの料金に対して一つのボタンです。
このままだと、複数の商品から一つ選んで購入するような形にしたい場合は、
商品の数だけボタンが並ぶことになります。 ちょっとスマートじゃないですよね。

ここでは、生成されるコードに少し改変を加えて、
下の図のように選択ボックスで商品を選択できるようにしたいと思います。

f:id:u874072e:20200715145259p:plain
商品の選択ボックス

準備

まずは、Stripeのアカウントを作成しておきましょう。

次に、Checkout を有効にしておきます。
以下の手順でCheckoutの設定ができます。

  1. ダッシュボードの検索ボックスに「checkout」と入力します。
    f:id:u874072e:20200715151533p:plain
    checkoutを検索
  2. 「Checkoutの設定」をクリックします。
  3. 「Checkoutクライアント専用組み込み」を「有効」にします。
    f:id:u874072e:20200715151759p:plain
    checkoutの有効化
  4. サイトのドメイン名を「ドメイン欄」に入力します。
    f:id:u874072e:20200715151901p:plain
    ドメイン名の入力
  5. 「保存」ボタンをクリックします。

ここではテスト環境で試すことを想定していますが、
本番環境に変更するためにはダッシュボードから利用申請を行う必要があります。

商品の作成

商品はstripeのダッシュボードから「商品」のメニューを開き、
「商品を追加」で新しい商品を作成します。

f:id:u874072e:20200715152458p:plain
商品を追加

表示されるフォームに沿って商品の情報を入力します。
「別の料金を追加」で複数の商品を作っても良いですし、
「商品を追加」を繰り返して複数の商品を作ってもOKです。

※1 料金体系モデルは「標準の料金体系」を想定しています。
※2 支払いは「一括」「継続」のどちらかに統一されていることを想定しています。

サイトに購入ボタンを設置する

それでは作成した商品を購入するボタンをサイトに設置します。

Checkoutのコードを取得する

商品を購入するためのボタンを設置するコードを取得します。
このコードをもとに選択ボックスを付けていきます。

  1. 上記で作成した商品の一つをクリックします。
    f:id:u874072e:20200715153631p:plain
    作成した商品をクリック
  2. 「料金体系」右端の「・・・」をクリックします。
    f:id:u874072e:20200715153750p:plain
    コードスニペットを取得
  3. 「Checkoutのコードスニペットを取得」をクリックします。
  4. 成功時とキャンセル時にリダイレクトされるURLを設定します。
  5. 表示されるコードをコピーします。

単にボタンを設置するだけなら、
このコードをそのままサイト上に貼り付けて完了ですが、
今回は、複数の商品から選択できるようにプルダウンメニューを作成するので、
このコードを少し編集します。

コードを編集する

上記で取得したコードを適当なエディタに貼り付けて編集します。

下の「+」の部分が追加したコードで、
「-」の部分が削除したコードを表します。

<option value='....の所に商品のIDを並べて、
itemA,itemBにはメニューに表示される名前を入力します。

商品のIDは各商品の料金体系の「API ID」欄から取得します。

f:id:u874072e:20200715154841p:plain
商品のID

下では二つの商品のみですが、<option value='....の行を追加することで、
さらに商品を追加していくことができます。

 <!-- Load Stripe.js on your website. -->
 <script src="https://js.stripe.com/v3"></script>

 <!-- Create a button that your customers click to complete their purchase. 
 Customize the styling to suit your branding. -->
+ <form>
+    <select id="stripe_select_box">
+        <option value='ここに商品IDを入力'> itemA</option>
+        <option value='ここに商品IDを入力'>itemB</option>
+    </select>
+ </form>

 <button
  style="background-color:#6772E5;color:#FFF;padding:8px 12px;border:0;border-radius:4px;font-size:1em"
  id="checkout-button-price_1H53TSIcYB2Y06an324Hsf5r"
  role="link"
  type="button"
 >
  Checkout
 </button>

 <div id="error-message"></div>

 <script>
(function() {
  var stripe = Stripe('pk_test_*******************************************');

  var checkoutButton = document.getElementById('checkout-button-price_1H53TSIcYB2Y06an324Hsf5r');
  checkoutButton.addEventListener('click', function () {
+  var select = document.getElementById("stripe_select_box");
+  const num = select.selectedIndex;
+  const price = select.options[num].value;
    // When the customer clicks on the button, redirect
    // them to Checkout.
    stripe.redirectToCheckout({
-     lineItems: [{price: 'price_**********************', quantity: 1}],
+    lineItems: [{price: price, quantity: 1}],
      mode: 'payment',
      // Do not rely on the redirect to the successUrl for fulfilling
      // purchases, customers may not always reach the success_url after
      // a successful payment.
      // Instead use one of the strategies described in
      // https://stripe.com/docs/payments/checkout/fulfillment
      successUrl: 'https://********/success',
      cancelUrl: 'https://********/canceled',
    })
    .then(function (result) {
      if (result.error) {
        // If `redirectToCheckout` fails due to a browser or network
        // error, display the localized error message to your customer.
        var displayError = document.getElementById('error-message');
        displayError.textContent = result.error.message;
      }
    });
  });
})();
 </script>

まとめ

Stripeでプルダウンメニューから選ぶ形式で、
商品の購入ボタンを設置する方法を紹介しました。

オンラインのイベントが増える昨今では、
このようなオンライン決済ツールを上手く使っていきたいですね。

Rで簡単にディリクレ過程混合モデルを触ってみる

クラスタリングではクラスタ数を事前に与えることが多いのですが、
クラスタ数も自動的に推定してしまうのがディリクレ過程混合モデルです。

ディリクレ過程混合モデルを動かそうと思うと、
モデル式を書いて、MCMC数値計算するのがシンプルな方法ですが、
結構面倒なのでちょっと試してみるには少々向いていない。。。

そんな時、簡単に動かすことのできるパッケージを見つけたので、
ここで紹介します。

ディリクレ過程混合モデルとは

過去の記事でディリクレ過程混合モデルについて紹介しているので、
そちらも参照して下さい。

簡単に言ってしまうと、クラスタ数を予め決めずに
データから推定するクラスタリングのためのモデルです。

clean-copy-of-onenote.hatenablog.com

パッケージのインストール

今回使うパッケージはdirichletprocessというパッケージです。

install.packages("dirichletprocess")

でインストールすることができます。

2クラスの分類

まずは、パッケージのマニュアルにも乗っている簡単な例で動かして見ます。

library(dirichletprocess)

dp = DirichletProcessMvnormal(as.matrix(faithful %>% scale))
fdp = Fit(dp,500)
plot(fdp)

ここでは、Rの標準データセットであるfailthfulのデータを使って、
クラスタリングを行なっています。

DirichletProcessMvnormalで、
多次元正規分布を混合したディリクレ過程混合モデルを生成して、
Fitでモデルのフィッティングが行われます。

データは行列形式で与えて、各列が一つの変数、
各行が一つのデータサンプルを表します。
ただし、データはscaleで正規化しておきます。

結果は、下の図のようにプロットされます。

f:id:u874072e:20200624151520p:plain
faithfulのクラスタリング結果

ほんの数行で実行できてしまうのでかなりお手軽ですね。

複数クラスのクラスタリング

せっかくなので、自分でデータを作って、
もう少しクラス数の多い状況で試してみましょう。

データの生成

d次元でC個の異なる平均値を持つ正規分布から、
N個のデータを生成します。

多変量正規分布からデータを生成するために、
mvnfastパッケージを利用しているのでインストールしておきましょう。

library(mvnfast)
C = 5
N = C*25
d = 2

y = NULL
for(i in 1:C){
  mu = rnorm(d,sd = 10)
  n = round(N/C)
  y = rbind(y,rmvn(n,mu,diag(1,d)))
}
plot(y)

今の場合、5個の正規分布からデータを生成していて、
例えば、下のようなデータが得られました。

f:id:u874072e:20200624152013p:plain
生成したデータ

クラスタリングの実行

2クラスの場合と同様に、クラスタリングを実行してみます。

dp = DirichletProcessMvnormal(as.matrix(y %>% scale))
fdp = Fit(dp,1000)
plot(fdp)

実行結果は下のようになりました。

f:id:u874072e:20200624152211p:plain
クラスタリングの結果

真ん中の方と端の方の2つに分類されてます。
確かにそれっぽいといえばそれっぽいのですが、
もう少しクラスを分けて欲しいですよね。

ハイパーパラメータをいじる

ディリクレ過程混合モデルでは、
クラスタ数はデータから自動的に推定されますが、
その数をある程度調整するパラメータ \alpha があります。
 \alpha が大きいほど、多くのクラスタが生まれやすいモデルとなります。

dirichletprocessでは、この \alpha 自体も自動的に調整されるのですが、
 \alpha の事前分布を与えることである程度コントロールできます。

 \alpha の事前分布はガンマ分布で与えられていて、
デフォルトでは G(2,4)となっています。
この状況では \alpha の値は小さくなりやすいので、
大きな値を取りやすいように設定して実行してみましょう。

dp = DirichletProcessMvnormal(as.matrix(y %>% scale),alphaPriors = c(100,10))
fdp = Fit(dp,1000)
plot(fdp)

DirichletProcessMvnormalの引数alphaPriorsで、
 \alpha の事前分布のガンマ分布の形を設定しています。
ここではG(100,10)の分布を設定してみました。
下の図のように、デフォルトの分布よりも大きな値を取りやすい分布です。

f:id:u874072e:20200624153311p:plainf:id:u874072e:20200624153328p:plain
左:G(2,4), 右: G(100,10) の分布

下の図はクラスタリングの結果です。

f:id:u874072e:20200624152817p:plain
クラスタリングの結果

真ん中の二つはくっ付いてしまっていますが、
それ以外は、かなり綺麗にクラスタリングできていることがわかります。

まとめ

ここではRで簡単にディリクレ過程混合モデルによる
クラスタリングができるパッケージを紹介しました。

クラスタリングの実行は数行でできてしまうので、
とりあえず試したいという時にぴったりですね。

メールアカウントが乗っ取られた時にサーバーで行なった対応

朝起きるとそこには大量のエラーメールがありました。

どうやら、管理下のメールアドレスから大量にスパムメールが送信され、
存在しないメールアドレスに送信したメールや、
相手にスパムとして判定されたメールが戻ってきているようです。

問題のメールアドレスは幸いにも(?)使われていないアドレスであったので、
メールアカウントが乗っ取られたということになります。

そこで、今回行なった メールサーバーで管理下のメールアカウントが乗っ取られた時の
対応をまとめておきます。

環境

OS : centOS
メールサーバー: postfix

アカウントのパスワードを変更

対応している間にも常にスパムメールが送られてしまうので、
まずはアカウントを使えないようにしましょう。

ということで、アカウントのパスワードを変更します。

sudo passwd [アカウント名]

今回は使われていないダミーのアカウントだったので、
勝手にパスワードを変更するだけでOKでした。
利用中のアカウントであれば、パスワード変更後、
アカウントの乗っ取りが検出されたので、
パスワードを再設定した旨を知らせる必要があったでしょう。

サーバー上のファイルの確認

メールアカウントが乗っ取られたということは、
サーバにアクセスして不正なファイルが置かれる可能性もあります。

外からのアクセスは遮断していましたが、
念の為、当該アカウントのディレクトリ上に不審なファイルがないか確認します。

こちらは大丈夫そうでした。

キューに溜まったメールを削除する

パスワードの変更でスパムメールの送信は止まりましたが、
送信に失敗したスパムメールがキューに溜まった状態になっているので、
それらのメールを削除します。

キュー内のメールは下のコマンドで確認できます。

sudo postqueue -p

が、大量にあるので手作業で一つづつ消すのは無理そうでした。

下のコマンドでは、キューにあるメールから、
乗っ取りにあった「送信元アドレス」のメールのIDを抽出して、
postsuper -dでそれらのメールを削除しています。

sudo postqueue -p | grep [送信元アドレス] | awk '{print $1}' | sed "s/\*//g" | xargs -I{} sudo postsuper -d {}

再度sudo postqueue -pで、
問題のスパムメールがキューから消えていることを確認します。

まとめ

管理下のメールアカウントが乗っ取られた時に、
メールサーバー上で行なった対応をまとめました。

今回は幸いにも誰も使っていないメールアドレスでしたが、
パスワードポリシーを厳しくするなどして、
簡単には破られないように運用する必要がありますね。

Gmailで「迷惑メールでないことを報告」が効かない時の対処法

Gmailでは自動で迷惑メールを振り分けてくれる機能があります。
ところが、中には迷惑メールでないのに、
迷惑メールに振り分けられてメールを見逃したなんてこともあります。

そのような誤判定を受けたメールについては、
「迷惑メールでないことを報告」ボタンをクリックして、
次のメールからは間違って判定されないことを期待します。

f:id:u874072e:20200605085857p:plain
迷惑メールでないことを報告

ところが、何度「迷惑メールでないことを報告」しても、
何度も迷惑メールに振り分けられてしまうものがありました。

今回はこのように迷惑メールでないことを報告が効かない場合の対処方法をご紹介します。

どうしても迷惑メールになるメールの特徴

今回迷惑メールに振り分けられてしまうメールにはある特徴がありました。
Gmailではメールにアイコンが表示されますが、
迷惑メールと判定されたメールでは、
そのアイコンが?になっていました。

f:id:u874072e:20200605101526p:plain
認証されていないメール送信者のアイコン

このはてなマークは、
メールが認証されていない場合につけられます。

手紙で差出人を偽って書くことができるように、
メールでも差出人を偽ることができてしまいます。
メールの認証とはそのような成りすましを防ぐ仕組みになります。

Gmailでは電子署名SPFという認証の仕組みを使っていますが、
今回問題となっているメールでは送信側で認証の設定を行なっていないため、
送信者が成りすましでないかを判断できず、
スパムメールとして判断されているようです。

SPFの認証が行えなかった場合、
「メッセージのソースを表示」すると、
下のようにSPFがNEUTRALと表示されます。
認証が行われた場合はPASSと表示されます。

f:id:u874072e:20200605101720p:plain
SPFがNEUTRALに

対処法

素直に考えると、
送信側で認証が有効になるように設定してもらえば良いように思います。
ところが、送信側のサーバーは別組織の人が管理しているので、
設定変更のお願いも簡単ではありません。

そこで、受信側で対処する方法を紹介します。
受信側ではフィルタを使って、
指定したメールアドレスの迷惑メールの判定を無効にします。

  1. メール右の「・・・」から「メールの自動振り分け設定」をクリック
    f:id:u874072e:20200605134823p:plain
    メールの自動振り分けを設定
  2. メールアドレスを確認して「フィルタを作成」をクリック
    f:id:u874072e:20200605134934p:plain
    フィルタを作成
  3. 「迷惑メールにしない」にチェックを入れて「フィルタ作成」
    f:id:u874072e:20200605135007p:plain
    迷惑メールにしない

これで、フィルタが作成され、
指定したメールアドレスからのメールは迷惑メールに入らなくなります。

その後届いたメールには、下のように、
フィルタによって迷惑メールに振り分けられなかったと表示されるようになります。

f:id:u874072e:20200605085811p:plain
誤判定を回避

まとめ

Gmailで何度も迷惑メールとして判定されてしまうメールを、
迷惑メールにしない方法を紹介しました。

自動的にメールを振り分けてくれるのは便利な機能ですが、
時には人手で操作することもまだまだ必要ですね。

ノートPCのキーボードでデスクトップPCを操作する

デスクトップパソコンとノートパソコンを併用していると、
デスクがどうしても下の図のようになると思います。

f:id:u874072e:20200528102427p:plain
デスクのイメージ

デスクトップのモニターをバックに、
ノートパソコンを置いて作業するという形ですね。

ここで問題は、
デスクトップのキーボードやマウスをどこに置くのかということです。

デスクが広ければ横に置いたり、
ノートパソコンを触っている間はキーボードを立てかけるなどもあり得ますが、
作業の途中で、ノートパソコンとデスクトップを切り替える時に、
いちいちキーボードを引っ張り出したり、手を移動させるのは結構手間です。

そこで、ノートパソコンのキーボードとトラックパッドを使って、
デスクトップパソコンを操作したいという要望が生まれます。
ここでは、その方法を紹介します。

Chrome リモートデスクトップを導入する

別パソコンを操作すると言えば、
リモートデスクトップというツールが代表的です。
ここでは簡単に導入できるChromeリモートデスクトップを使うことにします。

デスクトップパソコンはアクセスされる側、
ノートパソコンはアクセスする側とします。

デスクトップ側の設定

  1. Google Chrome をインストールする
  2. アドレスバーに remotedesktop.google.com/access を入力しEnter
    f:id:u874072e:20200529172834p:plain
    アドレスバーに入力
  3. 「リモートアクセスの設定」の右下のボタンをクリック
    f:id:u874072e:20200529172910p:plain
    リモートアクセスの設定
  4. ファイルがダウンロードされたらインストール
  5. PCの名前とPIN番号を設定する

ノートパソコン側の設定

  1. Google Chroomeをインストールする
  2. アドレスバーに remotedesktop.google.com/access を入力しEnter
  3. アプリとしてChrome リモートデスクトップをインストールする
    f:id:u874072e:20200604134859p:plain
    アプリとしてインストール

最後のアプリとしてインストールすることは必須ではなく、
Chrome上で利用できます。

ノートPCとデスクトップPCの操作を切り替える際に、
Chrome のタブを切り替えるよりアプリの切り替えの方が使いやすいので、
ここではアプリとしてインストールすることにします。

Chrome リモートデスクトップを使ってPCを操作する

上でChrome リモートデスクトップの導入が完了したら、
ノートPCからデスクトップPCにアクセスして操作します。

ノートPCからデスクトップPCに接続する

  1. Chrome リモートデスクトップを起動する
    f:id:u874072e:20200604145301p:plain
    chrome remote desktop の起動
  2. 接続するPCをクリックする
    f:id:u874072e:20200604145342p:plain
    接続するPCを選択
  3. PINを入力する

これでノートPCからデスクトップPCが操作できるようになります。

ノートPCとデスクトップPCの切り替え

ノートPCとデスクトップPCの切り替えは、
ノートPCで利用しているアプリを切り替えるだけです。

WindowsならAlt + Tab、
MacならCommand + Tab
のショートカットを利用して切り替えるのが便利です。

まとめ

ノートPCから手を離さずに、
後ろにあるデスクトップPCを操作する方法を紹介しました。

ローカルのネット環境にもよりますが、
カーソル移動や文字入力もほぼラグ無く操作できます。
デスクトップのモニタを見ながら、
ノートPCのキーボード入力をすれば、
まるでノードPCがただの無線キーボードになったかのように感じます。

Outlookで削除できない「標準アカウント」を消す方法

もう使わなくなったメールアカウントをOutlookから削除しようとしたら、
どうしても削除できないという現象が発生しました。

削除しなくても害がなければそのまま放置もありなのですが、
使ってないアカウントに対して毎回認証が要求されて、
結構なストレスのある状況でした。

ここでは、その解決方法を紹介します。

アカウントが削除できない問題

通常であれば、アカウントの削除は、
Outlook上で「ファイル」→「情報」タブ→「アカウントの設定」から、
削除したいアカウントを選択して、「削除」をクリックします。

f:id:u874072e:20200519093328p:plain
アカウントの削除

ところが、この方法でアカウントが削除できない場合があります。

エラーメッセージ

今回は、アカウントを削除する際に、
次のエラーメッセージが表示されました。

「プロファイルに標準アカウント以外のアカウントが存在する場合、標準アカウントを削除できません。標準アカウントを削除する前に、他のすべてのExchangeアカウントを削除する必要があります。」

「標準アカウント」という謎のキーワードが表示されていて、
この「標準アカウント」は削除できないようです。

メールアカウントの設定には「既定のアカウント」というものがあり、
メールを送信する際にデフォルトで利用するアカウントを設定できますが、
「標準アカウント」と「既定のアカウント」は別物です。
削除しようとしているメールアカウントを既定のアカウントから外しても、
やはり削除することはできません。

標準アカウントの意味

エラーメッセージでそのまま調べても、
「標準アカウント」が何を意味しているのかが分かりませんでした。

恐らくメッセージの翻訳がまずいのだろうと思い、
英語で同様のエラーを検索してみたところ、
以下の英語版では以下のエラーメッセージが表示されるようです。

「The primary account cannot be removed unless it is the only account in the profile. You must remove all other Exchange accounts before removing the primary account account.」

「標準アカウント」というのは「primary account」に対応していることが分かります。
「primary」は「最初の」という意味があり、
Outlook最初に登録されたExchangeのアカウントを指します。

つまり、Exchangeのアカウントが二つ以上存在する場合、
最初に追加されたExchangeアカウントは、
他のExchangeアカウントを全て削除しない限り削除できない

というのが今回の問題の原因だと分かりました。

解決方法

上のエラーメッセージの意味に従うと、
他のExchangeのアカウントを全て削除することで、
元々削除したかったExchangeのアカウントが削除できます。

ところが、他のアカウントは利用中なので、
削除するのには抵抗があります。

Outlookのアカウントの一覧は「プロファイル」という形で管理されています。 そこで、今のプロファイルを残したまま、
新しいプロファイルに必要なアカウントだけを追加するのが良さそうです。

ということで、その手順を紹介します。

  1. コントロールパネルを開く
  2. 「ユーザーアカウント」→「メール」をクリック
  3. 「プロファイルの表示」をクリック
    f:id:u874072e:20200519100413p:plain:w300
    メール設定
  4. 「追加」をクリックして新しいプロファイルを作成する
    f:id:u874072e:20200519100542p:plain:w300
    プロファイルの一覧
  5. 画面に従って必要なアカウントを追加する
    f:id:u874072e:20200519100801p:plain:w300
    アカウントの追加
  6. 新しいプロファイルを「常に使用するプロファイル」に選択する
    f:id:u874072e:20200519101012p:plain:w300
    使用するプロファイルの設定
  7. 「OK」をクリックしてOutlookを再起動する

これで新しく作成されたプロファイルに追加されたアカウントのみが読み込まれます。
元に戻したい場合は、使用するプロファイルを最初のものに戻せばOKです。

まとめ

Outlookで削除できない「標準アカウント」を、
取り除く方法について紹介しました。

今回の教訓は、エラーメッセージの意味が分からない時には、
対応する英語版のエラーメッセージも調べてみると良いということですね。
翻訳の過程で「primary(最初の)」という情報が欠落していたのが、
トラブルシューティングを難しくしているように思いました。

プライバシーポリシー