テストエンジニアが機械学習してみた備忘録

広島とジト目が好きなテストエンジニアが機械学習に手を出した備忘録。

「アジャイルもテスト自動化も当たり前?! ~AIがテスト設計をする日が来るかも~」を読んで

気づけば今年もあと一ヶ月となり、気づけばブログ開設して1年が過ぎていました。機械学習を勉強しようと思って備忘録的に始めたブログですが、今年はライフイベントを色々と詰め込んでしまったため、更新が滞ってしまいました…今年度はバタバタが続きそうなので、来年度に入ったくらいからは…と思いつつはてさてどうなることやら。

さて、今日はシステムテスト自動化カンファレンス(STAC)でした。

testautomationresearch.connpass.com

機械学習を絡めたセッションが多いので、ソフトウェアテスト機械学習を取り入れられないかということで勉強始めたこともあり、是非参加したかったのですが、残念ながら補欠から繰り上がらなかったので断念*1しました。

ところでこれ、繰り上がったら絶対行こうと思ってたので「一般参加(絶対行く枠)」の補欠に入れたものの、キャンセル率高そうなのは「一般参加(キャンセルするかも枠)」なので、「一般参加(キャンセルするかも枠)」にした方が良かったのだろうか…でも「キャンセルするかも」じゃないしなぁ…っていうかそもそもこの区分けいるのだろうか…?

閑話休題

STACの話はハッシュタグや発表資料を追うとして、ちょうどソフトウェアテストのアドベントカレンダー*2にもタイムリーな話題が出ていました。

kokotatata.hatenablog.com

「ふむふむ、なるほどー」と思う部分もあり、話の大枠としては「うんうん、目指したいよね」と思う反面、ちょっともやっとしたところもありましたので、整理がてら久々に筆を取ってみようと思います。

なお、以下の内容は元記事の私なりの解釈と、拙いながらもこれまで経験したこと、学んだことベースで考えたことです。経験や知識が不足している点も多々あります*3ので、別の見方や解釈や知見のある方は是非ご指摘いただけますと幸いです。

*1:ちなみに、一般参加(絶対行く枠)の最後に入ってますが、何故か当日の13:40頃に繰り上がりました。さすがに既に始まってるし、関西から駆けつけるのは無理…せめて前日なら…

*2:今年は1と2と小ネタがあるみたいですね。2はまだ空きがあるので何か書いてみようかな…

*3:そもそも元記事を書いた方は、自分なんかよりはるかに実力も実績もある方ですしね。

続きを読む

SVMで多クラス分類

ちょっとプライベートやらなんやらでしばらく時間が取れなかったのですが、久々に触ったので備忘録。 最後に取り組んだのがSVMによる2クラスの分類だったみたいなのですが、ちょうど多クラス分類をやってみたくなることがあったので、復習がてら取り上げてみます。

処理の仕方

とは言え、処理内容自体は2クラス分類の場合と同様で、教師データの正解ラベルの種類を増やすだけで良いみたいです。例えば前回、Kaggleのタイタニックに取り組んだ際は、生存か死亡かの2クラスを0と1で表していましたが、仮に無傷、負傷、死亡の3クラスに分けるとしたら、それぞれ0、1、2に割り当てて正解ラベルを作ることになります。

ovrとovo

多クラス分類する場合は、ovr (one-vs-rest)かovo (one-vs-one)かを選択します。両者の違いは以下の記事にまとまっています。

qiita.com

scikit-learnのドキュメントでもovrが推奨されており、デフォルトはovrのようです。

classification_report

多クラス分類の結果は、sklearn.metricsのclassification_reportを用いると簡単に評価できます。この辺りの話は、私も以前整理していました。

gratk.hatenablog.jp

参考

Twitterのデータから読み解くJaSST'18 Tokyo

gratk.hatenablog.jp

前回の記事で触れたように、今回のJaSSTはTwitterで #jasst のハッシュタグを追いかけるだけのエア参加でした。 せっかくなのでツイートの内容を分析してみようと思います。

続きを読む

