スプライン関数を使ってデータ数を揃える方法

このQ&Aのポイント
  • matlab初心者の方が、データ数が異なる2つのデータ群をスプライン関数を使って揃える方法について質問しています。データ数の揃え方によって、後の検定をスムーズに行うことができます。
  • 例えば、AとBという2つの条件で5秒ごとの心拍を測定する場合、データ数が異なっていることがあります。この場合、スプライン関数を使ってデータ数を揃えることができます。
  • 具体的には、データ数の多い方のデータを補完することでデータ数を揃えることができます。プログラムを組む際には、matlabのスプライン関数を使用することで簡単に実現することができます。
回答を見る
  • ベストアンサー

スプライン関数(spline)について

スプライン関数(spline)について matlab初心者です。 データ数が異なる2つのデータ群があり、その個数を揃えるために matlabのスプライン関数を使って揃えてみては、とアドバイスをいただいたのですが どのように行えばよいか分かりません。 個数を揃えたい理由は、その後の検定をスムーズに行いたいためです。 (SPSSを使うのでデータ数が揃っている必要があるようです。) 例えば、A,Bという2つの条件で5秒ごとの心拍を測定するとして、 A[80,82,84,86,82,84,93,94,84,87](データ数が10個) B[76,83,86,90,94,95,93,87,86,89,93,79,90](データ数が13個) となり、Bの13個のデータを10個に揃えるにはどのような プログラムを組めばよいのでしょうか。 ご存知の方がいらっしゃいましたら、ご教授宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • Kules
  • ベストアンサー率47% (292/619)
回答No.5

Kules Part5です。 >Kulesさんに添付していただいたグラフのように曲線になっておらず >点と点の間が直線になっていました。 >そこでツール→基本的な近似→スプライン補間とすると >曲線になり、補間したグラフに元データがのっていました。 >使用しているmatlabはR2010aですが >このような方法であっていますでしょうか? というかそもそも前回黒線をどうやって描いていたのかって話になるんですが…。 元のデータ(青丸)を直線で結んでも補間データ(赤丸)を直線で結んでも黒線はできません。 黒線は全く別の方法で引いています(A No.3にも書いていますが) >そこでツール→基本的な近似→スプライン補間とすると >曲線になり、補間したグラフに元データがのっていました。 ということは添付図で言うところの赤丸に対してツールからスプライン補間を選択したんでしょうか? ん~まあそれでも思ったものは出ると思います。問題ないんじゃないかと。 ただ私の黒線は別の方法で描いています。 参考になれば幸いです。

apple0917
質問者

お礼

複数にわたるご回答ありがとうございました。 大変貴重なご意見でした。 最後の件に関しましては、 私の勘違いもあり、解決しました。 お騒がせしました。 また何かありましたら宜しくお願い致します。 ありがとうございました。

その他の回答 (4)

  • Kules
  • ベストアンサー率47% (292/619)
回答No.4

Kules Part4です。 >どういった補間が今回の場合、適しているのかはなんとも判断しずらい状況です。 これは…私にもどうしようもないです(笑)私自身SPSSの何たるかも全く知りません。 ここに関しては私以外の人が答えた方がよいでしょう。 >実際のデータで私が行うとわずかですが線にのらないものもありました。 これはいくつか理由が考えられます。 (1)黒線の分解能が足りていない (2)縦軸(x方向)の設定が間違えている (1)の場合は確認は簡単です。黒線ではなく黒点で描けば、赤丸が黒点のいないところにあるのがわかると思います。 (2)の場合はちょっと難しいですね…スクリプトの全部を見ても理由がわかる自信はありません。 ただ、補足を見る限りはlinspaceの使い方や:を使った等差数列の作り方に若干の不安が残るので、 その辺りを確認する必要があるかも。 ただ、私が添付したグラフも本当に載っている保証はありません。spline関数の内挿がどの程度の精度を持っているのかもわかりませんし。 添付のグラフでちょっとずれてるかも…ぐらいのレベルではなく明らかにわかるぐらいずれているんでしょうか?その辺り補足願います。 参考になれば幸いです。

apple0917
質問者

補足

たびたびご返答ありがとうございます。 いろいろ検討してみましたが どうやらグラフの描き方に問題があったようです。 Kulesさんに添付していただいたグラフのように曲線になっておらず 点と点の間が直線になっていました。 そこでツール→基本的な近似→スプライン補間とすると 曲線になり、補間したグラフに元データがのっていました。 使用しているmatlabはR2010aですが このような方法であっていますでしょうか? 基本的なことをすみません。

  • Kules
  • ベストアンサー率47% (292/619)
回答No.3

