2011-07-26 4 views
6

Oracle 11には、varchar2フィールドの値の相関をチェックする組み込みの方法がありますか?このような単純なテーブル所与例えば:varchar値の相関

MEAL_NUM INGREDIENT 
-------------------- 
1   BEEF 
1   CHEESE 
1   PASTA 
2   CHEESE 
2   PASTA 
2   FISH 
3   CHEESE 
3   CHICKEN 

IはMEAL_NUMに基づく数値指標を取得したい、チーズをほとんどPASTAと、牛肉、鶏肉、およびFISHを用いて度を軽減する対になっています。

私の最初の傾向は、CORR関数を使用して、あらかじめ列挙したり、一意の選択肢からrownumを取得したりして、文字列を数値に変換することです。

これについてのご提案はありますか?

答えて

0

このようなクエリはどうですか?

select t1.INGREDIENT, count(*)a 
from table t1, 
    (select meal_num 
     from table 
     where INGREDIENT = 'CHEESE') t2 
where t1.INGREDIENT <> 'CHEESE' 
and t1.meal_num=t2.mealnum 
group by t1.INGREDIENT; 

結果は、各成分がCHEESEとmeal_numを共有する回数である必要があります。

3

「食品番号」を作成してBeef = 1、Chicken = 2、Pasta = 3を割り当てた場合、相関係数によって増加したチーズと相関するかどうかがわかります。CORR "食べ物番号"しかし、「食べ物の数」が高いか低いかは、あなたがそれを作ってから何も意味しません。したがって、あなたの食べ物が何らかの形で実際に注文されていない限り、数字はCORRを使用しないでください。

統計学者がこれについて話す方法は、levels of measurementです。リンクされた記事の言語では、MEAL_NUMは名目上の尺度です。食事が順序どおりに行われた場合は尺度になりますが、いずれにしても、相関係数を使用することは本当に悪い考えです。

代わりに、「何%の牛肉の食事にもチーズが含まれていますか?以下は、各成分について、それを含む食事の数とそれを含む食事の数とチーズを返します。そのトリックは、COUNTはヌル以外の値しかカウントしないということです。

SELECT Other.Ingredient, 
     COUNT(*) AS TotalMeals, 
     COUNT(Cheese.Ingredient) AS CheesyMeals 
    FROM table Other 
LEFT JOIN table Cheese 
     ON (Cheese.Ingredient = 'Cheese' 
     AND Cheese.Meal_Num = Other.Meal_Num) 
GROUP BY Other.Ingredient 

警告:あなたがいずれかの食事で二度成分が含まれている場合、誤った結果を返します。

編集:あなたは特にチ​​ーズに興味がないことが分かります。あなたは本当にすべての "相関"のペアを求めています。だから、私たちは「チーズ」を抽象化して、それを単に第一と第二の成分と呼ぶことができます。私は "PossibleScore"をこれに追加しました。これは、食事のパーセンテージのように動作しようとしますが、原料のインスタンスが非常に少ない場合、強いスコアを与えません。

SELECT First.Ingredient, 
     Second.Ingredient, 
     COUNT(*) AS MealsWithFirst, 
     COUNT(First.Ingredient) AS MealsWithBoth, 
     COUNT(First.Ingredient)/(COUNT(*) + 3) AS PossibleScore, 
    FROM table First 
LEFT JOIN table Second 
     ON (First.Meal_Num = Second.Meal_Num) 
GROUP BY First.Ingredient, Second.Ingredient 

スコア順にソートすると、これは

PASTA CHEESE 2 2 0.400 
CHEESE PASTA  3 2 0.333 
BEEF  CHEESE 1 1 0.250 
BEEF  PASTA  1 1 0.250 
FISH  CHEESE 1 1 0.250 
FISH  PASTA  1 1 0.250 
CHICKEN CHEESE 1 1 0.250 
PASTA BEEF  2 1 0.200 
PASTA FISH  2 1 0.200 
CHEESE BEEF  3 1 0.167 
CHEESE FISH  3 1 0.167 
CHEESE CHICKEN 3 1 0.167 
+2

