https://github.com/apple/turicreate
Appleが先日公開した機械学習のライブラリです。
READMEをみると…
1 2
| You don't have to be a machine learning expert to add recommendations, object detection, image classification, image similarity or activity classification to your app.
|
機械学習のエキスパートでなくても、リコメンドシステムなどが作れる…ほう(・ω・)
僕は、エキスパートではないので、僕でも本当に作れるか試してみます(`・ω・´)
ということで、この2つを作ってみます!
- Recommender systems(リコメンド)
- Image classification(画像分類)
導入
まずはじめにTuri Createをインストールします。
以下のようにすると、入れることができます。
※Python 2.7, 3.5, 3.6推奨
1
| pip install -U turicreate
|
最初は、映画のリコメンドシステムです(`・ω・´)
ユーザーさんが見た映画の履歴を元に、
次、この映画を見たほうがいいよと教えてくれるリコメンドシステムを作ります。
訓練データ
訓練データには、こちらのCSV形式(190MB)のデータを使います。
https://grouplens.org/datasets/movielens/

CSVのデータの中身は、こんな感じです。

CSVの読み込み
先ほどのCSVデータを読み込みます。
1 2 3
| import turicreate as tc data = tc.SFrame.read_csv('data.csv') data.explore()
|
読み込みますと、こんな感じに表示されます。
ちなみに、この表示機能はTuri Createに標準でついている機能です。

先ほどのコードにSFrame
という見慣れないものがあると思います。
https://github.com/turi-code/SFrame
こちらは、データ分析用に作られたスケーラブルなデータ構造らしいです。
また、SQLのフィルタ, ソート, ジョインなどのようなことができます!
学習
先ほどのデータを使って、学習させます。
1 2 3 4
| training_data, validation_data = tc.recommender.util.random_split_by_user(data, 'userId', 'movieId') model = tc.recommender.create(training_data, 'userId', 'movieId')
|
結果は、こんな感じになり、無事に学習ができました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Recsys training: model = item_similarity Warning: Ignoring columns rating, timestamp; To use one of these as a target column, set target = <column_name> and use a method that allows the use of a target. Preparing data set. Data has 80004 observations with 671 users and 8393 items. Data prepared in: 0.06855s Training model from provided data. Gathering per-item and per-user statistics. +--------------------------------+------------+ | Elapsed Time (Item Statistics) | % Complete | +--------------------------------+------------+ | 14.361ms | 100 | +--------------------------------+------------+ Setting up lookup tables. Processing data in one pass using dense lookup tables. +-------------------------------------+------------------+-----------------+ | Elapsed Time (Constructing Lookups) | Total % Complete | Items Processed | +-------------------------------------+------------------+-----------------+ | 228.774ms | 0 | 0 | | 547.001ms | 100 | 8393 | +-------------------------------------+------------------+-----------------+ Finalizing lookup tables. Generating candidate set for working with new users. Finished training in 1.56964s
|
検証
先ほどの学習したものの検証を行います。
1 2 3
| res = model.evaluate(validation_data) pro = res['precision_recall_overall'] pro.print_rows(18,3)
|
結果は、こんな感じです(`・ω・´)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| +--------+-----------------+------------------+ | cutoff | precision | recall | +--------+-----------------+------------------+ | 1 | 0.0746268656716 | 0.00222957408534 | | 2 | 0.0910447761194 | 0.00849339445401 | | 3 | 0.0980099502488 | 0.0140232349614 | | 4 | 0.10223880597 | 0.0197251532314 | | 5 | 0.102985074627 | 0.024713370957 | | 6 | 0.113432835821 | 0.0343338830723 | | 7 | 0.119829424307 | 0.0423068785092 | | 8 | 0.122388059701 | 0.0506102259718 | | 9 | 0.122885572139 | 0.0571544479215 | | 10 | 0.122388059701 | 0.0629408159497 | | 11 | 0.121031207598 | 0.0676575352222 | | 16 | 0.120335820896 | 0.0941542231187 | | 21 | 0.122885572139 | 0.126040641884 | | 26 | 0.127095292767 | 0.160259557501 | | 31 | 0.128069330766 | 0.190365739974 | | 36 | 0.128855721393 | 0.218778795533 | | 41 | 0.128940662541 | 0.256367765626 | | 46 | 0.131440622972 | 0.297542272455 | +--------+-----------------+------------------+
|

モデルの保存
学習と検証が終わったので、モデルを保存します。
1
| model.save('recommend.model')
|
リコメンドさせてみる
先ほど作ったモデルを使いリコメンドさせてみます!
はじめに、先ほどのモデルを読み込みます。
1
| model = tc.load_model('recommend.model')
|
そして、ユーザーID「3」の人が映画ID「1」を見たという感じでやっていきます。
(ユーザーID「15」, 「128」も同様)
1 2 3 4 5
| data = tc.SFrame({ 'userId': [3,15,128], 'movieId': [1,6,111] }) print(data.join(movie, on='movieId'))
|
1 2 3 4 5 6 7
| +---------+--------+--------------------+-------------------------------+ | movieId | userId | title | genres | +---------+--------+--------------------+-------------------------------+ | 1 | 3 | Toy Story (1995) | Adventure|Animation|Childr... | | 6 | 15 | Heat (1995) | Action|Crime|Thriller | | 111 | 128 | Taxi Driver (1976) | Crime|Drama|Thriller | +---------+--------+--------------------+-------------------------------+
|
では、リコメンドさせます(`・ω・´)
1 2
| res = model.recommend([3, 15, 128], new_observation_data=data) print(res.join(movie, on='movieId').sort('rank'))
|
結果
1 2 3 4 5 6 7 8 9 10 11 12 13
| +--------+---------+-----------------+------+-------------------------------+-------------------------------+ | userId | movieId | score | rank | title | genres | +--------+---------+-----------------+------+-------------------------------+-------------------------------+ | 3 | 2571 | 0.140675894239 | 1 | Matrix, The (1999) | Action|Sci-Fi|Thriller | | 3 | 4993 | 0.128428682685 | 2 | Lord of the Rings: The Fel... | Adventure|Fantasy | | 3 | 4963 | 0.120257125659 | 3 | Ocean's Eleven (2001) | Crime|Thriller | | 15 | 1580 | 0.0189388030345 | 1 | Men in Black (a.k.a. MIB) ... | Action|Comedy|Sci-Fi | | 15 | 103042 | 0.0183990796982 | 2 | Man of Steel (2013) | Action|Adventure|Fantasy|S... | | 15 | 1923 | 0.0179402843312 | 3 | There's Something About Ma... | Comedy|Romance | | 128 | 2797 | 0.0362989620521 | 1 | Big (1988) | Comedy|Drama|Fantasy|Romance | | 128 | 1517 | 0.0334305414787 | 2 | Austin Powers: Internation... | Action|Adventure|Comedy | | 128 | 1097 | 0.0305381224706 | 3 | E.T. the Extra-Terrestrial... | Children|Drama|Sci-Fi | +--------+---------+-----------------+------+-------------------------------+-------------------------------+
|
- ユーザーID「3」の人は、「Matrix」がおすすめされました。
- ユーザーID「15」の人は、「Men in Black」がおすすめされました。
- ユーザーID「128」の人は、「Big」がおすすめされました。
それっぽいものができたぞ(`・ω・´)
次は、犬の画像分類を作ってみます(`・ω・´)
Core MLにエクスポートしてiPhoneのカメラで犬の写真を写して、
その犬の犬種を表示するというアプリを作ります。
訓練データ
こちらのデータを使いました。
http://vision.stanford.edu/aditya86/ImageNetDogs/