三度Kulesです。 とりあえず謝罪と訂正です。 size(B)は最低2要素のベクトルを出力すると言いましたが、 :を使ったベクトルの生成などに使った時は1つ目の要素のみ出力するみたいです。 従って、13行1列のベクトルの場合は13を出力しますし、1行13列のベクトルの場合は1を出力します。また、関数を使って行列を生成する時、例えばlinspace(1,10,size(B))とする時にはエラーが出ます。 やはりsizeというと(縦、横)と2要素以上持っているイメージになりやすいので、ベクトルの長さを出力するlengthや、行列の要素の数を出力するnumelを使った方が、イメージに即したものになるんじゃないかなあ…と思います。別に直さなくてもいいんですけどね。 また、蛇足ではありますがアドバイスです。質問者様のベクトル表記が A=[80,82,…,87]; となっていたため私は横ベクトルと解釈し、それを解消するため補足で改行を用いて縦ベクトルを表現して下さったのだとは思いますが、 縦ベクトルを表現したければ A=[80;82;…;87]; のように;(セミコロン)を使っていただければMatlabやっている人間には通じますので。 改行使うと文章が縦に伸びてわかりにくいですしね。 本題に入ります。 まずspline関数についてですが、これは3次スプライン内挿という操作をしています。 3次スプラインとは、ざっくり言ってしまうと「元となる配列において、各々2点を結ぶ3次関数を考える。各境目において、滑らかに接続するよう係数を決める」 ということです。 例えば元のx軸方向の配列が[1,2,4,5,8]だとすると、 ・1~2の間 ・2~4の間 ・4~5の間 ・5~8の間 をそれぞれ3次関数でつなげます。そして、全ての節点(今回でいうと1,2,4,5,8)で各区間の3次関数が滑らかにつながるようにします。 具体的には、1~2の間での3次関数におけるx=2での1次微分係数と、2~4の間を表わす3次関数におけるx=2での1次微分係数 が一致するようにします。同様に2次微分係数も一致するように係数を決めます。 このように書くと非常に複雑なことをしているように見えますが、実際は簡単な行列の積で求まるようです。 次に質問者様が書かれている手法についての是非ですが、結論から言うと 「スプライン内挿としては正しいが、意図しているものが出ているとは限らない」 ということになります。 添付図をご覧ください(正しく添付されるかな?) 青丸が元のデータ(13個あります) 黒線が0.01刻みでスプライン補間したデータ 赤丸がxxでスプライン補間したデータですが、 上の図はxx=1:size(B)/10:size(B); 下の図はxx=linspace(1,length(B),10)です。 両者とも、赤丸は黒線にのっていることから正しく補間されていることはわかりますが、 赤丸がいる位置は違います。 ここから先はどちらの形のデータが欲しいか、ということだと思います。 上の場合は10個目のデータと元の13個目のデータは一致しない形、 下の場合は一致する形になります。 これ以外のデータの取り方が必要であれば、そのようにxxを設定すれば済む話です。 どのような形の補間データが欲しいのでしょうか? 参考になれば幸いです。

apple0917
質問者

補足

再三のご回答ありがとうございます。 図まで添付していただいて大変感謝しております。 今回、このようなことをしているのはSPSSで条件間に有意差があるのか ということを検定するためです。 しかし、データ数が異なると検定はできるのですが例でいうBの最後3つの データが全く無視されて、Bの10個までのデータとAとで検定するような仕様になっています。 そういったことを回避するためにデータ数を揃えようという発想が出てきたのですが どういった補間が今回の場合、適しているのかはなんとも判断しずらい状況です。 また、回答者様の添付図ですと赤丸がすべて黒線にのっていたのですが 実際のデータで私が行うとわずかですが線にのらないものもありました。 これはデータ数が多いために起こる現象なのでしょうか? (データ数は120ほどで、 plot(x,y,'o',xx,yy) と入力しております。) もしくはなにか手違いが生じているのでしょうか? たびたび申し訳ないです。

  • Kules
  • ベストアンサー率47% (292/619)
回答No.2

再びKulesです。 x=1:size(B); y=B; xx=1:size(B)/10:size(B); yy=spline(x,y,xx); と教わりました。 う~んこの書き方で動いたんでしょうか?私の感覚からすると間違いなくエラーになるんですが(苦笑) まず、sizeという関数は入力変数が1つの場合最低2つの値を持つベクトルを出力します。 今回の場合Bはデータ数が13個の横ベクトルですので、 m=size(B) とした場合n=[1,13] となると思うのですが。:での等間隔のベクトルを作る時の一要素に使われる時はデフォルトでスカラー量を返してくれるんでしょうか? ちなみにこれでエラーが出る場合は、size(B)ではなくnumel(B)かlength(B)を使えば解決すると思います。 xx=1:size(B)/10:size(B); も相当怪しいですね。これだと等間隔のベクトルができないのでは?size(B)が13のことでれば、 xxの増分size(B)/10は1.3です。ということはxxをそのまま書くと xx=[1,2.3,3.6,4.9,6.2,7.5,8.8,10.1,11.4,12.7,13] となり、最後の2つの間隔が明らかに狭いですね。これは最初が1からスタートしていることが原因です。 そういう意味では最初を1ではなくsize(B)/10にすればよいと思います。あるいは xx=(1:10)/10*length(B);とか。 また、こうしたとしても10個のデータと時系列を合わせられるかというとそんなことはありません。 ただ、今回はどうやらデータの個数を合わせることのみが目的のようですので、それでもよさそうですね。 参考になれば幸いです。