これは本当に良い情報です。私は、OPがcorr()のような関数を使用したかった理由は、1つの要素ではなく、データ全体に適用できることだと思います。 –

+0

@James Oh;それは実際にはとても良い点です。私の「チーズ」テーブルを一般化して、必ずしも「チーズ」とは言わないようにするのは興味深い練習ですが、私はOPから聞くのを待っています。 –

+0

はい、私はこのことをデータセット全体で実行する予定です。 – owook

2

が自己を行い返す必要がありますが、成分の組み合わせですべて取得するために参加し、その後、2 meal_nums

SELECT t1.INGREDIENT, t2.INGREDIENT, CORR(t1.MEAL_NUM, t2.MEAL_NUM) 
FROM TheTable t1, TheTable t2 
WHERE t1.INGREDIENT < t2.INGREDIENT 
GROUP BY t1.INGREDIENT, t2.INGREDIENT 

によってCORRはあなたを与える必要があります次のようなもの:

BEEF CHEESE 0.999 
BEEF PASTA 0.998 
CHEESE PASTA 0.977 

更新:Chrisが指摘するように、これはそのまま動作しません。私が望んでいたのは、序文 meal_numからまでの間接図(@Chris、リンクありがとう)の値をマッピングする方法があるかもしれないということです。それは可能ではないかもしれません。この場合、この答えは役に立たないでしょう。

+1

私はこれが悪い考えだと確信しています。牛肉が食事2、3、4に現れ、チーズが食事6にしか現われなければ、ペア(2,6)、(3,6)、(4,6)で相関係数を見つけることになります。それは問題になります - ポイントはすべて水平線にあり、相関係数は非常に興味深いものを返します。 –

+0

更新:それは偽陽性ではない - 私の統計は少し錆びているが、私の例のデータを与えると、相関係数はゼロで割った誤差を返すと思う。あなたが実際に数値的なものではないものをCORRに与えるならば、あなたはあらゆる種類の問題を求めています。 –

+0

[ここ](http://en.wikipedia.org/wiki/Levels_of_measurement)は、私が「数値的尺度」という言葉で言っていたことのより技術的な議論です。 –

1

DBMS_FREQUENT_ITEMSETをお試しください:

--Create sample data 
create table meals(meal_num number, ingredient varchar2(10)); 

insert into meals 
select 1, 'BEEF' from dual union all 
select 1, 'CHEESE' from dual union all 
select 1, 'PASTA' from dual union all 
select 2, 'CHEESE' from dual union all 
select 2, 'PASTA' from dual union all 
select 2, 'FISH' from dual union all 
select 3, 'CHEESE' from dual union all 
select 3, 'CHICKEN' from dual; 

commit; 

--Create nested table type to hold results 
CREATE OR REPLACE TYPE fi_varchar_nt AS TABLE OF VARCHAR2(10); 
/

--Find the items most frequently combined with CHEESE. 
select bt.setid, nt.column_value, support occurances_of_itemset 
    ,length, total_tranx 
from 
(
    select 
     cast(itemset as fi_varchar_nt) itemset, rownum setid 
     ,support, length, total_tranx 
    from table(dbms_frequent_itemset.fi_transactional(
     tranx_cursor => cursor(select meal_num, ingredient from meals), 
     support_threshold => 0, 
     itemset_length_min => 2, 
     itemset_length_max => 2, 
     including_items => cursor(select 'CHEESE' from dual), 
     excluding_items => null)) 
) bt, 
table(bt.itemset) nt 
where column_value <> 'CHEESE' 
order by 3 desc; 


    SETID COLUMN_VAL OCCURANCES_OF_ITEMSET  LENGTH TOTAL_TRANX 
---------- ---------- --------------------- ---------- ----------- 
     4 PASTA       2   2   3 
     3 FISH       1   2   3 
     1 BEEF       1   2   3 
     2 CHICKEN      1   2   3