モデルの読み込み
先ほどの犬の画像を読み込みます。
今回は「Border_terrier」,「cairn」,「Shih-Tzu」の3種類を判定するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import turicreate as tc def path2label(path): if "Border_terrier" in path: return "Border_terrier" elif "cairn" in path: return "cairn" elif "Shih-Tzu" in path: return "Shih-Tzu" else: return "unknown" def gen_sframe(): data = tc.image_analysis.load_images('/dog', with_path=True) data['label'] = data['path'].apply(path2label) data.save('train.sframe') data.explore() gen_sframe()
|
読み込みますと、こんな感じに表示されます。

学習
では、読み込んだデータをもとに学習させます!
1 2 3 4 5 6 7 8 9 10 11 12
| import turicreate as tc data = tc.SFrame('train.sframe') train_data, test_data = data.random_split(0.8) model = tc.image_classifier.create(train_data, target='label', max_iterations=100) metrics = model.evaluate(test_data) print(metrics['accuracy']) model.save('dogs.model') model.export_coreml('dogs.mlmodel')
|
結果は、こんな感じになりました!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| // 一部省略 -------------------------------------------------------- Number of examples : 557 Number of classes : 4 Number of feature columns : 1 Number of unpacked features : 2048 Number of coefficients : 6147 Starting L-BFGS -------------------------------------------------------- +-----------+----------+-----------+--------------+-------------------+---------------------+ | Iteration | Passes | Step size | Elapsed Time | Training-accuracy | Validation-accuracy | +-----------+----------+-----------+--------------+-------------------+---------------------+ | 1 | 4 | 0.000898 | 1.107175 | 0.786355 | 0.960000 | | 2 | 7 | 0.500000 | 1.213239 | 0.885099 | 0.840000 | | 3 | 8 | 0.500000 | 1.269205 | 0.919210 | 1.000000 | | 4 | 9 | 0.500000 | 1.332011 | 0.951526 | 1.000000 | | 5 | 10 | 0.500000 | 1.391532 | 0.971275 | 1.000000 | | 6 | 11 | 0.500000 | 1.458173 | 0.978456 | 1.000000 | | 11 | 16 | 0.500000 | 1.741182 | 0.996409 | 1.000000 | | 25 | 30 | 0.500000 | 2.535394 | 1.000000 | 1.000000 | +-----------+----------+-----------+--------------+-------------------+---------------------+ SUCCESS: Optimal solution found.
|
補足
先ほどのコードでは転移学習を使います。
なので、最初に転移学習用のデータのダウンロードに時間がかかります。
Core MLにエクスポート
学習が完了したので、Core MLに書き出します!
1
| model.export_coreml('recommend.mlmodel')
|

Xcodeに入れる
書き出したモデルをXcodeにいれます。

結果
で、こんな感じになりました!

それっぽいものができたぞ(`・ω・´)
が…訓練データが少ないのか反応がイマイチ…
まとめ
- 数行〜数10行で作ることができる。(とっつきやすい)
- これから機械学習を始める人には良いかも。
- 本番でも耐えれるかは未検証なので、不安は残る。
- 今後に期待(`・ω・´)
コードはGitHubで公開しています!
https://github.com/gupuru/turi-create-playground
ありがとうございました(`・ω・´)