Google先生の基調講演の噂を聞いて (JaSST'18 Tokyo エア参加)

3/7と3/8はJaSST Tokyoが開催されます。

JaSSTソフトウェアテストシンポジウム-JaSST'18 Tokyo

JaSSTは自分がソフトウェアテストの道を志すきっかけになったと言ってもよいイベントで、 数年前までは毎年参加していましたが、今年はチーム内の別の方が参加するということで参加を見送りました。 正直、基調講演がGoogleなので是非聞いて見たい感はあったのですが。

で、昼休みになんとなくTwitter眺めていると…

なんかめっちゃ楽しそうなことになってる

続きを読む

KaggleのタイタニックでSVMの練習

前回はKaggleのタイタニックをランダムフォレストでやってみて、下から数えたほうが早いくらいの成果しか出ませんでした。今回はSVMsupport vector machine)を試してみたいと思います。

続きを読む

Kaggleのタイタニックでランダムフォレストの練習

何番線じかわかりませんが。

バグやリファクタリングと戦いつつなんとかシストレを稼働にまで持って行けたので、機械学習の勉強を再開するということでKaggleに登録してみました。

Kaggleについてとか、サイト内の案内とか、タイにタックってなんやねんとかは以下のような良記事があるので、分析部分の備忘録。

続きを読む

仮想通貨とごまだれ

今年に入ってZaifで口座を開き、退職した同期がTwitterで「NEMはいいぞ(意訳)」と言っていたのを聞き、NEMを買おうと思っていた矢先に例の事件で価格が下がったので、これ幸いと仮想通貨に参入したのがつい最近のお話です。BTCでのマイニングにあたる行為がNEMではハーベスティングと言うそうなのですが、これは「NEMを使う人ほど報酬を得やすい」という仕組みのようなので、長期保有ハーベスティングしつつ、そのうちNEM使って経済活動できたらなー、とか思ってます。コーヒーも買えるとこあるし。在庫復活はよ。

で、仮想通貨の取引所は、株の証券口座に比べるとAPIが充実してなんだか楽しそうな気がします。 例えばZaifhttps://api.zaif.jp/api/1/last_price/xem_jpyにアクセスするだけで、その時点でのNEMの価格が取得できます。他の仮想通貨もしかり。

qiita.com

例えばここを参考に音を鳴らすようにすれば、閾値を超えた時に音を鳴らして知らせるといったこともできます。

と、いうわけで1円単位で価格があがるとゼルダの「ごまだれ〜」が鳴るようなスクリプト作って遊んでました。*1 下がったときはなんか残念なSEにしたかったのですが、思いつかなかったのとめんどくさかったのとでとりあえずゼルダの子守唄で。

import math
import requests
from time import sleep

import matplotlib.pyplot as plt
from synthesizer import Player, Synthesizer, Waveform


last_prices = []
alert = {'upr': 0, 'lwr': 100000}
sleep_time = 120

# オーディオデバイス出力用クラス
player = Player()
player.open_stream()
synth = Synthesizer(osc1_waveform=Waveform.sine, osc1_volume=1.0, use_osc2=False)

def gomadare():
    player.play_wave(synth.generate_constant_wave(440.0, 0.2))
    sleep(0.2)
    player.play_wave(synth.generate_constant_wave(466.164, 0.2))
    sleep(0.2)
    player.play_wave(synth.generate_constant_wave(493.883, 0.2))
    sleep(0.2)
    player.play_wave(synth.generate_constant_wave(523.251, 0.5))

def zelda():
    player.play_wave(synth.generate_constant_wave(493.883, 0.6))
    sleep(0.6)
    player.play_wave(synth.generate_constant_wave(587.330, 0.3))
    sleep(0.3)
    player.play_wave(synth.generate_constant_wave(440.0, 0.9))

try:
    while True:
        response = requests.get("https://api.zaif.jp/api/1/last_price/xem_jpy")
        last_price = response.json()['last_price']
        print(last_price)
        last_prices.append(last_price)

        if last_price > alert['upr']:
            gomadare()
            plt.plot(last_prices)
            alert['upr'] = math.ceil(last_price)
            alert['lwr'] = math.floor(last_price)
            print(f"upr: {alert['upr']}, lwr: {alert['lwr']}")
        elif last_price < alert['lwr']:
            zelda()
            alert['upr'] = math.ceil(last_price)
            alert['lwr'] = math.floor(last_price)
            plt.plot(last_prices)
        sleep(sleep_time)
finally:
    plt.plot(last_prices)

高速で回すとサーバに負荷かけちゃうのでご注意を…(上記スクリプトでは2分に1回の確認にとどめています)

*1:以外と「ごまだれ〜」ってなんやねんという人が多いのですが、ぐぐれば出るのでご存じない方は是非