apple0917
質問者

補足

たびたびのご回答ありがとうございます。 説明不足だったのですがBは13×1で B=[76 83 86 90 94 95 93 87 86 89 93 79 90]; と入力しました。 help splineで例として表示されたものと同様に x=1:size(B); y=B; xx=1:size(B)/10:size(B); yy=spline(x,y,xx); というプログラムを入力してエラーなく結果が出力されたのですが splineについて無知なため、どういう原理で計算されていて このプログラムが今回の場合、正しいのか正しくないのかも理解しきれていません。 なにかアドバイス等ありましたら宜しくお願いしたいです。

  • Kules
  • ベストアンサー率47% (292/619)
回答No.1

データの数を揃えるためにスプライン関数を使うんですか? 確認なのですが、Aという条件もBという条件も5秒ごとのデータなんですよね? 私自身の知識も曖昧なのですが、もともとスプライン関数というのは補間をするためのものなので、 データの取得間隔をもっと狭くする(つまり、5秒ごとのデータから1秒ごとのデータを作り出す)時には 有効ですが、今回のように13個のデータを10個に揃えるといった使い方には使えないと思います。 もし仮に、10個のデータは5秒ごとで0秒~45秒、13個のデータも45/12秒ごとで0秒~45秒なんだけど、 13個のデータから5秒ごとのデータを作りたい、ということであれば、 Aの波形をBeatA、Bの波形をBeatBとして、 TimeA=linspace(0,45,10); TimeB=linspace(0,45,13); BeatB1=interp1(TimeB,BeatB,TimeA,'spline'); でBの波形から5秒ごとのデータを作ることができます。 「こういうことではないんだよ」とか「こういうことなんだけど、うまくいかないんだよ」とかありましたらその旨補足願います。 参考になれば幸いです。

apple0917
質問者

補足

ご回答ありがとうございます。 先生にきいてみたところ、 x=1:size(B); y=B; xx=1:size(B)/10:size(B); yy=spline(x,y,xx); と教わりました。 これでデータの個数は揃えることができました。 ちなみにどこかおかしな点はありますか?

