質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

173閲覧

データのlist内から順にカウントしていき、同一データのまとまりとして取り出す方法

yohehe

総合スコア48

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/04/02 06:31

機械学習による連続データのクラス分類について勉強しております。
リスト内から順にカウントしていき、同一データをまとまったデータとして取り出す方法について考えているのですが、方法論が思いつかないため困っております。

python

1 2 3#modelのclass予測が以下だった場合 4#クラス分類0-5の6分類とすると以下のように予測クラスをリスト内に格納するとする。 5 6predicted_data=[0,0,0,0,1,0,2,2,2,2,3,2,4,4,4,4,2,1,4,5,5,5,5,2] 7 8#このpredicted_dataから以下のデータとして取り出したい 9#リスト内に格納されたデータから1つめから順々に認識させて、0,0,0,0,1,0を取り出し、1は予測の誤りであるとすると、それを除いたデータを抽出したい。以下のようなデータとして 10data1=[0,0,0,0,0] 11 12#同様に次は、2,2,2,2,3,2というまとまりを抽出して、3を取り除いたデータを取り出したい。 13 14data2=[2,2,2,2,2] 15#上記のようにデータを取り出したい。

上記のようなリストデータを取り出したい場合、なにかいい方法論はございますでしょうか。
n-gramのような手法で何個かに分けて取り出そうとも考えたのですが、方法論としていい方法が思いつかず困っております。何かアドバイスをいただけたら幸いです。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2019/04/02 07:53

> 0,0,0,0,1,0を取り出し、1は予測の誤りであるとすると どうして 0,0,0,0,1,0 を取り出したのか? どうして 1は予測の誤りであるとしたのか? を説明いただけるといいかと思います。
yohehe

2019/04/02 08:08 編集

quiqui様、ありがとうございます。 センサー習得からの動作認識に取り組んでおります。動作のような連続データを習得し続け、それをmodel.predict()でクラス分類していくとどうしても0,0,0,0,1,0のように大まかには0と習得したいデータリストが出力されています。 このような場合にKenji.Noguchi様が教えてくださったgroupbyのような手法で取り出して行く方法を導入することが学習モデルの後に取り入れる手法として正しいかはわかりませんが有用であると考えてはおります。 predictの類似度の出力を用いる方法もあるのかと調べたりしていますが、適切なやり方がみつからないでおります。このような連続したデータにおけるpredictの手法についてはなにかいい方法論がありますでしょうか。
yohehe

2019/04/02 08:12

"誤り"という言い方は間違いですね。誤りではなく、それらのpredictの予測データが混在したデータからデータのまとりまりとして捉えていきたいという言い方が正しいと思われます。失礼致しました。
quickquip

2019/04/02 08:18

つまり「予測した」データ列から「こうだったのだろう」列を作りたいのであって、「正解はわからない」状態と考えていいのでしょうか。 例えば、0,0,0,0,1,0 は [0, 0, 0, 0] [1, 1] の最後を間違えたとは「考えない理由」はなんでしょうか?
yohehe

2019/04/02 08:38

動作推定の分類手法が正しくないのかもしれないですが、秒単位で分類器などに入れるとどうしても大まかにこういう動作なんだろうというデータ出力がされています。ウインドウサイズのsecを小さくしていけばいくほど、その数が増えている状況でして。これは分類器の精度の問題であるといえばそうかもしれません。うまい例えばではないかもしれませんが、ランニングしている途中で少し歩いたり止まったりした部分があったとしても大まかにこの範囲は走っていると分類させたいということであります。大まかな動作が認識できれば動作の順序などを大きな範囲で取得できるのではないかと考えています。
quickquip

2019/04/02 08:41 編集

例えば 2,2,2,3,4,4の列に対して、好ましい正解なのか、[2,2,2,2] [4,4]が好ましいのか、[2,2,2][4,4,4]が好ましいのか、などはどうでしょうか? (最大長の最大を望むのか、長さの分散が小さいことを望むのか) # 行き違いました
yohehe

