SQL Server計算Jaccard係數—sim(i,j)

來源:互聯網
上載者:User

標籤:http   class   card   1.0   oss   cto   根據   ESS   擷取   

前些天,在Q群裡面看到有人請教這樣一個問題:在SQL Server中如何用SQL實現以下計算

由圖得知,該問題是如何計算Jaccard係數。Jaccard係數,又稱為Jaccard相似係數(Jaccard similarity coefficient)用於比較有限樣本集之間的相似性與差異性。Jaccard係數值越大,樣本相似性越高。


SQL Server通過intersect實現交集,union實現並集,如下:


intersect交集

計算交集程式碼片段如下:(1 intersect 0 = null,1 intersect 1 = 1,0 intersect 0 = 0)


union並集

計算並集程式碼片段如下:(1 union 0 = 1 0,1 union 1 = 1,0 union 0 = 0)


原理簡介:

通過sys.columns表擷取表的欄位名與欄位ID,迴圈欄位名,並根據欄位名去取到表中對應的值:如欄位名為A,那麼取ID為1的值:select A from test where id=1,取ID為2的值:select A from test where id=2,

然後將2個值進行交集與並集,欄位迴圈結束後,得到@str_intersect,@str_union,計算比值:len(@str_intersect)*1.0/len(@str_union)


最終結果如下:


全部代碼如下:(建表,見注釋部分)

--create table Test(id int,A INT,B INT,C INT,D INT,E INT,F INT)--INSERT INTO TEST SELECT 1,1,1,1,0,0,0--INSERT INTO TEST SELECT 2,0,1,0,1,0,1--INSERT INTO TEST SELECT 3,1,1,1,1,0,1--INSERT INTO TEST SELECT 4,1,1,1,0,1,0--INSERT INTO TEST SELECT 5,0,1,0,1,1,1--INSERT INTO TEST SELECT 6,0,0,1,0,1,1--drop table Test_result--create table Test_result(id int,_1_ numeric(10,4),_2_ numeric(10,4),_3_ numeric(10,4),_4_ numeric(10,4),_5_ numeric(10,4),_6_ numeric(10,4))--insert into Test_result select 1,null,null,null,null,null,null--insert into Test_result select 2,null,null,null,null,null,null--insert into Test_result select 3,null,null,null,null,null,null--insert into Test_result select 4,null,null,null,null,null,null--insert into Test_result select 5,null,null,null,null,null,null--insert into Test_result select 6,null,null,null,null,null,nullSELECT name,column_id  into #test  FROM SYS.COLUMNS WHERE object_id =object_id('dbo.test')and column_id>1declare @id_1 int=0,@id_2 int=0,@str_union varchar(max),@a_union int,@sql_union varchar(max),@str_intersect varchar(max),@a_intersect int,@sql_intersect varchar(max)declare @name varchar(20),@column_id intcreate table #a_union(num int)create table #a_intersect(num int)declare @min_id int=0,@max_id int=0,@global_min_id int=0,@global_max_id int=0select @min_id=min(id),@max_id=max(id),@global_min_id=min(id),@global_max_id=max(id) from Testwhile(@min_id<[email protected]_id)beginselect @[email protected]_id,@[email protected]_min_idwhile @id_2<[email protected]_max_idbeginselect @str_union='',@str_intersect=''while(select count(1) from #test)>0 beginselect top 1 @name=name,@column_id=column_id from #test order by column_idselect @sql_union='select CASE '+'WHEN (select count(1) from (SELECT '[email protected]+' FROM TEST WHERE ID='+convert(varchar,@id_1)+'union SELECT '[email protected]+' FROM TEST WHERE ID='+convert(varchar,@id_2)+') as a)>1 THEN 1'+' WHEN ISNULL((SELECT '[email protected]+' FROM TEST WHERE ID='+convert(varchar,@id_1)+' UNION  SELECT '[email protected]+' FROM TEST WHERE ID='+convert(varchar,@id_2)+'),0)=0 THEN 0 ELSE 1 END'insert into #a_unionexec(@sql_union)SELECT @a_union=num from #a_uniondelete from #a_unionif(@a_union=1)select @[email protected]select @sql_intersect='select CASE WHEN ISNULL((SELECT '[email protected]+' FROM TEST WHERE ID='+convert(varchar,@id_1)+' INTERSECT  SELECT '[email protected]+' FROM TEST WHERE ID='+convert(varchar,@id_2)+'),0)=0 THEN 0 ELSE 1 END'insert into #a_intersectexec(@sql_intersect)SELECT @a_intersect=num from #a_intersectdelete from #a_intersectif(@a_intersect=1)select @[email protected]delete from #test where @name=name and @column_id=column_idendinsert into #test SELECT name,column_id FROM SYS.COLUMNS WHERE object_id =object_id('dbo.test')and column_id>1--select @str_union,@str_intersect,@column_id,@id_1,@id_2if(@id_2=1)    update Test_result set _1_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where [email protected]_1if(@id_2=2)    update Test_result set _2_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where [email protected]_1if(@id_2=3)    update Test_result set _3_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where [email protected]_1if(@id_2=4)    update Test_result set _4_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where [email protected]_1if(@id_2=5)    update Test_result set _5_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where [email protected]_1if(@id_2=6)    update Test_result set _6_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where [email protected]_1   set @[email protected]_2+1endset @[email protected]_id+1enddrop table #testdrop table #a_uniondrop table #a_intersect-------------create table test_str_column(id int,str_columns varchar(max))--insert into test_str_column select 1,null--insert into test_str_column select 2,null--insert into test_str_column select 3,null--insert into test_str_column select 4,null--insert into test_str_column select 5,null--insert into test_str_column select 6,nullselect * into #temp_test_table from testselect name,column_id into #tmp_test_columns from sys.columns where object_id=object_id('dbo.test') and column_id>1declare @id int,@col_name varchar(20),@col_id int,@string_columns varchar(max),@sql_rs varchar(max),@num_1 intcreate table #tmp_rs(num int)while (select count(1) from #temp_test_table)>0beginselect top 1 @id=id from #temp_test_table order by idset @string_columns=''while(select count(1) from #tmp_test_columns)>0beginselect top 1 @col_name=name,@col_id=column_id from #tmp_test_columns order by column_idselect @sql_rs='select '[email protected]_name+' from test where id='+convert(varchar,@id)insert into #tmp_rsexec(@sql_rs)select @num_1=num from #tmp_rsif(@num_1=1)set @[email protected][email protected]_namedelete from #tmp_test_columns where @col_name=name and @col_id=column_iddelete from #tmp_rsendinsert into #tmp_test_columns select name,column_id  from sys.columns where object_id=object_id('dbo.test') and column_id>1update test_str_column set [email protected]_columns where id [email protected]delete from #temp_test_table where @id=idenddrop table  #temp_test_tabledrop table #tmp_test_columnsdrop table #tmp_rsselect * from testselect * from test_str_columnselect * from Test_result


SQL Server計算Jaccard係數—sim(i,j)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.