関連するQ&A

  • 分散分析について

    分散分析について 現在実験を終えて、解析作業をしている大学4年の者です。 検定したいことは、4つの条件間である試行を行ったときの心拍数を測定し、 その心拍数に関して有意差があるのかということです。 問題になっているのが各条件間で心拍数のデータ数が異なるということです。 SPSSを用いて検定をしているのですがソフトの仕様上(?)、データが少ない方に 揃えられて検定されてしまうため、多い方の差分は全く無視されてしまいます。 (例:Aという条件のデータ数が30個でBという条件のデータ数が40個の場合、 30個にあわせられて、Bの10個のデータは無視されているような状況) 全体に対して、わずかなデータ数の差なのであまり気にしなくてもよいという話 なのですが気になる場合はmatlabのspline関数を用いて 多い方のデータを少ない方のデータにあわせて検定してみては、といわれました。 実際にそのようなことは可能なのですが、果たしてこのような手法は正しいのでしょうか? 正しくない場合、どのような手法を用いればよいのでしょうか? なにか詳しいことをご存知の方がいらっしゃいましたら、ぜひご教授お願い致します。 よろしくお願いします。

  • MATLABでの3次spline補間に関して

    MATLABでの3次spline補間、その端点仮定条件として使用されている「節点なしの拘束条件」について教えてください。 通常、3次スプライン補間は端点において二次導関数を0と仮定すると思います。 しかし、MATLABの3次スプライン補間の結果をみると、この部分のスプライン関数の係数が0になっていません。 サイトの説明を読むと、「節点なしの端点条件(not-a-knot end conditions)」を使用していると書かれています。これがどのような仮定かということを知りたいです。 ご存じの方がいらっしゃいましたら、ご教授宜しくお願い致します。

  • 検定方法に間違いがありますか?

    ある医療系(心理学系)の研究をすることになりました。 2つ悩みがあります。 1つは、統計解析ソフトSPSSを使用するのですが、データを入力する際はエクセルで行うべきでしょうか?? 勘違いかもしれませんが、エクセルにできてSPSSではやれない関数(SNMIF関数など)がたくさんあると思っているからです。 ・・・この認識に間違いはあるでしょうか???? もし、間違っていたらエクセルに入れる膨大なデータをSPSSにコピーする作業が非効率的な作業になりますので。。。。 どうでしょうか? アドバイスお願いします。 二つ目は、検定方法についてです。 ある独立したA群、非A群があるのですが、仮説としてA群になった要因は非A群より「Bという要素」と「Cという要素」が多いためである。としています。 それを検証するには、私は、2群の母比率の差の検定を2組行うことだと思っています。 つまり、「A群、非A群の人数とそれぞれのBという要素の人数」で1組として母比率の差の検定を行い、次に、、「A群、非A群の人数とそれぞれのcという要素の人数」で母比率の差の検定を行うように考えています。 ・・・これは禁忌でしょうか??? 例えば、独立した3群(A,B,C)などは、2群の平均値の差の検定を(AB)(BC)(CA)と3組に分けてt検定がきないように、 今回の私の検定も2組にわけることはできないのでしょうか? できない場合は、どのような検定方法があるのでしょうか??? どうかよろしくお願いします。

  • 罰則付き回帰スプライン?について

    スプラインを用いた回帰には,私が知る限り以下の3種類あるようです。 (1)回帰スプライン:全データ点を通るスプライン。残差平方和を最小にするように求める。 (2)平滑化スプライン:罰則によって滑らかにしたスプライン。データ点と節点の数が一致する。 (3)Penalized Regression Spline:(2)より節点数の少ないスプライン。 そのうちPenalized Regression Splineは,統計パッケージでよく使われているのですが(例えばRのmgcvライブラリのgam関数),求めるためのアルゴリズムがよく分からないため,詳しく調べてみたいと思っています。ところが,邦訳が見当たりません。 直訳すると「罰則付き回帰スプライン」になるのでしょうが,Googleで1件もヒットしません。 もし,何か情報をお持ちの方がいらっしゃいましたら,教えて頂ければ幸いです。

  • SPSS

    SPSSで何で調べたらいいのかわからないので教えてください。 あるやり方をしてポイントカードの加入数を調べました。まぁそれはいいのですが・・・。 A群が20件中16件、B群は20件中10件、C群は20件中15件、D群は20件中7件でした。 これをSPSSを使って調べるなら、何の検定がいいのですか? そして、結果はどうなりますか?

  • 対応のないt検定について

    心理学をやってます。 対応のないt検定についてです。 PCに関する知識が乏しいので手計算でやろうとしてます。 条件が違う2群で7人(8人)の参加者に15試行テストをしました。 2群間のt検定をしたいのですが、 1群 参加者A(データの個数-平均)の二乗+… 参加者B(データの個数-平均)の二乗+… 2群 参加者A(データの個数-平均)の二乗+… 参加者B(データの個数-平均)の二乗+… の先がいまいちわかりません。 また、間違えている可能性もあります… どうかご指導お願いします。

  • 3次スプライン補間法について

    x=3,7,4,7,5,8,3,2,3 (秒) Y=4,7,2,3,12,6,13,5,1,24 (cm) として、 速さa(cm/秒)はa=Y/xで出てくるのですが(a=1.7,1,0.5・・・)、 それぞれの点を結ぶと折れ線グラフになりますよね? 3次スプラインという補間関数を使うと、 それぞれの点を通過する滑らかな曲線を引けるらしいのですが、 この場合、x秒における速さaを求める計算式はどのようになるのでしょうか? a=? ご存知の方いらっしゃいましたらご教授・アドバイスよろしくお願い致します。

  • Excel 2007の関数

    条件付きデータの個数集計がわかりません。地域、新しい顧客(Y/N)のデータから新しい顧客数を数えたいのですが、条件が二つあるのでCountifが使えません。 地域   新しい顧客 A市     Y B市     Y A市     Y A市     N 上のデータから求めたい個数集計は、地域別の新顧客数です。 A市 2 B市 1 このようになるには、どのような関数を使えばよいのでしょうか。教えてください。

  • SPSSでのMann Whitney検定

    SPSSの使用について質問です。 2群の対応のない変数に対して、ノンパラメトリック検定を行いたいのですが、SPSSでMann Whitney 検定を指定しても、”計算できません”となってしまいます。 データ数は22と12です。 データに基づいて自動的に検定を選択する、というふうにすると、Kruskal Wallisの検定が選択されて、それでは計算結果が出てきます。 SPSSのバージョンは19.0です。 なぜでしょうか? お分かりの方、ぜひご意見をお願いします。

  • エクセルの関数 COUNTA

    COUNTA関数で空白以外のデータの個数を数えて、その中から○○という文字列になっているものを引いた数を表示するには? 例えば 「A型 B型 B型 O型 空欄 AB型 A型 空欄 AB型 O型」 という10個のデータでCOUNTAを使うと8 になります。そこからさらにA型も除いて、6と表示したいというようなケースです よろしくお願いします