I'm interested in learning some AI algorithms that have a practical use in web applications eg. search, product recommendations etc. Obviously since I'm asking this question I am look for some more entry level material.
Any sort of useful stuff on the subject is good - books, blogs, tutorials, anything. My language of choice is c# so anything in that would be awesome but I'm happy to look at examples in other languages.
Toby Segaran's Programming Collective Intelligence isn't strictly an AI book I guess, but it does cover the kind of topics you're interested in (e.g. product recommendations, predictions, price modelling), and as a newcomer to the field I found it pretty accessible. It does sometimes skip over algorithmic detail in favour of "here's how to use this technique via an existing library" though; also the code samples are written in Python though it's clearly explained and easily translated to C#. It has a strong Web focus because, as the title implies, it deals with mining data from user-provided content, particularly on external sites such as eBay, etc.
I use AForge.NET in several projects. There are quite simple and fast implementations of genetic algorithms, neural networks, machine learning and so on.
It is an open-source project, so I can recommend it as a starting framework for any project using AI.
There is an excellent series of Google talks that will cover the foundations called Statistical Aspects of Data Mining. It's the same graduate level class that David Meese gives at Stanford.
The book Algorithms of the Intelligent Web by Haralambos Marmanis & Dmitry Babenko (Manning ed. 2009) provide a primer into this kind of things.
This book covers a rather broad spectrum of areas where "smarts" can be applied to web applications. Because of this, many topics receive at a rather superficial treatment, BUT each chapter includes very relevant references for digging further.
Also, code-wise, the working examples found in the book are made available in a code.google.com project (sorry however, mostly java, not C# as suggested in the question)
I cannot think of other AI resources specifically focused on Web applications, but many areas of AI-at-large are relevant the "intelligent web", in particular:
Natural Language Processing
[some] Neural Networks
Machine learning and classifiers
"Algorithms of the Intelligent Web" by Marmanis & Babenko. Hands down the best reference for what you need (based on your description). Yes, the code is written in Java but it is so clean and straightforward that you can probably transliterate it, into whatever you want, rather quickly.
In terms of search functionality it goes beyond indexing and describes, in-detail, PageRank, user click enhancements, and a PageRank-inspired ranking algorithm for plain documents (ASCII, Word, PDF) that the author called DocRank.
The book also provides, probably the best, practical coverage of recommendation engines, e.g. user-user, item-item, content based.
Related
Lately, I have developed a keen interest in the speech recognition and natural language processing domain and have been playing around with a few different approaches to build a system which can perform commands based on natural language instructions.
In my study so far, I have come across various NLP tools, but haven't been able to figure out how to utilize them for my purpose.C# is my primary language, and sadly, there is hardly anything available on the dotnet platform for NLP.
In addition to the learning curve, there are various problems with the regular NLP approach as well. Language ambiguity, named entity recognition, sentence boundary detection etc are a few points that add to the complexity. These issues are much more prominent in free form unconstrained language detection and parsing, but for a limited domain, the complexity should be reduced. However, I couldn't really overcome the challenge as most tools have huge static dictionary data or the training process is too complex.
The other major issue is about the conversational approach. Most of the tools do not handle conversational history and have no way to identify the context of the incoming instruction.
I was hoping that some of you guys who have either worked on a similar technology earlier would be able to help me iron out these challenges and point me towards the right direction.
Can you share your experience with various tools, the approaches you took, the roadblocks you faced and how you resolved them during the process.
Update: Let me also include a brief overview of what I envision. The system would essentially be a just a command executor that understands simple english. So, if I say, "send an email to john", it should understand that I want to send an email and now ask me questions to get more information about what should be the subject line and the content. Additionally, if there are more than one Johns in my address book and may be more than one email address for John, the system should be able to identify that too and ask me for further directions.
For the implementation, I think I need following components:
Speech to text converter
NLP engine to parse the text and identify the action and the objects on which the action is to be performed.
An execution engine to create and co-ordinate different agents to perform the different types of actions.
The challenge lies in making the system extensible to be able to support more such actionable features at a later stage with a little modification.
I think I am fine with Speech to text part and execution part. But the pain point is the NLP engine which can understand the natural language correctly and give me exact action and parameters for it.
I have played around with POS taggers. They do not help much with the compound statements, and it gets a little tricky to establish the relationship between various verbs and nouns detected in the sentence.
Another issue is with maintaining the context of previous actions and include it making sense of the current statement.
P.S.: Convert it to a wiki if you feel appropriate. Please don't flame me for asking a generic problem.
You can't uncouple learning, from doing coding from scratch, otherwise is meaningless.
Lisp is probably the best language for natural processing, the classic emacs psychiatrist session is an example of what can be accomplished with little work. Its a scientist's language with functional style of programming, the whole thinking is different than regular c like programming, OOP has no bearing on this. Is the oldest still in use language, a version of it called Scheme is in the MIT introductory course. A classic on the field of AI research.
The problem is you can't easily interface it with your sound input devices, at least most free versions I know of. So you can do the pure logic and awesome of natural language processing in clever ways. But it can't hear you. You can use some stdin/stdout, text file, and database wrappers for independent sound to text and viceversa, but the flux is broken up at uneven levels, and is not natural any longer, because in a natural way of speaking context is lead by understanding of the environment.
If I'm talking with a visiting friend while my AI enabled PC is on and I say: "Just rm -rf everything", how does my machine know who I'm talking about, I silly solution would be that the machine only accept direct addressing: "Computer Do X Y Z", but what if I say to my friend : "In that computer rm -rf everything". Context can only exist through awareness, and Awareness requires some sort of AI.
This is not something to tackle with if/else/then or class hierarchies. Of course at the end of the day lisp machines are coded in C. But is a minimal base, over which you can construct the rest.
So for a mix of learning and "practical approach", you would need to extend a lisp interpreter to add functions to deal with hardware input/output schemes and convert the data back and forwards. This would be trivial and almost secondary on the grand scheme of thigs, but not without considerable effort.
But the most important issue would be the lisp program. You would have to find ways to for example add a intonation property to distinguish stress or eagerness to prioritize an order or to create new context, there is also the problem that people often say non sensical illogical stuff when tired or stressed or by using some local idiom like "chill out", "get a hold of your horses",etc.
A beginner program should not deal with this above example right away, but should be designed to be extensible so it can be able to address such conditions in the future.
Is Easy "do this and that" voice recognition and processing of the order, to contextualized you need a lot of work, both with human issues (language, psychology, culture,etc) and programming Computer Science issues.
An ideal software would be able to use common code to speak both japanese and english, even if grammar and phonetics are completely opposed to each other.
Well this can be almost an exposition of philosophy as well, and can be endless so I'll stop here. I hope this mini essay can be helpful somehow.
I'm about to start working on a rich-internet-application project for a student organization at my university. I will be the only programmer, and what technologies to use is totally up to me. I've already decided on going with Silverlight, but I'm not sure whether to use C# or F#. Here are some of the things I'm keeping in mind:
C#:
I already know it and have used it extensively with Silverlight at work. I have no F# and little general FP experience.
Some say the OOP paradigm works better for complex stateful UIs.
Maintenance: I'll be in school for three more years, but after that if the app is still in use they may have a better time finding someone else to maintain it if I use a more common language.
C# experience is probably more valuable in the "real world".
F#:
The main reason is I want to learn something new. Functional programming languages seem pretty cool (I find myself using the FP features of C# very often, and think they're the biggest improvement in C# 3.0). I think I'd have a lot more fun if I used F#, but am I being unrealistic in thinking the cost in time and effort might not outweigh the benefits?
In my opinion, when you are a student, you should be trying to put your fingers in as many pots as possible.
The more languages you play with, the more understanding you will have of the "best" ways of doing things in a specific language.
As for "experience" being more valuable in the "real world". Personally I only ever consider true commercial experience when looking at potential candidates. Experience in a language when you're in a job and being paid is extremely different to experience in using a language when learning / studying it. Things you do whilst studying are about gaining skills and knowledge whereas things you do in a commercial environment give you experience in solving real life problems.
Bottom line... play with the cool stuff whilst you still can!
Because you expect to create something useful that will live past your tenure as maintainer, I would suggest writing the majority in C#. What you can do to scratch your new-technology-itch, though, is pull out distinct, well-defined components that don't interact directly with the UI and write those in a separate F# assembly.
I've done something similar with a project that I've open sourced in the past. My fundamental UI logic (in this case, the V-VM parts of the M-V-VM) were in C# because it works so well with WPF technologies. Then, certain functionally-oriented components of the Model itself I broke out into a separate assembly and wrote in F# just to get some limited exposure to the language.
It's not a jump-with-both-feet approach to learning technology, so I probably didn't learn as much as I could have. An F#-only project wouldn't have taught me nearly as much about exposing F# functionality to the greater .Net world in a friendly way, either, though.
No matter what, the key in a situation like this is for you to have fun and enjoy what you're doing. :)
You can make F# business logics project (a dll).
And then the user interface in C#. And in user interface project you can add a reference to the F#-library.
This is a good solution in general when using Silverlight: The power of F# is (functional) programming but currently C# will have a better tool-support.
I know it's not in your list, but if you're interested in learning something new, you might consider GWT - You write your client in Java (which ought to be an easy jump from C#), and then the compiler turns the client side into JavaScript. Should be a bit more cross-platform compatible than Silverlight, and it's an interesting fusion of technologies (CSS, JavaScript, and Java aren't going anywhere in the near future).
I just gave a talk about programming reactive Silverlight applications in F# at London F# user-group meeting. The recording of the talk (and samples) are available here, so you can take a look at that.
Here are a few points you could consider:
I think F# has some very nice features that make programming this kind of applications more elegant than in C# (for example, you can nicely model program as a state machine and encode this direcly in code).
F# is still relatively new, but I believe that there is a decent chance that finding someone familiar with F# after three years will be much easier than today (and finding younger students who are interested to learn something new should be easier :-)).
I was surprised that there is already quite a demand for good F# programmers in the London area. This will be probably different in different places, but I think that F# is becoming a "nice-to-have" feature on CV for some jobs.
I'm presuming that this will be used in an intranet environment. Otherwise, I'd question whether the choice of Silverlight is really the best due to market penetration.
The second point I'd raise is that one of the really key skills for most web developers is Javascript. (Nowadays, that would be Javascript with a library like JQuery to manipulate the DOM, simplify AJAX, etc.) unless the application is particularly complex, there might be some merit in considering DHTML+Javascript as a starting point, and only looking at other technologies if it proves too much for that.
However, if you're set on going down the Silverlight route, then C# is by far the most likely to be supported. If you're still learning, then it's also the route that has the best documentation. F# has some excellent documentation around, but unfortunately not nearly as much as for C#.
You briefly mention the time and cost commitment. Unless you're quite comfortable with functional programming, F# is liable to take significantly longer, in part due to unfamiliarity and in part due to the amount of reference documentation to help you on your way.
While it it undoubtedly good to have knowledge of a range of programming languages under your belt, what's more valuable to most employers is a solid understanding of their language of choice - so diversifying too much can miss that. When looking to learn an unfamiliar programming language starting with something like solving Project Euler problems may present a better way of starting out, rather than diving straight into a major project with a new language. If you start in C#, you can always create an F# project that implements functions more suitable for its focus, and reference it from the C# one, to dip your toe in its waters while not automatically committing a lot of additional time to it.
I have been studying the ECMAScript specification and have found that it is extremely hard to read and understand. I constantly have to backtrack to keep concepts in my head. When reading the C# specification I am able to study components of the language without constantly moving around the document.
ECMAScript Specification
C# Specification
As I am the only person regularly posting on SO who has been a member of both the C# language design committee and the ECMAScript technical committee, I can probably offer a few insights.
First off, thanks for your kind words about the C# specification. We've worked very hard to keep it readable and it is good to know that we've succeeded.
Second, I note that the C# specification was not always that way. The C# 2.0 specification was written as an addendum to the C# 1.0 specification. Generics, iterator blocks and anonymous methods had widespread impacts on many sections of the specification. It was a real pain reading the 2.0 spec and having to jump around between two chapters to understand the real overload resolution algorithm. Mads did a huge amount of editing work in C# 3.0 to first integrate all the C# 2.0 changes into a reasonable place in the spec so that you would not have to jump around all over the place.
Third, a big part of what you're describing is a result of differences in both goal and style of the principal architects of the two specifications. Imagine a spectrum of "technical-ness" with papers about formal correctness written largely in Greek letters at one end, and magazine articles for beginners on the other. We design the C# specification to fall at a particular place on that spectrum. We do not want it to be a beginner programmer tutorial, but do want it to be a reasonable document for beginner C# programmers to consult. Anders specifically wished to avoid what he calls "the higher math of the specification".
This is a reasonable set of goals given our target audience for the spec: professional programmers, some of whom want to learn C#, and some of whom want to look up precisely how something works. The spec has vague tutorial aspects and precise semantic description aspects in order to serve those two constituencies.
Waldemar Horwat, the principal author of the ECMAScript 3 spec, had rather different goals for the E3 spec -- not worse goals, but different goals. The goal of the E3 spec was to be far more towards the mathematically precise end of the spectrum. You'll note how practically every section of the specification consists of essentially pseudocode algorithms that describe in rather math-heavy prose precisely what the effect of each operation is on the system.
You'll notice for example that the E3 specification talks about the difference between "mathematical" numbers and their binary representations. One draft of the E4 spec even went so far as to note that there are set-theoretic problems with a naive definition of "type" as a set of values if types are also values. This sort of thing would be completely out of place in the C# spec; it does not seek to have a strong theoretical mathematical underpinning to ensure its correctness. You'll note that the C# spec nowhere even defines "type" -- it was written with the assumption that the readers will be pro devs who (1) already know what types are for practical purposes, and (2) neither know nor care what set theory or category theory has to say about the mathematical well-foundedness of any definition of "type".
The goal of the ECMAScript process was for multiple vendors of highly similar languages to come together and agree on a precise description of what was in the common ground amongst all those implementations. The E3 spec was never intended to be a tutorial of any kind, and is primarily aimed at language and tool implementors, rather than language users.
Waldemar's E4 spec went even further. If I recall correctly, he began by specifying a very precise, simple "spec language" with clear semantics. Then he wrote an interpreter for that language in Common Lisp. Then he wrote the E4 spec in his spec language. The result was that he could compile the specification itself into a working ECMAScript interpreter. That is exactly the sort of "higher math" that we are trying to avoid in the C# specification. This is an awesome approach to specification if you want to be incredibly precise and accurate, but it is a terrible way to write a document that language users can learn from.
Does that answer your question?
You are probably experiencing a difference between the readability of the specifications of the two languages because they were written by different groups of people, and discuss languages which employ different object paradigms.
The JavaScript specification was written by a committee after the language had evolved organically after several years. The C# specification was written by a small group of corporate engineers while the language was growing in a controlled manner.
C# is class-centric OOP and JavaScript is prototype-centric. It is possible that if you are not as familiar with one as you are with the other, then some material may be difficult to understand at first, especially when it gets into implementation details. That doesn't necessarily indicate a problem with the clarity and readability of a specification.
Relative to conventional languages JavaScript is very strange. In fact there aren't too many popular languages that like JavaScript are prototype based. JavaScript is completely object based, and all objects are essentially associative arrays with functions too being first-class object. This isn't typically what you'd expect to see from a language however with popularity of Ajax and browser side programming JavaScript has become the language of the web. While these strange specs could have been avoided, I believe JavaScript can lead to some interesting and creative coding. Closures for example are the thing that most new developers struggle to understand but in my experience they are very useful. The semantic of the language at times fools developers to think JavaScript is a flavor of C but soon they realize this to be not true.
To me C# is the pinnacle of programming languages. It is correct and inline with academic expectations. Its a shame that MS is the primary driver of this language. Like myself I'm sure there are many others who would enjoy a proper implementation of a platform with support for C# on none Windows based system (Mono is a move in the right direction).
If you are keen to learn JavaScript and not a JavaScript Framework, then I really suggest to stick with books that directly discuss JavaScript. However if you are intending to get started and don't care much about the ins and outs of JavaScript #bwawok suggestion of books is the right way to go.
Well, you are the first person I know of trying to learn a language based on the ECMA documents. Anyhow, I would say the difference is mostly due to the skill of the people writing the specs. C# is obviously a little easier to specify (due to the less dynamic nature - as already pointed out), but at the end...
...IIRC JavaScript is design by committee (many people writing also on the spec), while C# was done by Microsoft by ONE person at the end, maybe with 1-2 authors along the way and some helpers, but at the end it is Anders Hejlsberg (hope I spelled that right). Design by committee and having to vote on things may sometimes lead to less optimal "design" of a document.
So, at the end I think it is about the skill of the people writing the different specifications that one is harder to read than the other.
Part of the reason is that the standard you link to is actually ECMAScript. JavaScript, JScript and ActionScript are all implementations of ECMAScript, and ECMAScript was written to encompass the common parts of each. In contrast, C# was designed primarily by three people (according to the ECMA-334 standard) at Microsoft.
Other than that, you'd have to take it up with the committee that wrote the ECMAScript Standards.
Put simply, it's probably because they were written by different authors. The C# spec was written by Microsoft who had a vested interest in making it good (so that it would be accepted) whereas the ECMAScript spec was written by a committee after the language was already in use.
Well the best part is, C# will run from one computer to another the same (yes maybe minor differences in .net versions, but stuff will generally behave). Javascript will run very different between internet explorer vs firefox vs chrome.
For example you have a webpage with an element
<input type="text" name="fred" />
And you run the JavaScript
document.getElementById("fred")
Internet explorer will get you the element (even though this is wrong behavior, there is no element with an ID of fred), but firefox will give you a null.
More likely than not, this is because of how the languages grew. C# was made by 1 company and developers were forced to follow the standards, or their code would not work. JavaScript was implemented in many different browsers in different ways, and people were free to add or remove or change functions as they saw fit.
In summary, JavaScript takes more work to learn than other languages because of it's history. Look into a good library like JQuery to abstract away the browser differences, and you should get the hang of it quick enough. Learning from a document is only a small part of learning a language... do some coding and learn how it works, and it will make sense.
I have a little programming experience with vb 6 and vb.net not much. Please tell me the best way to become an expert C# programmer and I know it will take a long time.
Think about how you learn human languages - reading, writing, speaking and listening.
Read code. Read articles. Read examples. When you're more experienced, look at the source code for some projects that you use.
Write code. Play with the examples you've read about. Modify them. Solve problems from Project Euler. Think of your own projects then try to solve those.
Talk about code. Blog about it. Tell your friends about it. See if you can impress your grandmother with how good your program is. Now try to impress your professor. Learn how to communicate about programming with different types of people.
Listen to other programmers. Many of them have more experience than you and have useful things to say that you can learn from. Learn the vocabulary they use. Discuss your ideas with them.
Practice. Practice. Practice.
Google is your friend.
Start by downloading http://www.microsoft.com/express/ and start programming. If you don't have a project of your own or something someone else wants done, start looking up popular algorithms and implement those. Try implementing certain design patterns. This way rather then just focusing on syntax your learning a heck of a lot more about programming in general.
Even though I feel the other answers on this thread already well-cover the bases, in terms of replying to a pretty "nebulous," even "naive," question : I'm going to add another opinion (slightly too long to just be a comment).
I respectfully disagree with a few posts suggesting an analogy of learning a programming language to learning a spoken, or written, language. SO is not the place to discuss linguistic theory, and its relation to evolution, and cognitive structure, and the work of Chomsky, and Pinker, et. al., which suggest not only language learning's "innateness," but also how variation in "endowment" (genetic, and, yes, even "temperament"), and its dynamic interaction with environment, and "developmental windows of opportunity" at which learning can take place at phenomenally accelerated rates, contributes differentially to morphemic versus phonemic competency, etc.
But, please allow me just to register the hypothesis that there are many ways in which the analogy of learning a programming language to learning a spoken and written language is more of a "catch-all" that masks complexity, rather than a useful tool.
On the other hand, I suspect (hypothesis) that a person who has achieved mastery of more than one spoken/written language has, indeed, developed certain cognitive structures and skills that may be "useful" in learning a programming language.
To my mind the above two paragraphs are not inherently contradictory statements.
imho programming in general is also not analgous with learning mathematics or geometry which build structures up from axioms, or fundamental assumptions, into complex systems that sometimes can be "formally" proven, or validated. Of course there are some "rare birds" who start off from Knuth, or Gamma, et. al. and "Design Patterns," and "work their way down" to the "real world" :)
My "vote" goes with starting with a good book, and, as Mark Byers suggested, combining that with practice, testing yourself, taking on problems like those on the Euler project Mark mentioned, and, yes, certainly, also as Mark suggests, studying other people's code.
The question, in the beginning, though, is, imho : how to know which code is good to study.
For me the answer to that is : study the code examples provided by really good books like those by Jesse Liberty, for example : "Programming C#" latest (3rd.) edition from O'Reilly. Note : my understanding is the 4th. edition is due in March 2010.
imho Jesse has an unusual gift as a teacher of programming languages, an ability to "pace" the introduction of material in a skilfull way, to select and present the right examples in the right sequence, and remarkable gifts of clarity in his technical writing.
CodeProject articles are a great resource for code examples to study. Look for articles in areas that interest you that have a very high rating by other users, and are specific to C#.
The lesser-known book by Liberty "C# 2005 : A Developers's Notebook" is a fantastic resource (also, imho, one of the most fascinating books in terms of graphic design and book structure, ever done in any technical arena). It's a series of "exercises" that I would compare to the idea of "etudes" in music : each exercise demonstrates a topic, challenges you to understand a good example of that topic, and each topic is really something that will be useful in your "real-world" programming.
imho, once you have your "feet on the ground" with a hundred hours or so of study and practice of .NET : fly, don't walk, to the "guru-level" with Jon Skeet's "C# in Depth" published by Manning. He also, imho, is a superb technical writer who shares with Liberty the gift of selective presentation of material, and has his own special, unique, gift for "stepping out of the book to speak to you directly," addressing the kinds of concerns you are probably thinking about as you encounter more difficult material. I should note that I feel I am a long way from mastery of the content of this book, which just whets my appetite for understanding it. There's an element of wit and humor in Skeet's writing that also, in my experience, is extremely rare in technical books.
Please note : disclaimer : while I have worked as a paid consultant for Addison-Wesley on the technical editing of two major .NET books, I have never worked for O'Reilly or Manning, or received "comp" copies of their books (dammit :).
I must, respectfully, disagree with the recommendation of "C# in a Nutshell" by Albahari and Albahari (also O'Reilly; I believe 4th. edition is out now : I have only seen 3rd. edition) above : I think it would be a very inappropriate tool for a newcomer to .NET. On the other hand, when you get to studying Linq : you'll find, imho, that Albahari's website and free version of LinqPad is just the coolest thing ever done for helping you "get into" and explore Linq.
Good luck !
The same way you learned VB6 and VB.NET, no doubt. Pick up a book, and start reading. There's nothing radically different about it that requires any esoteric approach to learning. Just good old fashioned squatting in Barnes and Noble for a few hours before breaking down and buying a book. You could also mosey around http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx and read up a bit.
If you've already been using VB.NET, C# should come pretty natural to you. The syntax will be different, but the objects, methods, etc will all be familiar. Check out the tutorials on MSDN for C# too: http://msdn.microsoft.com/en-us/library/aa288436(VS.71).aspx
Oh, and welcome to StackOverflow!
If you're already familiar with other programming languages, the O'Reilly "In a Nutshell" books are generally a good place to start. "C# in a Nutshell" is both a good introduction and a good reference.
Download Charles Petzold's .NET Book Zero and read it through from start to finish, skip nothing even when you think you a fair bit about a particular area.
I'm thinking about learning Java. I'm already a more than competent c# developer. Has anybody else been in a similar situation? Roughly how long (whilst doing a typical 9-5 job) did it take you to transfer your skills? What resources would you recommend?
(When talking about resources, I specifically mean resources aimed at developers who want to learn Java, not newbie material)
I studied Java at university, and did c# at work.
You will find the Sun Java API (Javadocs) to be very informative and will help you dearly. You can find it here. This website should be the first to consult if you need a query, as it is brief, and up-to-date - similar to the MSDN Library for c#.
Also, Java has a strong community who will be willing to help # the forums.
Finally, I think its best to learn Java through practice and experimentation over theory. You will need a good IDE to start you off and there are plenty to choose from. Eclipse and Netbeans are notable Visual Studio contenders, but personally I prefer JCreator(albeit the version with intellisense is not free). It maybe text based, but you have greater control IMO.
If you are going to create GUI applications, then you should learn about swing. Again, the guys at sun provide excellent tutorials on the matter.
There are also books:
Java in a nutshell is a nice book. Click for google preview.
Java: the complete reference By Herbert Schildt is one I would highly recommend. Google Preview.
I'd recommend these books:
Effective Java (Joshua Bloch)
Core J2EE Patterns (Deepak Alur; John Crupi; Dan Malks) - sort of out of date, but still useful for understanding the history of J2EE. A lot of this is still applicable.
Concurrent Programming in Java (Doug Lea) - good guide to Java threading
Here's a more comprehensive list:
http://www.javalobby.org/articles/5books/full.jsp
It shouldn't be a difficult switch. Java is pretty much a subset of C# (Operationally) since C# was a Java clone that has mutated since it was split. (Everyone here remember the fiasco when MS tried to embrace java by modifying it so it would only work with windows, was sued by Sun and then made J++ and C# instead?)
The biggest difference will probably be the libraries, but if you are proficient at C#, then you shouldn't need to do anything more than study the Javadocs to pick up the new libraries.
EE might be a bit of a jump, but that's a whole 'nuther world.
For me, the nicest thing about Java is the minimal syntax. There are very few surprises or tricky parts to remember (Well, Generics have a kind of tricky syntax to implement, but using them is pretty straight-forward). If you agree with this or not--it does tend to make the learning curve a bit more shallow.
I started in Java and went to C#.
I will be honest with you; going back to Java won't be so easy, depending on how you started. It's going to change your world a bit. J2EE is quite different from ASP.NET, even though it looks a bit the same. Forget lots of things you used to hold dear, like == of strings, and switch on strings, and properties, and other such nicities. Oh, and prepare to be welcomed by checked exceptions.
Don't get me wrong, I love Java, and it's a great language, but you'll need be wary of the differences.
I would say a fun way to learn would be to write a program simultaneously in Java and C#, and see how you would do each thing, and note the differences.
I think you may find books hard to read, as they'll cover the basics, which will be boring for you, so you may skip critical things.
Learn by doing :) That is my approach.