2019/04/02 08:53

動作が対象になっておりますので、動作の時間:長さが異なっておりますので長さはある程度の自由度があるほうがいいとは考えております。 なるほど、最大長の設定して、そのなかで分散表現、分布として大まかな類推をするということでしょうか。
guest

回答2

0

ベストアンサー

なにをもって「同一データのまとまり」と解釈するかが肝になるかと思います。
美しくないですが、とりあえず以下のコードを書いてみました。
混在する値が1つだけなら、それを除いて抽出します。
よって混在数が2つある 4,4,4,4,2,1,4 は 4,4,4,4,4 にはなりません。

Python

1lst=[0,0,0,0,1,0,2,2,2,2,3,2,4,4,4,4,2,1,4,5,5,5,5,2] 2 3cur_n = -1 # 抽出する数値 4pos_st = 0 # 抽出開始位置 5dif_cnt = 0 # 抽出中の異なる数値の数 6MAX_DIF = 1 # 混在を許す上限数 7 8i = 0 9while i < len(lst): 10 # 次の抽出する数値を決定 11 if cur_n < 0: 12 cur_n = lst[i] 13 dif_cnt = 0 14 pos_st = i 15 # 抽出中 16 else: 17 # 異なる数値が出現 18 if cur_n != lst[i]: 19 # 混在上限に達した→抽出終了 20 if dif_cnt >= MAX_DIF: 21 print([v for v in lst[pos_st:i] if v == cur_n]) # 同一値のみ 22 cur_n = -1 23 i -= 1 # 巻き戻し 24 # 異なる数値が出現 25 else: 26 dif_cnt += 1 27 i += 1 28 29# 末尾に取りこぼしがあればそれも抽出 30if cur_n > 0: 31 print([v for v in lst[pos_st:i] if v == cur_n]) 32 33""" 34[0, 0, 0, 0, 0] 35[2, 2, 2, 2, 2] 36[4, 4, 4, 4] 37[1] 38[5, 5, 5, 5] 39"""

投稿2019/04/02 08:22

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohehe

2019/04/03 10:59

業務により遅くなりすみません。 can110様、アドバイスありがとうございます。なるほど、同一のまとまりの定義をまずはある程度自分で定義する必要があるのですね、勉強になります。 教えていただきましたコードについて今から勉強してみます。
yohehe

2019/04/03 16:39 編集

can110様、ありがとうございます。こういった書き方でまとまりとしてとらえていく手法もあるのかと勉強になりました。
guest

0

直接の回答ではないかもしれませんが、itertools.groupbyが使えると思います。

Python3

1import itertools 2 3predicted_data=[0,0,0,0,1,0,2,2,2,2,3,2,4,4,4,4,2,1,4,5,5,5,5,2] 4 5for k, g in itertools.groupby(predicted_data): 6 print(k, list(g))

結果

0 [0, 0, 0, 0] 1 [1] 0 [0] 2 [2, 2, 2, 2] 3 [3] 2 [2] 4 [4, 4, 4, 4] 2 [2] 1 [1] 4 [4] 5 [5, 5, 5, 5] 2 [2]

長さが1のものは誤りとして除外するなら

import itertools predicted_data=[0,0,0,0,1,0,2,2,2,2,3,2,4,4,4,4,2,1,4,5,5,5,5,2] for k, g in itertools.groupby(predicted_data): l = list(g) if len(l) <= 1: continue print(k, l)

結果

0 [0, 0, 0, 0] 2 [2, 2, 2, 2] 4 [4, 4, 4, 4] 5 [5, 5, 5, 5]

投稿2019/04/02 06:55

Kenji.Noguchi

総合スコア358

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohehe

2019/04/02 07:06

Keni.Noguchi様、アドバイスありがとうございます。groupbyというライブラリについて調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問